Posts Tagged ‘jQuery

30
Nov
09

Interesting New Uses for SPDisplayRelatedInfo: Follow Up

Following up on my post Interesting New Uses for SPDisplayRelatedInfo, I’ve just added two new options to the SPDisplayRelatedInfo function in the first alpha for v0.4.7 of the jQuery Library for SharePoint Web Services.  The function is getting a little overloaded with options, but these two seemed pretty valuable yet not worth breaking things out into a new function.

 The two new options are:

numChars: 0,      // If used on an input column (not a dropdown), no matching will occur until at least this number of characters has been entered
matchType: "Eq",     // If used on an input column (not a dropdown), type of match. Can be any valid CAML comparison operator, most often "Eq" or "BeginsWith"

With these options, you can now use SPDisplayRelatedInfo more flexibly with columns which are not dropdowns or multi-selects, specifically Single line of text or Number columns.

By specifying a number of characters in numChars, you can limit the Web Services calls to find matching items in the relatedList from occurring until there have been at least that many characters typed.

By specifying a different value for matchType, you can change the type of comparison which is done to find matching items.  As noted above, the two most common values will be Eq and BeginsWith, however, there didn’t seem to be any reason not to allow all of the other available CAML comparison operators: Contains, Geq, Gt, Leq, Lt, Neq, etc.  You can see the descriptions for all of these CAML operators in the CAML Query Schema in the SDK on MSDN.

27
Nov
09

Great reference JQuery and SharePoint 2007 Blog Post

I ran across a great JQuery and SharePoint 2007 blog post yesterday, and I wanted to capture the URL here for later reference. Vedant Kulshreshtha has done a great job gathering up links to explain what jQuery is all about, why it is a good thing, what people think about it, how you might use it with SharePoint, etc.  From now on when people ask me what they should read to learn about jQuery with SharePoint, this is where I’m going to send them.

27
Nov
09

Interesting New Uses for SPDisplayRelatedInfo

I had a question on my recent article over at EndUserSharePoint.com entitled A jQuery Library for SharePoint Web Services (WSS 3.0 and MOSS): Real World Example – Part 1.  The question was about the SPDisplayRelatedInfo function, and while I was setting things up to see if I had a bug, I found that there were some interesting ways you could use the SPDisplayRelatedInfo function that I hadn’t considered.

I added a Single line of text column to my old standby Sales Opportunities list and called it StateID.  In my EditFormCustom.aspx, I added this call to SPDisplayRelatedInfo:

$().SPServices.SPDisplayRelatedInfo({   
    columnName: "StateID",
    relatedList: "States",
    relatedListColumn: "ID",
    relatedColumns: ["ID", "Title"],
    displayFormat: "table"
});

The States list is one of the lists I use in testing SPCascadeDropdowns, and it has these columns: State (the original Title column) and State Abbreviation. Now, when I typed digits into the StateID column, I got real-time results from the SPDisplayRelatedInfo function as the digits matched the ID of the State item. Cool!

So if I started out with the column empty, I saw:

image

then when I typed 1:

image

then when I typed 2:

image

This also worked if the StateID column was a Number column.  Looking through the code, there was no reason this shouldn’t work, it’s just not the use I had intended.

So then I thought, well what if I wanted to match as I type the State?  I switched the function call to this:

$().SPServices.SPDisplayRelatedInfo({   
    columnName: "StateID",
    relatedList: "States",
    relatedListColumn: "Title",
    relatedColumns: ["ID", "Title", "State_x0020_Abbreviation"],
    displayFormat: "table"
});

Then when I typed Massachusetts, I saw:

image

Hmm, that can’t be right.  I went and checked the States list, and sure enough, I had some junk test data in there that I had forgotten about.  Even cooler!  The SPDisplayRelatedInfo function essentially acts like an as-you-type reference lookup!

These examples aren’t exactly what you’d be doing in the real world, but think about the situation where you had a product code that could be 1-5 digits or numbers or something where you wanted to let the user type instead of dealing with a dropdown. If you come up with another interesting use, let me know about it.

It’s always nice to find out that code you’ve written is *more* useful than you thought (as opposed to the dreaded less useful situation).

24
Nov
09

jQuery Library for SharePoint Web Services v0.4.6 Released

