There are several confusing things in your code. I suppose it is somewhat testing code, but anyway, I'd like to mention some of the mistakes:
- There is no need for loading anything into the context (with
ctx.load(...)) since you're trying just to update an item. Loading into context is supposed for retrieving information from the server side to the client side, for further usage (displaying, analysing, etc.). And all you're going to do here, apparently, is to update the item in either case, no matter what is it's current state.
- You are not supposed to place any code after the
ctx.executeQueryAsync(OnListLoaded); statement, you should place it into the OnListLoaded function instead. Otherwise, you could get some misleading errors.
- OnError function should be passed as a second parameter to
ctx.executeQueryAsync method, if you want to get any error message from the server side.
There are also some other things, so I would say, that the code is anxiously cluttered and probably this is the first problem with it.
After all these mistakes and inaccuracies, it was not a surprise to hit upon the misusage of the ctx.get_site() property. It doesn't allow any arguments. Actually, it is a property getter, not a method :)
Instead, for getting particular site collection, there is SP.ClientContext constructor.
So, the code should look something like this:
var siteUrl = '/sites/site2';
var listId = '...'; // the list guid here
var listItemId = 1;
var ctx = new SP.ClientContext(siteUrl);
var web = ctx.get_web();
var list = web.get_lists().getById(listId);
var listItem = list.getItemById(listItemId);
listItem.set_item('Title', 'new title');
listItem.update();
ctx.executeQueryAsync(
function() { alert('all ok!'); },
function(sender, args) { alert('ERROR! ' + args.get_message()); });
Unfortunately, this code will not work.
If you will try to run it, you will get the following error:
The security validation for this page is invalid. Click Back in your
Web browser, refresh the page, and try your operation again.
Based on my knowledge, there is no acceptable way to work it around using ECMAScript Client Object Model. You can check out this related question for details.
However, there are some other options:
- You can use SharePoint web service Lists.asmx and its UpdateListItems method.
- You can use server callback and do the work server-side.
Update:
The sample code for updating an item using Lists.asmx (jquery should be included):
// helper function for calling the Lists.asmx web service
function batchUpdate(siteUrl, listId, batch)
{
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>' + listId + '</listName>'+
'<updates>' + batch + '</updates>'+
'</UpdateListItems>'+
'</soap:Body>'+
'</soap:Envelope>';
$.ajax({
url: siteUrl + "/_vti_bin/lists.asmx",
beforeSend: function(xhr) {
xhr.setRequestHeader("SOAPAction",
"http://schemas.microsoft.com/sharepoint/soap/UpdateListItems");
},
type: "POST",
dataType: "xml",
data: soapEnv,
complete: function (xData, status) { alert(status); },
contentType: "text/xml; charset=utf-8"
});
}
var listItemId = 1;
var title = 'new title';
var listId = '{PUT-YOUR-GUID-HERE}';
var siteUrl = 'http://localhost/sites/site2';
var batch =
'<Batch OnError="Continue">'+
'<Method ID="1" Cmd="Update">'+
'<Field Name="ID">' + listItemId + '</Field>'+
'<Field Name="Title">' + title + '</Field>'+
'</Method>'+
'</Batch>';
batchUpdate(siteUrl, listId, batch);
I've tested this code and it works.