Forcing SharePoint into asynchronous AJAX-like submission, using jQuery
A while ago I posted a screencast on Twitter, of me navigating around a WSS 3.0 document library, without any synchronous reloads (full page refreshes): changing sort settings, creating folders and deleting files - all updated in place. If you didn't catch that, here's the screencast:

The demo looks pretty cool (he said confidently), and I feel that these are features SharePoint is lacking. With SharePoint 2010, this will all have been improved majorly, so it's admittedly not the most useful feature to be adding now - a mere few months before the release of '10. For the sake of (mis)using JavaScript and jQuery, though - let's stride on!
The code behind the demo is pretty intrusive - I'll be the first to admit that - and it's in no way complete. What it does, is override the usual SharePoint document library submit behavior, with a jQuery asynchronous load. The loaded data, which would be the page returned from the server, is chopped up and updated at the relevant spots on the existing page. If the user opens a folder in a document library, the asynch call loads the page with the view of the folder, then strips all the stuff which isn't the view of the folder, and replaces the current folder view: straight forward DOM stuff.
For this hack to (kinda) work, I also override some standard SharePoint APIs which returns state information (e.g. which document library folder we're currently viewing). I spent a minimal amount of time completing this, so I have no doubt that some state info will be missing or wrong in the code below, but it does seem to work fairly well for folder navigation, creation and item deletion. Sorting, however, is another matter entirely.
So all in all, there are quite a few kinks. The create folder popup is included mostly for show, and looks horrible. I didn't adapt this to work with the upload form, although that improvement would be pretty simple to complete. One of the more prominent issues, however, is the scripts which are returned along with the asynchronous loads. IE8 freaks out somewhat by these, and throws an error at you when you e.g. delete an item in a library. The fix is to ignore scripts in the parts of the page we keep (the view of the folder, etc.), but that's another thing I didn't look into.
All in all, I consider this a curiosity, rather than something of actual value. I'm positive someone with more time on their hands than me could improve it a ton, but then again - why bother with SharePoint 2010 coming up :-)
Excuses aside, here's the important part of the script:
var wssHook =
{
/* Public interface */
setupWSSHooks: function()
{
this.hookWSSApi("FilterFieldV3");
this.hookWSSApi("GetSource");
this.hookWSSApi("GetUrlKeyValue");
SubmitFormPost = this.hookedSubmitFormPost;
STSNavigate = this.hookedSTSNavigate;
},
/* Private interface */
hookWSSApi: function(api)
{
this[api] = window[api];
var body = window[api].toString();
eval("window[api]=function" + body.substring(body.indexOf("(")).replace("window.location.href", "window.realurl?window.realurl:window.location.href"));
},
hookedSubmitFormPost: function(url, forcesubmit, getonly)
{
window.realurl = url;
var postvars = {};
if(!getonly)
{
$(document.forms[MSOWebPartPageFormName]).find("input").each(function(id, element) { postvars[element.name] = element.value; });
}
else
{
postvars = "";
}
$("table#MSO_ContentTable>tbody").load(url + " table#MSO_ContentTable>tbody", postvars,
function(resp, status, req)
{
var location = req.getResponseHeader("Location");
if(location)
{ window.realurl = location; }
});
},
hookedSTSNavigate: function(url)
{
var shown = false;
var dialog = $("<div></div>");
dialog
.dialog({
width: "80%",
height: "300",
modal: true,
close: function(event, ui) { dialog.remove(); SubmitFormPost(window.location.href, false, true); }
})
.append(
$("<iframe frameborder='0' width='100%' height='100%' src='" + url + "' />")
.load(function(){
if(shown) { dialog.dialog('close'); return; }
shown = true;
var c = $(this).contents();
var ctrls = c.find("td.ms-bodyareaframe>table").clone();
ctrls.find("script").remove();
c.find("table#.ms-main:first").remove();
c.find("form#aspnetForm").append(ctrls);
})
);
}
}
You can download the entire thing, including jQuery / jQuery-UI loads from the Google CDN, here.
If you want to give it a test run in your own portal; head to a document library, add a content editor web part and add the code downloaded from the link above as the html source.

4 comments:
I LOVE the concept! Copy-pasted the code from the link but am unfortunately getting javascript errors on my page :(
Dialog will show, but no dialog contents for upload doc and view item (just a white area).
Edit item will show quickly for 1 sec and then dissappear with a javascript error.
Would really love to see this working!
Yeah, I'm with Jaap - this is really neat. Unfortunately a multi-value select list (the two select lists next to each other with add/remove buttons) doesn't work, nor does Manage permissions.
But a really nifty concept!
I think you guys missed the hints I threw off in the post, about it *nearly* working :)
It's by no means intended to be a complete solution to asynch'ify SharePoint, but rather a start for potential jQuery hackers to play around with.
This looks great. One issue you might run into when trying to get the upload item to work is the fact that you can't upload with script. Do you know of any workarounds to get this working?
Post a Comment