Today I released v0.4.6 of my jQuery Library for SharePoint Web Services.  This version was fun to work on because I’ve got quite a few people out there in the world (California, North Carolina, Sweden) using the library actively, so we were able to work together pretty much real time to get enhancements and bug fixes into the library together.  This was also the first release where I decided to keep a current alpha version posted on Codeplex while I was doing the work.  This was rewarding because there was a real feedback loop going on.  I think this is a better way to go in the future, so watch for more alpha versions you can kick the tires on for me (actually for all of us).

This release has two really nice enhancements:

  • SPCascadeDropdowns now works with multi-select child columns. This was the most requested enhancements over the last few months, and to be honest I dragged my feet on it.  The controls that SharePoint uses for multi-select choices are just plain complicated.  There’s also a whole pile of JavaScript which sites behind it all (groupeditempicker.js) that took some time to dig through.  The good news is that I was able to take advantage of those “native” JavaScript functions and write less of my own code.

Multi-Select Example

  • Both SPCascadeDropdowns and SPDisplayRelatedInfo now have a new CAMLQuery option which allows you to specify additional filters on the relationshipList.  You specify this as an additional CAML fragment which is then <And>ed with the filters which the library uses to grab the allowable values.  For example, the CAMLQuery option can contain a CAML fragment like:
CAMLQuery: "<Gt><FieldRef Name='ID'/><Value Type='Counter'>1</Value></Gt>"

or

CAMLQuery: "<Eq><FieldRef Name='Status'/><Value Type='Text'>Active</Value></Eq>"

Additionally, the $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo functions are now *much* more efficient.  As part of the refactoring I did in v0.4.5, there were some unnecessary Web Services calls happening.  With this efficiency change, there are no unneeded calls, so the dropdowns ought to behave almost as fast as they would without the functions sitting behind them.Of course there are some bug fixes as well.

Release Notes

New Functionality

Issue Tracker Item Function Operation Description
NA $().SPServices.SPCascadeDropdowns NA SPCascadeDropdowns now works with multi-select child columns.
NA $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo NA Added a new option on SPCascadeDropdowns and SPDisplayRelatedInfo for an additional filter, specified as a CAML fragment which is inserted into the existing filter. See the documentation for details.

 New Operations

Web Service Operation Options MSDN Documentation
Lists UpdateList listName, listProperties, newFields, updateFields, deleteFields, listVersion Lists.UpdateList Method

 Bug Fixes and Efficiency

Issue Tracker Item Function Operation Description
NA $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo NA Added an additional check for column value changes within the cascadeDropdown and showRelated private functions to reduce unnecessary Web Service calls. This change makes both functions considerably more efficient and therefore faster.
NA $().SPServices.SPCascadeDropdowns NA Fixed an issue in SPCascadeDropdowns when a child column is a Lookup to a Lookup column, and therefore displayed option values in the format ‘ID;#Value’, e.g., 1;#Massachusetts.
NA All list-based functions NA Tighter code to find z:row elements in XML using the selector: find(“[nodeName=z:row]“) based on a nice trick from Kevin Whinnery.
NA $().SPServices.SPCascadeDropdowns NA Fixed an issue in SPCascadeDropdowns when a parentColumn has multiple childColumns which caused only the first childColumn to be filtered.
NA listNameFromUrl() private function NA More reliable listNameFromUrl() using GetListCollection. The prior version was failing if the list had been renamed.
NA $().SPServices. SPRequireUnique NA Fixed a bug in SPRequireUnique where both values for duplicateAction (0 = warn, 1 = prevent) were acting like prevent. Also made the <span> which contains the messages unique per column in case the function is used more than once on the form.
11
Nov
09

A jQuery Library for SharePoint Web Services (WSS 3.0 and MOSS): the SPDisplayRelatedInfo Function

Cross posted from EndUserSharePoint.com

SPDisplayRelatedInfo is a function in the jQuery Library for SharePoint Web Services that lets you display information which is related to the selection in a dropdown. This can really bring your forms to life for users: rather than just selecting bland text values, you can show them images and links that are related to their choices.

Example

Let’s take a look at a customized edit form (EditForm.aspx copied into EditFormCustom.aspx) for a SharePoint list. In this list, we’re capturing sales opportunities in my favorite demo list. In addition to everything else, we want to capture the System that the customer might want to buy.

