Thursday, June 25, 2009

Redirect to list item page knowing only item id, list id and web id

Is never to late to learn something new and useful.

My situation was that I had to open a list item page knowing only the ids of the item, the item container (list in my case) and web. Searching on the net I did not found what I needed. This was until a colleague told me about CopyUtil page from SharePoint and indeed I found a very interesting article from Jan Tielen.

http://weblogs.asp.net/jan/archive/2008/02/26/copyutil-aspx-a-little-sharepoint-gem.aspx

Enjoy !

Wednesday, June 17, 2009

Delete list items with Web Services and JQuery

We can delete multiple list items calling UpdateListItems web method from Lists.asmx web service provided by SharePoint. This method can be called using JQuery ajax method.

In my example I want to delete more items from a list knowing the items id’s. In user interface I have a collection of checkboxes with “id” attribute as id of the list item. Using a selector we obtain the collection of checkboxes, and build using the id attribute of checked one’s the batch that we will send to web method. “Tests” is the list name where I want to delete. For each item we have to add a Method with a distinct id.

function DeleteSelected() {
var chkcoll = $("myselector");
var fields = "";
chkcoll.each(function(i){
if($(this).attr('checked') == true)
{
fields += "<Method ID=\""+$(this).attr('id')+"\" Cmd=\"Delete\"><Field Name=\"ID\">" + $(this).attr('id') + "</Field></Method>";
}
});

var batch = "<Batch OnError=\"Continue\">" + fields + "</Batch>";
var soapEnv = BuildSoapEnv(batch, 'Tests');
theAjaxCallForUpdate(soapEnv, onSuccessDelete);
}




function BuildSoapEnv(batch, listname)
{
var soapEnv =
"<?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> \
<UpdateListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\"> \
<listName>"
+ listname + "</listName> \
<updates> \
"
+ batch + "</updates> \
</UpdateListItems> \
</soap:Body> \
</soap:Envelope>"
;
return soapEnv;
}



To avoid the “The security validation” error thrown by the web service, the SOAPAction header must be provided using beforeSend option.



The functionToCall is another function that you can call when the web method call is completed for some action that have to take place after. Also “success” option can be used and perform actions only if the calling of the web method was successfully.




function theAjaxCallForUpdate(soapEnv, functionToCall)
{
$.ajax({
url: textWebUrl + "/_vti_bin/Lists.asmx",
beforeSend: function(xhr) {
xhr.setRequestHeader("SOAPAction","http://schemas.microsoft.com/sharepoint/soap/UpdateListItems");},
type: "POST",
dataType: "xml",
data: soapEnv,
complete: functionToCall,
contentType: "text/xml; charset=\"utf-8\""
});
}




function onSuccessDelete()
{
// do something
}



The textWebUrl is a variable that contain the web url. We set this from our .cs code. The scripts are stored in a separate folder in _layouts. The entire Jquery script for calling the web service is in MyScript.js file. This file must be copied into _layouts/JQuery folder together with the last version of JQuery.




StringBuilder sbJQ = new StringBuilder();
sbJQ.Append("<script type=\"text/javascript\" src=\"_layouts/JQuery/jquery-1.3.2.min.js\"></script>");
sbJQ.Append("<script type=\"text/javascript\">").Append("var textWebUrl='"+this.Web.Url+"';").Append("</script>");
sbJQ.Append("<script type=\"text/javascript\" src=\"_layouts/JQuery/MyScript.js\" ></script>");

if (!Page.ClientScript.IsClientScriptBlockRegistered("scriptkey"))
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "scriptkey", sbJQ.ToString());
}