RE: Problem using owssvr.dll to save list item
From: Hobietje (Hobietje_at_discussions.microsoft.com)
Date: 11/03/04
- Next message: Hobietje: "RE: RPC Call 2 Sharepoint"
- Previous message: Andy Whatley: "Re: New Users"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 3 Nov 2004 14:37:02 -0800
Whooo whoo! I figured it out!
Below is the code on how to save a list item from javascript. In my case, I
have a normal sharepoint form page and turned the toolbar off, so I could
create my own 'Save and close' and 'Go back to list' buttons. On my 'Save and
Close' button I call the ClickSaveItem() function. I copied some of the
scripts that Sharepoint uses to validate, etc, but I removed the
form.submit() and replaced it with my own code to send a HTTP post, allowing
me to get the ID of the new item that was created and redirect to the Display
page for this list item.
The ClickSaveItem() is basically the sharepoint ClickOnce() function but it
calls my ValidateAndSave() function instead of the sharepoint
frm.ValidateAndSubmit().
The ValidateAndSave() function (which resembles the sharepoint
frm.ValidateAndSubmit() function) then calls the sharepoint frm.FValidate and
frm.FPostProcess to validate the form and postprocess a few field types (such
as the checkbox). Finally, instead of submitting the form, it sends a HTTP
post request to the server with the CAML to create a new list item.
A few little notes on all of this:
- The __REQUESTDIGEST performs the security validation. The HTTP post will
not work if this is not included in the actual url and using a <SetVar>
element in each <Method> element of your CAML.
- The Batch element is commented out below because it is not required if you
only have 1 Method to execute. If you need to save multiple items, uncomment
the batch and create a <Method> element for each method you want to execute
- Make sure the ContentType and X-Vermeer-Content-Type are both set to
"application/x-www-form-urlencoded"
- The actual CAML has to be encoded. The sharepoint escapeProperly()
function seems to perform this job. Before I encoded the CAML with this
function, only the first of my fields got saved (regardless of which field it
was).
- escapeProperty(), STSHtmlEncode(), STSNavigate() and any other functions
not detailed below are sharepoint functions in the OWS.JS file (located in
C:\Program Files\Common Files\Microsoft Shared\web server
extensions\60\TEMPLATE\LAYOUTS\1033 on your server).
- I put this javascript in a seperate Job.js file and included it on my page
using <script src="/Job.js"></script>. If you want to included the actual
script in the actual .aspx page, you will have to encode all caml tags (eg.
<setvar> should be <setvar>
------------------------------------------
//Ideally, I want to replace these with CAML to make it more dynamic
var URL_Base = 'http://myserver';
var URL_ViewJob = '/ViewJob.aspx';
var myForm = document.forms(0);
//Sharepoint var: Looks like its used to catch double clicks so we can
confim that the user really wants to launch a second save request
var g_MSclicked=false;
function ClickSaveItem()
{
myForm.Cmd.value='Save';
if(!g_MSclicked)
{
if(ValidateAndSave(true))
g_MSclicked = true;
}
else
{
if(confirm(L_ClickOnce1_text ))
ValidateAndSave(true);
}
}
function ValidateAndSave(fUI)
{
//This is basically the sharepoint ValidateAndSubmit function without the
submit :-)
if (frm.fPreviewMode)
{
var L_cantSave_Text = "This form cannot be saved when previewing this page.";
window.alert(L_cantSave_Text);
return;
}
if (!frm.FValidate(fUI)){
return;
}
//This is a sharepoint postprocess, which changes checkbox values to 0 or 1
and who knows what else
frm.FPostProcess();
//Send the caml request (ie Save this Item)
var url =
'http://myserver/_vti_bin/owssvr.dll?Cmd=DisplayPost&__REQUESTDIGEST=';
url += myForm.elements['__REQUESTDIGEST'].value;
url += '&PostBody=';
var caml = '<?xml version="1.0" encoding="UTF-8"?>';
// caml += '<ows:Batch Version="6.0.2.5608" OnError="Continue">\n';
caml += GetCamlToSave();
// caml += '</ows:Batch>\n';
caml = escapeProperly(caml);
var objHTTP = new ActiveXObject("Microsoft.XMLHTTP");
objHTTP.open("POST" , url + caml, false);
objHTTP.setRequestHeader("Content-Type" ,
"application/x-www-form-urlencoded");
objHTTP.setRequestHeader("X-Vermeer-Content-Type",
"application/x-www-form-urlencoded");
objHTTP.send();
//Process the caml response (ie Get new Item id and redirect)
var objDoc = new ActiveXObject("Msxml2.DOMDocument");
objDoc=objHTTP.responseXML;
objDoc.setProperty("SelectionLanguage","XPath");
if(objDoc.documentElement)
{
var eNode = objDoc.documentElement.getElementsByTagName("ID");
if(eNode.length > 0)
{
var myID = eNode[0].text;
STSNavigate(URL_Base + URL_ViewJob + '?ID=' + myID);
}
else
{
var eNode = objDoc.documentElement.getElementsByTagName("ErrorText");
var text='';
if(eNode.length > 0)
text += eNode[0].text;
alert('A problem was encountered while trying to save this item. Please try
again later.\n\n' + text);
}
}
else
alert('A problem was encountered while trying to save this item. Please try
again later.');
}
function GetCamlToSave()
{
//Build the caml request to send to sharepoint to save this item
var caml='';
caml += '<Method ID="0,SaveItem">\n';
caml += '<SetList Scope="Request">' + myForm.List.value + '</SetList>\n';
caml += GetCamlToSaveField('Cmd') + '\n';
caml += GetCamlToSaveField('ID') + '\n';
caml += GetCamlToSaveField('__REQUESTDIGEST') + '\n';
for(var i=0; i< myForm.elements.length; i++)
{
if(frm.stFieldPrefix.length < myForm [ i].name.length && myForm [
i].name.substring(0,frm.stFieldPrefix.length) == frm.stFieldPrefix)
{
caml += GetCamlToSaveField(myForm [ i].name) + '\n';
}
}
caml += '</Method>\n';
return caml;
}
function GetCamlToSaveField(field)
{
var caml='';
caml+='<SetVar Name="' + field + '">';
caml+=STSHtmlEncode(myForm.elements [ field].value);
caml+='</SetVar>';
return caml;
}
- Next message: Hobietje: "RE: RPC Call 2 Sharepoint"
- Previous message: Andy Whatley: "Re: New Users"
- Messages sorted by: [ date ] [ thread ]