Here’s what the form might look like. It’s pretty humdrum (though it does have SPCascadeDropdowns applied to it so that the Country -> Region -> State relationships are enforced, as well as SPLookupAddNew for easy addition of Regions).

clip_image002

If we use the SPDisplayRelatedInfo function, we can spiff up the form quite a bit. Now when we choose a System, we can display an image of it and a link to the Lead Sales Rep:

When the user makes a different selection, the System Image and Lead Sales Rep will change accordingly. Much nicer, IMHO. What you can display in this manner for each column in your list on the form is really only left to your imagination, based on the available column types. You might include a link to a User Manual, for example, or show a list of available inventory at each of your warehouse locations.

Prerequisites

This is one of the places where you’ll be glad if you’ve followed my previous advice to set up reference lists for things like Products, States, and Regions. In this case, I have a list called Systems, which has three columns:

clip_image006

The System column in my Sales Opportunities list is a Lookup column into the Title column of the System list. That gives us a nice, tight relationship between the System value in the Sales Opportunity and the Title of the Systems list.

Syntax

As with all of the functions in the jQuery Library for SharePoint Web Services, everything is put in place from the UI or SharePoint Designer. There’s nothing to install server-side. You simply need to add references to the core jQuery library and the jQuery Library for SharePoint Web Services and then call the function. See the documentation on the Codeplex site for more details on how to set things up.

SPDisplayRelatedInfo currently takes the following options:

$().SPServices.SPDisplayRelatedInfo({
  columnName: "",// The display name of the column in the form
  relatedWebURL: "", // [Optional] The name of the Web (site) which contains the related list
  relatedList: "", // The name of the list which contains the additional information
  relatedListColumn: "", // The internal name of the related column in the related list
  relatedColumns: [], // An array of internal names of related columns to display
  displayFormat: "table", // [Optional] The format to use in displaying the related information. Possible values are: "table", "list".
  headerCSSClass: "ms-vh2",// [Optional] CSS class for the table headers
  rowCSSClass: "ms-vb", // [Optional] CSS class for the table rows
  debug: true // [Optional] If true, show error messages; if false, run silent
});

In the example above, the function call looks like this:

$().SPServices.SPDisplayRelatedInfo({
  columnName: "System",
  relatedList: "Systems",
  relatedListColumn: "Title",
  relatedColumns: ["System_x0020_Image", "Lead_x0020_Sales_x0020_Rep"],
  displayFormat: "list"
});

So I’m asking SPDisplayRelatedInfo to show me the values in the System_x0020_Image and Lead_x0020_Sales_x0020_Rep columns (these are the StaticNames of the list columns as opposed to the DisplayNames) in the Systems list under the System column in my form using the list display format where the System value matches the Title value. I’m just taking the default CSS classes for the example. As you can see, you can pass in any CSS class you’d like to make the SPDisplayRelatedInfo output match your site branding.

The displayFormat takes one of two options:

  • “table” displays the matching items much like a standard List View Web Part would, in a table with column headers
  • “list” also uses a table, but displays the item(s) in a vertical orientation, like in the example above

How Does It Work?

The SPDisplayRelatedInfo works like this:

  • When the function is first called, it attaches an event handler to the dropdown control. The logic here varies a bit depending on what type of dropdown it is.
  • When the selected option in the dropdown changes, SPDisplayRelatedInfo calls two Lists Web Service operations:
    • GetList on the relatedList to get information about its columns (fields)
    • GetListItems to get the items where the specified column’s value matches the current selection. Note that there can be multiple items returned; generally displayFormat: “table” makes more sense if you’ll want to display multiple items.
  • For each column it’s asked to display, SPDisplayRelatedInfo calls a private function (showColumn) to render the column value based on its type. Most of the normal column types are covered, though locale conversions can’t be done from the client side (yet!).

Conclusion

Quite a few of the early functions I’ve implemented in the library can help you make your forms more interactive and interesting to use. Having worked with data for as long as I have, I know all too well how the GIGO rules can bite you. (Garbage In, Garbage Out, in case you haven’t seen the acronym before.) By utilizing some of the functions like SPDisplayRelatedInfo, you can help your users do a better job adding data into SharePoint lists, and maybe even make it a little bit more fun.

08
Nov
09

SharePoint’s Web Services, jQuery, and the z:row Namespace in Safari and Chrome

