[Apologies if this article appears in your feed as a duplicate – it didn’t go out to many readers originally due to a Feedburner glitch]
- Boiling jQuery down to the essentials (technique)
- Using jQuery AJAX with a HTTP handler (technique)
- Returning JSON from a HTTP handler (technique)
- Enable Intellisense for Client OM and jQuery (tip)
- Useful tools when building AJAX applications (tip)
- Migrating existing applications to jQuery/AJAX – this article
One of the most interesting things I did when getting my head around AJAX/jQuery with SharePoint, was to actually migrate something I’d written over to AJAX. I wanted to do this for a few reasons:
- It was a real-life app rather than a Hello World
- It should be a good way to learn
- I figured demo’ing the steps live would be an interesting segment in my talk at SharePoint Saturday UK
I decided that my SP2010 Feature Upgrade Kit would be a good candidate for this exercise – it’s more of a “mini-app” than a full blown application, in that it really consists of a couple of SharePoint application pages. These deal with the new ‘upgradable’ Features capabilities (read my Feature Upgrade series for more info), but fundamentally it queries a database, displays the records and then allows some or all of them to be updated – in other words, a fairly typical CRUD app which would be good to AJAX-ify.
Needless to say, it’s all standard ASP.Net/SharePoint controls, so a postback happens when you do a search/update records etc.
The original code
If you’re in any way interested in the upgrade process (or the mindset for building AJAX apps), it’s probably worth having a quick scroll to get feel for the original code at this point.
The ASPX page:
Changes required for AJAX
Here’s the process I went through to covert the app to AJAX – I’ll list the code lower down (and post the solution file) if you want to look at any specifics. If you’re new to building the AJAX way, I personally think it’s quite eye-opening:
- Delete ALL the code in the code-behind. You Ain’t Gonna Need It (in this form), even if it did take you a few late nights to write it :)
- In the .aspx, remove any of the ASP.Net controls used in the app and switch them to good ol’ fashioned HTML controls. For example:
- The dropdown for the Feature scope is changed from a <asp:dropdownlist> control to a <select> control.
- The ‘Feature status’ radio buttons are changed from a <asp:RadioButtonList> to a <input type="radio">.
- The ‘Search’ and ‘Upgrade Features’ buttons are changed from <asp:Button> to <button>.
- The <asp:Panel> and <asp:Label> controls used to present results messages are removed completely.
- The SPGridView control used to display records is also removed – for these last 2 items, you’ll see that I use jQuery to insert HTML into the parent div instead.
Note that often you’ll want to keep many other ASP.Net controls – in my case I kept the InputFormSection, WebApplicationSelector and SiteCollectionSelector controls, since these are SharePoint controls responsible for application page look and feel, and selecting the web app/site collection respectively. In terms of the selector controls, of course I’ll still need to ‘get’ the selected value but it turns out it’s entirely possible to do this with jQuery instead of server side code.
- Introduce some jQuery code:
- Event binding code on page load – here we bind event handlers to HTML the button clicks.
- The following jQuery methods:
- getWebAppSelectorValue() – since a Microsoft.SharePoint.WebControls.ApplicationSelector control actually renders a div containing a link and span, the following jQuery will fetch the value (assuming the HTML ID is correct) - $('a#zz1_webAppSelector span').text().
- getWebAppSelectorValue() – similar to above.
- displayFeaturesTable() – does the work of fetching the records (list of Features to be upgraded) and displaying them in a HTML table similar to the output of a SPGridView. Key method – this calls into a HTTP handler using jQuery AJAX (as shown in article 3, using jQuery AJAX with a HTTP handler) which queries SharePoint for Features to upgrade, and ultimately injects the HTML for the results table into the page.
- upgradeFeatures() – does the work of updating the selected records (upgrading the Features) and displaying the results. Key method – this calls into a different method on the HTTP handler using jQuery AJAX, passing the IDs of Features to upgrade, collecting the results from the server and updating the page accordingly.
- Introduce the HTTP handler – generally this is written simultaneously with the calling jQuery. I detect parameters in the URL to know which action is being processed (i.e. fetching the records or updating the records). Add code for each:
- In the ‘QueryFeatures’ branch of the code, fetch a list of Features requiring upgrade, then JSON-serialize the data and return (as shown in article 4, Returning JSON from a HTTP handler)
- In the ‘UpgradeFeatures’ branch, write code to resolve Features from the passed IDs, then call SPFeature.Upgrade() on each. Finally, return a JSON-serialized object containing the results.
Once the changes were made, the app definitely was a lot slicker without postbacks. Although screenshots can’t show it, the grid fades in smoothly once the results are returned (courtesy of a jQuery fadeIn()) and upgrading the Features has a similar experience. If anything, there was a (somewhat ironic) new problem that everything happened so fast that it didn’t seem like the processing work had been done properly.
If you want to download the code to take a close look, there’s a link at the end of the article. Otherwise here’s what the jQuery looked like:
And the HTTP handler:
Although I ended up with a fully-functioning app, I decided not to go ahead and implement the final bits and pieces to ‘production-ize’ these changes (into the main Codeplex release). It didn’t feel like there was much more to do, but ultimately the exercise was about me learning AJAX techniques rather than about this specific tool, and realistically there isn’t a ton of added value for AJAX in this particular case. No doubt this is partly because most users of this tool would expect the operation to take a bit of time, and therefore a postback is pretty acceptable. In case you’re interested, this was my list of observations or things I’d want to iron out:
- Replace hardcoded HTML in HTTP handler with jQuery templates (which weren’t actually released when I did the work)
- Consider presentation speed of results – currently there is an SP.UI.Notify message saying something like ‘Feature upgrade started..’, but unless lots of processing is required to upgrade the Features things are so quick that it shows up at the same time as the results are shown!
- Some refactoring of the HTTP handler and jQuery would be nice
Download the files
For anyone interested, I posted two VS solutions (before and after AJAX). In fact they are a specific release of the main Codeplex project, available here. If you take a look and run into issues or have questions, please post here or on Codeplex.
So this concludes my SharePoint and AJAX series, I hope it was in some way useful. Although this post has perhaps shown that AJAX isn’t necessary everywhere, recently I noticed a couple of experienced SharePoint folks complaining on Twitter about the postback hell which is the ‘Manage User Profile Properties’ page in SharePoint 2007/2010 Central Administration. This is the page I used as an example in my AJAX talk and referred to in the 1st article – if you have any doubts about why you should build your apps, web parts and page controls with AJAX these days, feel free to go to that page and reorder a bunch of properties! I genuinely believe it’s an important approach for any developer these days, and you’ll never look back once you’ve done your first one. Happy coding!