I needed to update a SharePoint list item directly on client side in a classic SharePoint list form. I found this blog who explains very well how to do it by using Prototype but I was already using jQuery and didn’t want to add another javascript framework to my solution. Sure this is very easily portable to jQuery but I wanted a cleaner solution.
I found this: jQuery SOAP Client, a jQuery plug-in (it’s really an add-on because it doesn’t use jQuery extension mechanism) who was looking very promising. So I started to code…
I was going to call the UpdateListItems of the list web service (http://server/_vti_bin/lists.asmx). This method requires two arguments: listName and updates. Updates are the CAML commands describing the changes to the list and looks like this:
<Batch OnError="Continue">
<Method ID="1" Cmd="Update">
<Field Name="ID">1</Field>
<Field Name="Title">updated title</Field>
</Method>
</Batch>
I think that’s pretty readable: we want to change the Title of the element with the ID=1 to “updated title”.
Next: the javascript code using jQuery SOAP Client:
var wsMethod = "UpdateListItems";
var soapNs = "http://schemas.microsoft.com/sharepoint/soap/";
var soapBody = new SOAPObject(wsMethod);
soapBody.ns = soapNs;
soapBody.appendChild(new SOAPObject("listName")).val("list1");
soapBody.appendChild(new SOAPObject("updates")).val(batch);
var sr = new SOAPRequest(soapNs + wsMethod, soapBody);
SOAPClient.Proxy = "http://server/_vti_bin/lists.asmx";
SOAPClient.SendRequest(sr, processResponse);
For this to work it needs to be executed from an already authenticated SharePoint web page. Internet Explorer automatically passes the credentials with the XHR call. You could pass the credentials in the jQuery call but I wouldn’t do that if I where you.
Well, this didn’t work… I was getting some generic SharePoint error page, not very useful for debugging so I fired up Fiddler2.
I found out that the response was a HTTP error code 415 – Unsupported Media Type. I noticed some differences between the SOAP request created by jQuery SOAP Client and the SOAP code expected by the service and modified the plug-in accordingly. But I was still getting the same error.
And then I saw it: the Content-Type sent was application/x-www-form-urlencoded, text/xml; charset= "utf-8"; Thing is when you make an AJAX call with jQuery it automatically ads application/x-www-form-urlencoded content-type if no content-type is specified. But jQuery SOAP Client added the content-type not by using jQuery but directly into the XmlHttpRequest object:
$.ajax({
type: "POST",
url: SOAPClient.Proxy,
dataType: "xml",
processData: false,
data: content,
complete: getResponse,
beforeSend: function(req) {
req.setRequestHeader("Method", "POST");
req.setRequestHeader("Content-Length", SOAPClient.ContentLength);
req.setRequestHeader("Content-Type", SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"");
req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer);
req.setRequestHeader("SOAPAction", soapReq.Action);
}
});
Fixing that was simple and… it worked!!!
$.ajax({
type: "POST",
url: SOAPClient.Proxy,
dataType: "xml",
processData: false,
data: content,
contentType : SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"",
complete: getResponse,
beforeSend: function(req) {
req.setRequestHeader("Method", "POST");
req.setRequestHeader("Content-Length", SOAPClient.ContentLength);
req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer);
req.setRequestHeader("SOAPAction", soapReq.Action);
}
});
You can download the source code here
Maybe I missed it, but do you have a download for the complete (client side) code, or a demo somewhere?
Also, you say IE automatically passes the credentials with the XHR call – do you know if the the same applies for other browsers?
A jquery plugin for SharePoint would be great…
Found this entry while searching for a SOAP client jquery plugin and got the one you mentioned. I downloaded the current beta and checked to see if this problem needed fixing – but it seems the author has implemented this fix in his code.
Figured I’d just let you know it’s now fixed, so shouldn’t be an issue in the future
Oskar> I added a link to the source code at the end of the post; better late than never…
Eli> Is there a newer version than 6 – May 16, 2008 ?
Because this version still calls req.setRequestHeader(“Content-Type”…
Nice work.
I’d been doing this a much more difficult way over the past 3 years as I was using a standard http request and constructing all of the soap headers.
Your way is much nicer. I knew about the jQuery.Soap plugin but hadn’t yet looked at it, your code is the quick start I was hoping to find.
Btw, have you seen the utility I’ve just open sourced for SharePoint? ShUIE http://www.codeplex.com/ShUIE/
It’s designed to allow SharePoint developers to work with jQuery and to do funky stuff on the front end.
I’m probably going to be adding the soap stuff to that so that it becomes trivial to lookup list data in other sites… I’ll ping you an update when I make such a thing.
“You could pass the credentials in the jQuery call but I wouldn’t do that if I were you.”
How do you go about doing that?
Pingback: NH Code Camp 09 « Absolute Bits & Beats
hmm. strange ))