jQuery’s totally cross-browser capable, right?  Well, generally, yes.  However, through no fault of jQuery, Safari and Chrome don’t seem to like the z:row namespace that the SharePoint Lists Web Service GetListItems operation returns.  I found a nice workaround for z:row from Mike Hacker to improve cross-browser compatibility.  I added a check for ItemCount up front so that we don’t try to use the getElementsByTagNameNS function in IE if there have been no rows returned legitimately.

Here’s my function.  I call it with the XMLHttpRequest result wherever I’m using GetListItems to get a usable rowset regardless of the browser.

// Find the rows in an XMLHttpRequest.  This includes a workaround for Safari and Chrome's
// aversion to the z:row namespace.
function getZRows(rXML) {
    var rows;
    var itemCount = $(rXML).find("rs\\:data").attr("ItemCount");
    if (rXML.getElementsByTagName("z:row").length == 0 && itemCount == undefined) {
        rows = rXML.getElementsByTagNameNS('*', 'row');
    } else {
        rows = rXML.getElementsByTagName("z:row");
    }
    return rows;
}

I’ve tested this in IE8, Firefox, Safari, and Chrome on my Windows PC.  It still doesn’t seem to solve the issue on Safari for Mac, but I’m getting there.  This will at least let the functions in v0.5.0 of my jQuery Library for SharePoint Web Services work with all of the main browsers on the Windows side of things.

01
Nov
09

jQuery Library for SharePoint Web Services: Interim Update on What’s Coming Up in v0.5.0

This post was also published at EndUserSharePoint.com

While seemingly everyone else in the SharePoint Universe is oohing and aahing over SharePoint 2010, I continue to plod along with my jQuery Library for SharePoint Web Services.  (Follow the library on Twitter: @jQSPWS.) I’m sticking with my belief that we’re all going to be using SharePoint 2007 (WSS 3.0 or MOSS) for a good long time, and my library will help make it work better and more “coolly” for us now rather than waiting for SharePoint 2010.

SharePoint 2010 isn’t totally off my radar screen, however.  I’ve had some discussions with a couple of folks on the SharePoint team at Microsoft about making the library forward compatible with SharePoint 2010.  The SharePoint 2010 Web Services documentation is now available in the SDK at MSDN, with the existing Web Services still available (some with new operations) and new Web Services exposing the new functionality in SP2010, of course.  As I learn more about SharePoint 2010, I’ll be coming up with a strategy for supporting it.

I haven’t had this much fun writing code for a long time.  I get to learn some new approaches to things, code ‘em up, and then help a bunch of you to get them implemented.  I’m having a ball.  For those of you I’ve been interacting with on the Codeplex site in the Discussions and Issue Tracker, I want you to know that I appreciate your patience in working with me to use the library.  It’s still really in its infancy, and because of your willingness to use it now, I’ll be able to come up with a better set of solutions for you and others later.

There are quite a few things coming up in v0.5.0 that are inspired directly from your troubles in early usage, and hopefully that will make it easier going forward.  There are also a bunch of enhancements and new functions on the drawing board.  I’ll let the actual Release Notes cover all of the nitty-gritty details (keep watching them, as they will evolve as the codebase evolves), but here are a few highlights you can expect in v0.5.0, coming in the next few weeks.

  • Better error handling in the key functions - Quite a few of you using the library have never touched scripting before, and that’s fine; I don’t expect you to need to debug the code.  The current implementation of functions like SPCascadeDropdowns and SPDisplayRelatedInfo gives you nothing to go on if they don’t work when you first try to use them.  I’m implementing an optional debug mode for these functions, which I’ll roll out to other functions over time.  It’ll let you know if you’re doing something obviously wrong at first, like calling the function with an invalid option.
  • New functionality – Many of you have asked that I make SPCascadeDropdowns work for multi-select lookup columns, and I’m putting that functionality into this release.
  • Added functions – I’ve been talked about SPAuditScripts for quite a while, but I haven’t gotten it done.  With this library comes a responsibility to help with management of its usage.  The SPAuditScripts function will help you do that by telling you where you or others are using script in Content Editor Web Parts (CEWPs).  I’ll have at least an initial version of this function in the release.
  • Tighter code and efficiency in the existing functions – As with most code, the first iteration isn’t always the best one.  By learning from current usage, I’m aiming to get some better code in place on some of the key functions.
  • Bug fixes – See the list in the Release Notes.

