Using the JavaScript Object Model in a Content Editor Web Part (Kumar Abhishek Verma)
Much has been written about how to use the new ECMAScript class library to do useful things in SharePoint 2010. A recent search turned up advice about how to use JavaScript in a Web Part, how to use it to customize the ribbon, and how to use it in custom application pages. But not much has been said about programming against the SharePoint 2010 client-side object model in JavaScript that you insert in a Content Editor Web Part.
This blog aims to plug that gap.
Suppose, for example, that your SharePoint website includes a survey list. Now, when you created the list, SharePoint automatically inserted a link under the Surveys heading on the Quick Launch menu. But let’s say that you want maximum participation in this survey. A simple link might not grab enough attention. What you want, let’s suppose, is a way to embed the survey form itself directly on the website’s Home page. You want to put the form where users can see it immediately and respond without going out of their way.
It is a simple requirement and demands a simple solution. This is a job for the Content Editor Web Part (CEWP).
Preparation
To follow along with the example code, you need to add a survey list (SPBaseType.Survey) to your SharePoint 2010 website. Name the list “SampleSurvey” (no space). The survey should have two questions, both with answer type choice. Use the following questions and answers:
1. How is the weather?
Bad
Good
Great
2. How are you doing?
Fine
Good
Great
It will be easier to test your code if you also allow multiple responses from the same user. Navigate to Survey Settings, and then click Title, description and navigation. Next to Survey Options, look for Allow multiple responses.
Adding the Content Editor Web Part to a Page
The first step in this project is to add an instance of the Content Editor Web Part to a page and then link it to a text file where we will place the HTML tags for the survey’s user interface and the JavaScript to submit survey responses.
Tip. It is possible to insert tags and script directly into the Content Editor Web Part. However, a better technique is to first put your tags and scripts in a separate file and upload the file to a document library on the website. After you have done that, open the Web Part Properties pane for the Content Editor Web Part and type the URL to the document in the Content Link box. The content of the linked file becomes the content of the Web Part. This method allows you to do your tagging and scripting with the source editor of your choice, and it has the added benefit that you can reuse the linked code elsewhere on the website. For more information, see Insert JavaScript into a Content Editor Web Part (CEWP).
You can upload a source document to any library on your website. For this example, we will use the Site Assets library.
To add a source document to Site Assets
Use Notepad to create a new text file.
In the text file, paste the following markup:
<div onkeydown='javascript:if (event.keyCode == 13) postSurvey()'> <p>1. How is the weather?<br /> <input name='q1' id='q1Bad' type='radio' value='Bad'/><label for='q1Bad'> Bad</label><br /> <input name='q1' id='q1Good' type='radio' value='Good'/><label for='q1Good'> Good</label><br /> <input name='q1' id='q1Great' type='radio' value='Great'/><label for='q1Great'> Great</label> </p> <p>2. How are you doing?<br /> <input name='q2' id='q2Fine' type='radio' value='Fine'/> <label for='q2Fine'>Fine</label><br /> <input name='q2' id='q2Good' type='radio' value='Good' /><label for='q2Good'> Good</label><br /> <input name='q2' id='q2Great' type='radio' value='Great' /><label for='q2Great'> Great</label> </p> <input type='button' value='Submit' onclick='javascript:postSurvey();' /> </div>
Note: You might wonder why we used an HTML <div> tag instead of a <form> tag here. View the source for any page on a SharePoint 2010 website, and you will see that the markup for the body of the page is enclosed by a single set of <form> tags. You cannot insert a <form> tag inside another <form> tag, so we use <div> tags instead.
Save the text file as Survey_CEWP.txt.
In the Quick Launch area of your website, click Libraries.
Under Document Libraries, click Site Assets.
Click Add document.
Browse to Survey_CEWP.txt. Then click OK to upload the file.
To insert the Content Editor Web Part on a page
On the ribbon, click Page. Then click Edit.
Click on the part of the page where you want to insert the Web Part.
On the ribbon, click Insert. Then click Web Part.
Under Categories, click Media and Content.
Under Web Parts, click Content Editor. Then click Add.
The Web Part is added to the page.
Click Page on the ribbon and then click Save & Close.
To link the source document to the Content Editor Web Part
Move the mouse over the right side of the Web Part title area. When a down arrow appears, click it.
In the Content Editor tool pane, under Content Link, type “/SiteAssets/Survey_CEWP.txt”.
Click OK.
The HTML content displays in the Web Part.
Adding JavaScript to the Web Part
The next step is to add some code to the source file. We begin by adding straightforward JavaScript such as you might use for validating an HTML form. In this case, what we need is code that can tell us which answers the user has selected and more code to ensure that all questions have answers.
We accomplish the first task by writing a utility function, getCheckedValue(). This function accepts an array of input elements and returns the value of the element that is selected. Next we write an event handler for the onclick event of the Submit button. The event is handled by postSurvey(), which calls getCheckedValue() for each question on the survey and verifies that all questions have answers. Later we will add more code to postSurvey().
To add validation code
Navigate to the Site Assets library.
Click Survey_CEWP.
In the Open Document dialog, select Edit. Then click OK.
Below the closing </div> tag, paste the following code:
<script language='javascript' type='text/javascript'> /* Returns the value of the input element that is checked. Accepts either an array or a single input element of type radio or checkbox. Returns an empty string if none are checked or if there are no radio buttons or check boxes. */ function getCheckedValue(buttonGroup) { if (!buttonGroup) return ''; var objLength = buttonGroup.length; if (objLength == undefined) { if (buttonGroup.checked) return buttonGroup.value; else return ''; } for (var i = 0; i < objLength; i++) { if (buttonGroup[i].checked) return buttonGroup[i].value; } return ''; } function postSurvey() { // Retrieve the radio button values var question1 = getCheckedValue(document.getElementsByName('q1')); var question2 = getCheckedValue(document.getElementsByName('q2')); /* Validate the response. Do nothing more until all questions are answered. */ if (question1 == '' || question2 == '') { alert('Please answer all questions.') return; } } </script>
Using the ECMAScript Class Library to Add an Item to a List
In SharePoint 2010, a survey list is actually a list of survey responses. When a user responds to a survey, a new item is added to the survey list. Before we get down to business and actually write the code to do this, it might be helpful to review the process. We will just go over the highlights. For more detailed information, see How to: Create, Update, and Delete List Items in the Microsoft SharePoint 2010 SDK .
As with all client object model code, you begin by getting the current SharePoint context.
var context = new SP.ClientContext.get_current();
Then you get the current website from the context.
var web = context.get_web();
And you get the list from the website's list collection.
var list = web.get_lists().getByTitle('SampleSurvey');
The code so far should look very familiar if you have programmed against SharePoint in managed code. One difference that you have probably noticed is that in JavaScript you do not have get and set property accessors. Instead, you must call get_ and set_ methods. You cannot write web.Title
so you write web.get_title()
.
To create a list item, you create a ListItemCreationInformation object and pass it as an argument to the addItem method of the List class.
var itemCreateInfo = new SP.ListItemCreationInformation(); var listItem = list.addItem(itemCreateInfo);
The call to addItem() returns a ListItem object that you can modify by setting the appropriate field values. Here we come to another difference from how you use the client object model in managed code. In managed code, you set the value of a field with code like this:
listItem[fieldname] = value;
In JavaScript, you call the set_item method, which accepts two arguments: the field name and the field value.
listItem.set_item(fieldName,value);
As with all things SharePoint, whenever you make a change, you must commit the change by calling the update method.
listItem.update();
The final step in any run of client-side code is to execute the code on the server or, more precisely, to post a query to the client service. With JavaScript, queries run asynchronously, so you call the ClientContext object’s executeQueryAsync method, passing as arguments two callback handlers, one for success, the other for failure.
var success = Function.createDelegate(this, this.onSuccess); var failure = Function.createDelegate(this, this.onFailure) context.executeQueryAsync(success, failure);
The Function.createDelegate function is in the Microsoft Ajax library, which is loaded when you load the SharePoint 2010 ECMAScript library. You can load the ECMAScript library by placing the following <script> tag on your page or in your Web Part:
<script src='/_layouts/SP.js' type='text/javascript'></script>
Adding an Item to the SampleSurvey List
The final task is to write JavaScript that uses values from our simple HTML form to create a new item on the SampleSurvey list. We will do this by modifying the code in Survey_CEWP.txt. First we add a script link to reference the ECMAScript library. Then we add to the code in the postSurvey function.
To complete the code for the Content Editor Web Part
In Survey_CEWP.txt, immediately below the closing </div> tag but above the existing <script> tag, add the following markup:
<script src='/_layouts/SP.js' type='text/javascript'></script>
This markup references the primary file for the ECMAScript class library, SP.js.
Inside the postSurvey function, after the last line of code but before the closing curly brace, insert the following additional code:
// Get the current context var context = new SP.ClientContext.get_current(); // Get the current site (SPWeb) var web = context.get_web(); // Get the survey list var list = web.get_lists().getByTitle('SampleSurvey'); // Create a new list item var itemCreateInfo = new SP.ListItemCreationInformation(); var listItem = list.addItem(itemCreateInfo); /* Set fields in the item. In managed code, this would be listItem[fieldname] = value. In Javascript, call listItem.set_item(fieldName,value). */ listItem.set_item('How_x0020_is_x0020_the_x0020_wea', question1); listItem.set_item('How_x0020_are_x0020_you_x0020_do', question2); listItem.update(); // Create callback handlers var success = Function.createDelegate(this, this.onSuccess); var failure = Function.createDelegate(this, this.onFailure); // Execute an async query context.executeQueryAsync(success,failure);
After the postSurvey function, add code for the two callback handlers.
// Async query succeeded. function onSuccess(sender, args) { alert('Thank you for responding to our survey!'); // Refresh the page. SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK); } // Async query failed. function onFailure(sender, args) { alert(args.get_message()); }
Save Survey_CEWP.txt and close the file.
Test the Web Part
The Content Editor Web Part is automatically updated with the changes when you save the source file in the Site Assets library. Now you can give it a spin. Navigate to the Home page and click the Submit button that is now on Content Editor Web Part. You should get a message asking you to answer all the questions. So go ahead and do that, and click the Submit button again. After a delay, you should see a message thanking you for your response. You can navigate to the SampleSurvey list to verify that the response was added to the survey list.
Comments
Anonymous
April 14, 2011
Thank you for your post. Please advise how to prevent users from browsing to the library and deleting items in there. Thanks.Anonymous
April 14, 2011
You could set read permissions for users on the Library. So they can read but not change or delete.Anonymous
June 08, 2011
I want to know that can i embed this code in the NewItem form for survey and have validations when the user press the Finish button? Thanx in advanceAnonymous
June 08, 2011
Well you could embed this js New Form.aspx, infact better would be to call the submit method and have the code in a custom javascript file in style library and refer the file in your new form. As for validations you can write your own Javascript validations on the client as well.Anonymous
June 08, 2011
Can you please also tel me that how to modify this code to store the answers for the rating scale type of questions in the survey list as you have only given the code for choice type of questions.Anonymous
July 29, 2011
One of the things I enjoyed about using server side object model was the ability to use LINQ to query multiple lists. I am trying to do the same thing client side useing JSOM and JSLINQ and while I can get them both to work I can't get tehm to work together. Do you know of a decent way to convert a list object into an array of key value pairs?Anonymous
September 06, 2011
I'm confused concerning the location of the script source:"<script src='/_layouts/SP.js' type='text/javascript'></script>". Your instructions seem contradictory. If the source tag is below the closing </div> tag is can not be above the <script> tag. The last two tags in the file are: </script> </div> I would love to see this example work, but I can not place the source tag the whole thing does not work.Anonymous
September 07, 2011
Nevermind. I got the example to work.Anonymous
December 07, 2011
You can put these codes in a txt file and then upload it to the document library .Then you can use it in the content editor web part . <script type="text/javascript" src="code.jquery.com/.../script> <script type="text/javascript" src="http://win-uaiflcfh1h6/Team%20Site/Shared%20Documents1/jquery.SPServices-0.7.0.js"></script> <script type="text/javascript"> $(document).ready(function(){ var userName = $().SPServices.SPGetCurrentUser({ fieldName: "Name", debug: false }); alert(userName); }); </script> The jquery.SPServices-0.7.0.js file can be downloaded here: spservices.codeplex.com/.../changesetsAnonymous
January 18, 2012
Having the same problem that Mark did and the site is throwing some error regarding SP Script Utility...would anybody have any idea how to fix this issue?Anonymous
April 20, 2012
The "customize the ribbon" link in the first paragraph is broken.Anonymous
April 23, 2012
Does anyone have the entire Survery_CEWP.txt file? I'm getting and error and would like to reference the entire code.Anonymous
April 24, 2012
I could not get this example to work because of this markup: <script src='/_layouts/SP.js' type='text/javascript'></script> I have no idea whyAnonymous
April 24, 2012
Whats is the error your are getting. Please look here for how to include js files Please try to check this sptwentyten.wordpress.com/.../insert-javascript-into-a-content-editor-web-part-cewpAnonymous
November 01, 2012
Since you cannot return values from an asychronous query and can only display an alert to the user, they have no purpose for querying.