Power User Toolbox: JavaScript for SharePoint – Pt4
Remember in part 3 when I said that frameworks can help you develop faster? Since jQuery in SharePoint is the hot topic right now, I’ll compare an old standby script in poj (Plain Old JavaScript) against a new jQuery version.
Soon after people started using SharePoint 2007, the SharePoint Designer Team blogged about Using Javascript to Manipulate a List Form Field. This opened a lot of doors for me personally and I really started getting interested in using JavaScipt to solve SharePoint challenges.
Scenario: We have a simple newform.aspx generated by our custom list. One of the fields, ItemID, needs to be pre-populated from the URL.

Solution 1 (old shcool):
- Navigate to the newform.aspx page of our custom list.
- Add the following to the URL: “&PageView=Shared&ToolPaneView=2″.
- Add a Content Editor Web Part (CEWP) to the main zone.
- Open the web part’s tool pane and edit the source.
- Paste in the following JavaScript (making sure the three parameters are entered):
<script type="text/javascript"> _spBodyOnLoadFunctionNames.push("fillDefaultValues"); function fillDefaultValues() { var qs = location.search.substring(1, location.search.length); var args = qs.split("&"); var vals = new Object(); for (var i=0; i < args.length; i++) { var nameVal = args[i].split("="); var temp = unescape(nameVal[1]).split('+'); nameVal[1] = temp.join(' '); vals[nameVal[0]] = nameVal[1]; } setTextFromFieldName("ItemID", vals["ItemID"]); //two parameters to copy query string to field switchback("ItemID"); //another parameter to reset the field if changed } function setTextFromFieldName(fieldName, value) { if (value == undefined) return; var theInput = getTagFromIdentifierAndTitle("input","",fieldName); theInput.value=value; } function getTagFromIdentifierAndTitle(tagName, identifier, title) { var len = identifier.length; var tags = document.getElementsByTagName(tagName); for (var i=0; i < tags.length; i++) { var tempString = tags[i].id; if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) { return tags[i]; } } return null; } function switchback(fieldName){ var switchInput = getTagFromIdentifierAndTitle("input","",fieldName); switchInput.onchange = fillDefaultValues; } </script>
Now when we add the query string “ItemID=x”, x is put into our text field and, because of the switchback function, if the user changes it, it will fire fillDefaultValues again. I made that modification to the original scripts to prevent users from haphazardly changing my pre-populated values.
Solution 2 (jQuery):
- Upload the jQuery and jQuery.queryString plugin scripts to our server.
- If you have access to the server file system, add them to 12\TEMPLATE\LAYOUTS so they reference at /_layouts/…
- You can also place the scripts in a document library where “all users” have Restricted Read or higher permissions.
- Navigate to the newform.aspx page of our custom list.
- Add the following to the URL: “&PageView=Shared&ToolPaneView=2″.
- Add a Content Editor Web Part (CEWP) to the main zone.
- Open the web part’s tool pane and edit the source.
- Paste in the following JavaScript:
- Use a reference (src=) that does not include the server name, this will make the script call faster since the call avoids DNS resolution (the process of asking the name server for the IP address of a given server).
- In production, you should use the compressed version of the jQuery scripts for better performance.
<script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript" src="/js/jquery.queryString.js"></script> <script type="text/javascript"> $(function () { fillDefaultValues("ItemID","ItemID"); //two parameters }); function fillDefaultValues(fieldName,value) { var qs = $.getQueryString({id:""+value+""}); var x = $('input[title="'+fieldName+'"]'); x.val(qs); x.change(function () { x.val(qs); }) .change(); } </script>
Now the exact same thing happens as in solution 1. What’s the difference? Well, for starters there’s a lot less code in our CEWP–this seems easier to maintain. Using the YSlow add-on for FireFox, I also noticed that Solution 1 downloaded 218.8k loading in .563s with a Performance Grade of D(67) while Solution 2 downloaded 274.7k in 0.807s, a Performance Grade of F(59).
So that’s a real-life example of the trade-offs a framework offers. Simpler, easier-to-maintain code in exchange for a larger “footprint” and lower performance. For some more tips implementing jQuery in SharePoint, check out Jan Tielens’ blog.
UPDATE (12/1/2008):
Based on the discovery of the JSRequest method in the SharePoint init.js file, we can rewrite Solution 2 without the additional plugin and reduce its footprint.
<script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript"> $(function () { fillDefaultValues("ItemID","ItemID"); //two parameters }); function fillDefaultValues(fieldName,value) { JSRequest.EnsureSetup(); var qs = JSRequest.QueryString[value]; var x = $('input[title="'+fieldName+'"]'); x.val(qs); x.change(function () { x.val(qs); }) .change(); } </script>
The YSlow result for this newer script is D(63); proving a smaller footprint than the original.
- Power User Toolbox: JavaScript for SharePoint - Pt1
- Power User Toolbox: JavaScript for SharePoint - Pt2
- Power User Toolbox: JavaScript for SharePoint - Pt3
- Power User Toolbox: JavaScript for SharePoint - Pt4
- Power User Toolbox: JavaScript for SharePoint - Pt5
- Power User Toolbox: JavaScript for SharePoint - Pt6
- Power User Toolbox: JavaScript for SharePoint - Pt7
- Power User Toolbox: JavaScript for SharePoint - Pt8
- Power User Toolbox: JavaScript for SharePoint - Pt9
Great article Paul!! I was really looking forward to seeing a hands-on practicle article in this series.
Definitely worth the wait!
I’ve been using JavaScripts to meet some of my requirements but frankly it’s usually a long and tedious process if you’re not a developer. Love how much easier it is to implement something using jquery compared to JavaScript.
Can’t wait for the next article..
Cool! Thanks for sharing :)
Hi Paul,
In the second script: where do you tell to wait for the page to load? (the equivalent of _spBodyOnLoadFunctionNames in the first script).
Another question: why is your series not in the list of ongoing series? I sure want to see more of this…
Christophe
Christophe,
jQuery has an event syntax that basically says “when the DOM is ready”: $(document).ready(function ()…
http://docs.jquery.com/Events/ready#fn
Since the document ready event is the default, you can shorten script to: $(function ()… with the same results. As I understand it, this prevents the jQuery from trying to manipulate a DOM that isn’t fully loaded but also works like an onLoad without being in the HEAD element.
As for the second question, I’ll mention it to Mark. I’m glad you’re interested; I’m always impressed with your ideas.
Christophe and Paul – Done… Mark
I updated this article with a new find. The new Solution 2 script uses a pre-existing querystring method from SharePoint’s init.js file.
I used jQuery in a CEWP and someone else used the Rich text editor and all of my script disappeared. Someone told me that this is just how the RTE in the CEWP works. Is this true, how I can I work around this?
TIA
Dean
@Dean,
I’ll make that the topic of the next article I write in this series. I too have had that problem and I’ve developed a few strategies I can share.
That sound great, how long will i have to wait?
@Dean,
I published pt9 just now which should help you: http://www.endusersharepoint.com/?p=1031
I need to pass the itemid to an infopath url (in cewp). Is this possible to do?
What I know about query string parameters and InfoPath I learned here: http://blogs.msdn.com/infopath/archive/2007/02/26/passing-data-into-a-form-input-parameters.aspx
in the steps java script is not available. please send me this java script .
thanks
Tina – They should be visible now. — Mark
Hi Paul / Autosponge,
I’ve found these articles most interesting for my need and am combining a number of Jscript things to solve a user simple multi-filter of a document librarty based on meta data lists.
What I’m stuck on is the use of the view name parameter in the getListItems method. If I put the anything as a value for the view name parameter on my list I get an Internal Server Error returned.
I’ve tried the text name and the GUID. If I leave the parameter blank/null it uses the all items view wothout problem, applying the record count and query as stated. Do you have any ideas ?