This release will be bigger and take longer than my early iterations; the first releases often had only days between them.  Now that there are so many of you out there actually using the darn thing, I owe it to you to be taking a more thorough and careful approach to new enhancements, especially those which impact existing functionality.  That said, if you’d like to be on the beta testing team, drop me a line through the library’s Codeplex site or my blog.  You’ll get access to the new bits ahead of everyone else and can help make the library better and better for others.  If you do drop me a line, let me know a little about your background and goals; it’ll help me as well.  I’ll probably be reaching out to those of you who have had specific issues to try some new bits out for me to get your feedback as well.

Finally, I’m doing all this because I love it, but several of you have indicated that you’d be willing and interested in contributing to the effort monetarily.  (The offer of French Fries was even better!)  I’m looking into how I can rig something up so that you can contribute to an organization that means a lot to me instead.  Watch for details on that in the upcoming days or weeks.  I do work for a living, of course, so also consider Sympraxis Consulting for your next SharePoint project.  We’ve got a pretty good toolkit.

28
Oct
09

A jQuery Library for SharePoint Web Services (WSS 3.0 and MOSS): Part 2 – How Does It Work?

Cross posted from EndUserSharePoint.com

WebServicesIn my last post, I wrote about why I decided to start building the jQuery Library for SharePoint Web Services. In this post, I’ll tell you a bit about what’s there and how it works. If you’re totally familiar with the SharePoint Web Services, this may all be old hat to you, but I felt it would be useful to explain some of the underlying concepts in what I think of as “English” for those who might get something out of it.

As I’ve mentioned, the fundamental idea for the library was to “wrap” the key SharePoint Web Services which would allow you to talk to SharePoint in real time without full page refreshes. As I looked across the Web Services, I saw clear patterns in how they were called (and some glaring exceptions). The patterns meant that I could do some nice generalizing in my jQuery code. The “core” of the jQuery Library for SharePoint Web Services is the $().SPServices function, which allows you to simply call each Web Service operation.

There is a set of Web Services which are available in WSS 3.0 and MOSS, and then some that are only available in MOSS. The table below shows the Web Services currently available in the library and where they work, along with links to the MSDN documentation:

Web Service WSS 3.0 MOSS MSDN Documentation
Alerts Alerts Web Service
Authentication Authentication Web Service
Forms Forms Web Service
Lists Lists Web Service
Permissions Permissions Web Service
Users and Groups Users and Groups Web Service
Versions Versions Web Service
Views Views Web Service
WebPartPages Web Part Pages Web Service
Webs Webs Web Service
PublishedLinksService   PublishedLinksService Web Service
Search   Search Web Service
UserProfileService   User Profile Web Service
Workflow   Workflow Web Service

I haven’t tried to wrap every single Web Service or every single operation of each. I’ve focused on the Web Services and operations that seemed as if they would provide the most benefit the most often. If I’ve missed something that would be of use to you, then by all means let me know by dropping a comment into the Discussions on the Codeplex site. I’d be happy to add it in the next release.

Each Web Service is called with a Simple Object Access Protocol (SOAP) Envelope which contains information about what you want to accomplish in the SOAP Body. As an example, here’s what the SOAP call for the Lists Web Service’s GetList operation looks like:

<xml version="1.0" encoding="utf-8"?>
  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
  <GetList  xmlns="http://schemas.microsoft.com/sharepoint/soap/">
   <listName>string</listName>
   </GetList>
   </soap:Body>
  </soap:Envelope>

You can see what the SOAP call for any of the SharePoint Web Services needs to look like by going to /_vti_bin/[WebService].asmx. You can tack this onto the end of any URL within SharePoint. Here are a couple of examples:

  • http://servername/_vti_bin/lists.asmx
  • http://servername/sitepath/_vti_bin/workflow.asmx

On those pages, you’ll see what operations are available, and clicking on any of the operation links will show you the SOAP request and response structures. I’ve stared at most of these a lot so that you don’t really have to.

Building the SOAP Request

The SOAP Envelope and SOAP Body “wrappers” are the same for all of the SharePoint Web Services. Think of this wrapper as saying “I’m going to speak SOAP to you.” In my library, I store these wrappers in the SOAPEnvelope.header and SOAPEnvelope.footer variables:

SOAPEnvelope.header = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body>";
SOAPEnvelope.footer = "</soap:Body></soap:Envelope>";

Next comes what I call the SOAPEnvelope.opheader, or Operation Header. The Operation Header varies based on what operation you want to use. For the most part, the structure of the Operation Header is consistent for all of the operations within a Web Service, but there are a few exceptions. (Naughty developers.) The Operation Header tells the specific Web Service what operation you want to have a chat with.

We also need to have a SOAPAction, which is passed ahead of the request. In the case of the GetList operation above, it looks like this:

http://schemas.microsoft.com/sharepoint/soap/GetList

The SOAPAction is also generally consistent within a Web Service, but not always. (Naughty developers again.)

Finally, we get to what I call the SOAPEnvelope.payload. This is where you pass in the real data that you want to use to talk to the Web Service. In the GetList example above, the payload simply contains the listName, which can be either the text name of the list (e.g., States) or the GUID for the list (e.g., 8BADF8E2-3758-4D1B-9966-045F4A77F73D).

The AJAX Call

Based on what operation you pass into the SPServices function of the library, it builds up the appropriate SOAP call and uses it “talk” to the Web Service using AJAX (shorthand for Asynchronous JavaScript and XML). The AJAX call is amazingly simple:

$.ajax({
   url: ajaxURL, // The relative URL for the  AJAX call
   async: opt.async, // By default, the AJAX calls are  asynchronous. You can specify false to  require a synchronous call.
   beforeSend: function  (xhr) { // Before sending the msg, need  to send the request header with the SOAPAction
     xhr.setRequestHeader("SOAPAction",  SOAPAction);
   },
   type: "POST", // This is a POST
   data: msg, // Here is the SOAP request  we've built above
   dataType:  "xml", // We're  sending XML
   contentType:  "text/xml; charset='utf-8'", //  and this is its content type
   complete:  opt.completefunc // When the call is  complete, do this
});

Calling the Library

To set things up to use the jQuery Library for SharePoint Web Services, you’ll need to add references to it and the core jQuery library in the right context for what you are trying to accomplish. This may mean that you add the references in your master page (if you are going to use jQuery pervasively), in a page layout (if only a certain class of pages will utilize jQuery), or in specific pages (if you want to use some of the functions only on a list’s forms, for example). These references will look something like this:

<script language="javascript" type="text/javascript" src="/jQuery%20Libraries/jquery-1.3.2.min.js"></script>
<script language="javascript" type="text/javascript" src="/jQuery%20Libraries/jquery.SPServices-0.4.1.min.js"></script>

I recommend putting both .js files into a Document Library in the root of your Site Collection called something like “jQuery Libraries”, as above. This way, you can manage them as content. For deployment purposes, you may want to use a generic name for the current version you are using so that you won’t need to update every reference every time you upgrade the .js files:

<script language="javascript" type="text/javascript" src="/jQuery%20Libraries/jquery-latest.min.js"></script>
<script language="javascript" type="text/javascript" src="/jQuery%20Libraries/jquery.SPServices-latest.min.js"></script>

What all this adds up to is that you can use the jQuery Library for SharePoint Web Services to call any of the Web Service operations it wraps as simply as this:

$().SPServices({
   operation:  "GetList",
   listName:  "States",
   completefunc: function  (xData, Status) {
     ...do something...
   }
});

which is a whole lot easier and efficient than trying to decipher all of the SOAP and AJAX requirements for each operation every time.

You can also pass in some optional options:

  • WebURL — If you pass in a Web URL, then that context is used for the ajaxURL in the AJAX call above. If you don’t pass in a WebURL, the current context is used. (The current context is determined by a call to the WebUrlFromPageUrl operation of the Webs Web Service. This is exposed as the public function $().SPServices.SPGetCurrentSite, as it can be a little tricky to determine the current site otherwise.) The WebURL is only useful in the case where the context matters to the result, and this is indicated in the library’s Documentation.
  • async — [true | false], as described above

One important caveat: a lot of people and blog posts will tell you to simply drop jQuery into Content Editor Web Parts (CEWPs). I’m not saying that this is always a bad idea, but it will make keeping track of your jQuery usage pretty difficult. I recommend using SharePoint Designer to put the jQuery into the pages them selves. This allows you to use whatever deployment mechanisms you already have in place for customized (unghosted) pages and also eliminates the possibility that a user will delete or change the jQuery in the CEWPs inadvertently.

I’m working on a function called SPAuditScript which will let you get a report of script usage in CEWPs across a Site Collection. This ought to help with keeping track of things as well as allay some of the fears that IT folks have about non-developers doing developer-like things without any way to track it.

The Results

When you make one of these calls, you get back XML, just as you’ve passed XML into it. As I was building the library, I found that I very often wanted to see what was in that XML in an easy to read format, so I built the $().SPServices.SPDebugXMLHttpResult function. If you’re comfortable with XML and debugging tools, you may never need this function, but I find it useful. If you wanted to use it in the above example, replace the completefunc with this:

completefunc: function (xData, Status) {
   var out =  $().SPServices.SPDebugXMLHttpResult({
     node:  xData.responseXML
   });
   $(divId).html("").append("<b>This  is the output from the GetList operation:</b>" + out);
}

where divId is the ID for a DIV on the calling page where you’d like to place the results. The output from the $().SPServices.SPDebugXMLHttpResult function for GetList will look something like this excerpt:

jQuery Library for SP Web Services

On the other hand, if you’d like to work with the output, you’d probably do something like this:

$().SPServices({
   operation:  "GetList",
   async: false,
   webURL: opt.webURL,
   listName:  opt.listName,
   completefunc:  function(xData, Status) {
     $(xData.responseXML).find("Field").each(function()  {
       if($(this).attr("StaticName")  == opt.columnStaticName) displayName = $(this).attr("DisplayName");
     });
   }
});

This example comes from the $().SPServices.SPGetDisplayFromStatic function. In the completefunc, I find all of the Field elements, iterate through them until I find the one I’m looking for, then grab the DisplayName attribute to return. I’m not going to go into a jQuery tutorial here, but working with the XML SOAP response is often about this simple.

Conclusion

So all of this (hopefully) explains what happens when you use the jQuery Library for SharePoint Web Services function $().SPServices to call a Web Service operation. Any one of these Web Service operations can let you do some spiffy stuff, but to me the real power comes in utilizing one or more operations together to accomplish cool things. For instance, the $().SPServices.SPCascadeDropdowns function uses GetListItem, $().SPServices.SPLookupAddNew uses GetList (2x) and GetFormCollection, and so on.

In my next post, I’ll write about the other functions in the SPServices namespace and how you can use them to improve the user experience in SharePoint.

28
Oct
09

SPCascadingDropdowns Demystified (or Mystified, Depending on Your View)

In my  jQuery Library for SharePoint Web Services, one of the most popular functions is $().SPServices.SPCascadeDropdowns.  The SPCascadeDropdowns function lets you set up cascading dropdowns on SharePoint forms. What this means is that you can enforce hierarchical relationships between column values.  This is sometimes called connected dropdowns or linked dropdowns (or probably other things I haven’t run across yet).

The function uses the GetListItems operation of the Lists Web Service to refresh the allowable values based on relationships which are maintained in reference lists. By implementing this function, you can remove all of the coding requirements to manage the hierarchical relationships (once it is in place) and let your users manage the content.

The requirement that the values be stored in a list seems to baffle many people, as do the basic steps to use the function.  I’m not dissing anyone here.  I know that there are people using this stuff who don’t have a development background.  I see that is a Really Good Thing, and is one of the reasons I’ve implemented the functions in the library the way I have.  But what it can mean is that the underlying concepts may be downright foreign.

Here are some explanations of the most common things I see people struggling with.  I’m going to add these ideas into the documentation, of course, but I thought a blog post might be a good idea, too, as some of these ideas apply in general.

  • The src attribute in <script src="../../jQuery%20Libraries/jquery-1.3.2.js"></script> should point to where *you* put the .js files.  You can store them anywhere that makes sense for your needs.  To reiterate my suggestion in the documentation: I recommend putting them into a Document Library in the root of your Site Collection called something like jQuery Libraries. However, they can be stored anywhere as long as all users who need to access them have read permissions.
  • relationshipListParentColumn and relationshipListChildColumn should be the internal name (also known as the StaticName) for the columns in the relationshipList.  parentColumn and childColumn should be the DisplayNames for the columns on the form.
    • When you first create a column in a list, the name which you give the column becomes the StaticName.
    • The StaticName is encoded, meaning that certain characters are replaced with a set of characters which represent their ASCII value.  So if you name a column Product Description, the StaticName will be Product_x0020_Description. Terms & Conditions becomes Terms_x0020__x0026__x0020_Condit.  _x0020_ = space (" "), _x0026_ = ampersand ("&"), etc.
    • As you can see from the Terms & Conditions example above, the StaticName is limited to 32 characters, including the encoded values.
    • If you aren’t sure what the StaticName for a column is, go into List Settings, click on the column name in the Columns section, and look at the URL.  At the end of the URL, you’ll see a Query String parameter called Field: &Field=Lead%5Fx0020%5FSource.  The string after the = sign is the StaticName, in this case Lead_x0020_Source.  The %5F values are the underscores ("_"_ encoded for the URL.  I know this can be confusing if you aren’t familiar with these concepts.
    • If you subsequently change the column name (like renaming Title to Failure), the StaticName stays static (does not change), but the DisplayName does change.
    • One of the dangers of this is that a column is renamed several times and ends up being used for something entirely different than its original intent.  Because of this, it’s often better to delete a column and add a new one than renaming it.
  • Don’t create the lists to drive the cascading dropdowns *only* to drive the cascading dropdowns.  These lists are the best practice way to manage the choices that are available to a user in list columns.  This is a key concept way beyond the cascading dropdowns idea:
    • Things like States or Regions or Products or Parts ought to be created as Site Columns in the root of your Site Collection which are lookups into lists and then used everywhere in the Site Collection you need them.
    • Because the choices are stored in a list, you can manage them as content as opposed to as settings, applying content management rules or workflows, as needed.
    • Since the values are stored in one place, a change in the list ripples out to every list or library where the Site Column is used.  This is an incredibly powerful capability in SharePoint that is totally underused and ensures information uniformity and a good information architecture.
    • By taking advantage of this capability, you can begin to enforce a common taxonomy of concepts which apply across the organization.  Rather than calling Product 12345 the Blue Widget and the Left Screwed Thing and the One that J&J Buys, we can all call it Product 12345 and understand what we are all talking about.
19
Oct
09

jQuery Library for SharePoint Web Services v0.4.0 Released

This release contains two functions I’ve wanted to get into the library for a long time: $().SPServices.SPRedirectWithID and $().SPServices.SPRequireUnique.  These two functions show how you can solve tricky problems with jQuery and the SharePoint Web Services much better than any of the other approaches available, IMHO.

$().SPServices.SPRequireUnique allows you to specify a page to redirect to after creating a new list item with a NewForm.aspx (or your customization of it).  The two posts discussing this topic on my blog are together the #1 most read by a long shot. (You can read these two old posts: Redirect to Another Page from NewForm.aspx with the New Item’s ID: Redux and Redirect to Another Page from NewForm.aspx with the New Item’s ID to see where my thinking used to be.)

$().SPServices.SPRequireUnique lets you require unique values in a Single line of text column.  Generally you would use this on the Title column so that you can use a reference list relationally, such as the lists I use in the examples for $().SPServices.SPCascadeDropdowns to contain the States and Regions.

The release is rounded out with a couple of new Lists Web Service operations (CheckInFile and CheckOutFile) and exposing a couple of the nifty “utility” functions ($().SPServices.SPGetLastItemId and $().SPServices.SPSPGetDisplayFromStatic) I wrote in the process of building the first two functions above.

You can download jQuery Library for SharePoint Web Services from Codeplex.

Release Notes

New Functions

Function Description
$().SPServices.SPRedirectWithID This function allows you to redirect to a another page from a new item form with the new item’s ID. This allows chaining of forms from item creation onward.
$().SPServices.SPRequireUnique Checks to see if the value for a column on the form is unique in the list.
$().SPServices.SPGetLastItemId Function to return the ID of the last item created on a list by a specific user. Useful for maintaining parent/child relationships.
$().SPServices.SPSPGetDisplayFromStatic This function returns the DisplayName for a column based on the StaticName.

New Operations

Web Service Operation Options MSDN Documentation
Lists CheckInFile pageUrl, comment, CheckinType Lists.CheckInFile Method
  CheckOutFile pageUrl, checkoutToLocal, lastmodified Lists.CheckOutFile Method

 




 

December 2009
M T W T F S S
« Nov    
 123456
78910111213
14151617181920
21222324252627
28293031  

Twitter Updates