1,804 articles and 15,137 comments as of Sunday, May 15th, 2011

EndUserSharePoint has combined resources with NothingButSharePoint.com. You can now find End User (Mark Miller), Developer (Jeremy Thake) and IT Pro SharePoint content all in one place!

This site is a historical archive and is no longer being updated. Please update your favorites, bookmarks and RSS feeds.

NothingButSharePoint.com
Thursday, April 2, 2009

JQuery for Everyone: Create a Client-Side Object Model

But Paul! SharePoint has a client-side object model. Well, yes and no.

Yes. SharePoint has the WPSC to fetch properties about a page’s web parts. However, SharePoint’s JavaScript uses an ActiveX object to call the SharePoint web services–a completely unnecessary strategy that locks you into using IE. No, no, and no.

When I looked at rewriting the WPSC for use in all browsers, I noticed that a lot of the data I wanted was already on the page, just not in a format I could use in my code. So, for starters, I’m not going to call the web service at all.

The CTX object

Every time an out-of-the-box web part with a SP data source loads, it creates another instance of the CTX (context) object. Each one gets a number (ctx1, ctx2, …). These objects hold some good info about the web parts on the page but it’s missing simple stuff like web part title!

Open Firebug and type ctx into the console. You’ll see the last ctx object created and some of the properties it holds.

A better Object

The web parts on your page all get IDs like “WebPartWPQ8″. These are apparently given out at runtime and are therefore subject to change based on the order in which the web parts are loaded and which ones are open (as opposed to closed, not deleted). So they’re useless without a way to map them back to your web part.

I want to provide context for my jQuery selectors to specific web parts and I want to do that by web part title, something with meaning. So I wrote the code below in a jQuery plug-in style to build an object with meaningful names like Tasks, Announcements, and Calendar instead of ctx1, ctx2, and ctx3.

if (typeof wp=='undefined'){ //check for the wp object
	$("div[webpartid]").wpCollect();  //build the wp object
}
if (typeof wp.Pics=='object'){  //check for the specific web part by name
	$("#"+wp.Pics.id).hide(); //hide the Pics web part by ID
}

Since I can also collect the ctx object for a given web part, I put that inside my wp object so I can get at all of the available data by web part title (or guid if the title was hidden by turning Chrome off in the web part settings).

You can get the data from your objects like this: wp.Tasks or by using the bracket notation when names have spaces: wp["Shared Documents"].

<script type="text/javascript">
if(typeof jQuery=="undefined"){
	var jQPath="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/";
	document.write("<script src='",jQPath,"jquery.min.js' type='text/javascript'><\/script>");
}
</script>
<script type="text/javascript">
(function(){
	jQuery.fn.wpCollect = function(){
		wp = {};
		this.each(function(i,e){
			var guid = e.getAttribute("webpartid").toUpperCase();
			var id = e.id;
			var ctx = g_ViewIdToViewCounterMap["{"+guid+"}"];
				ctx = (!ctx)?{}:eval("ctx"+ctx);
			var title = id.replace(/WebPartWPQ/,"#WebPartCaptionWPQ");
				title = $(title);
				title = (title.length==0)?guid:title.prev().text();
			wp[title] = {guid:guid,id:id,ctx:ctx};
		});
		return this;
	};
})();
$(function(){
	if (typeof wp=='undefined'){ //check for the wp object
		$("div[webpartid]").wpCollect();  //build the wp object
	}
});
</script>

Paul Grenier

View all entries in this series: PaulGrenier-JQuery for Everyone»
Entries in this series:
  1. JQuery for Everyone: Accordion Left Nav
  2. JQuery for Everyone: Print (Any) Web Part
  3. JQuery for Everyone: HTML Calculated Column
  4. JQuery for Everyone: Dressing-up Links Pt1
  5. JQuery for Everyone: Dressing-up Links Pt2
  6. JQuery for Everyone: Dressing-up Links Pt3
  7. JQuery for Everyone: Cleaning Windows Pt1
  8. JQuery for Everyone: Cleaning Windows Pt2
  9. JQuery for Everyone: Fixing the Gantt View
  10. JQuery for Everyone: Dynamically Sizing Excel Web Parts
  11. JQuery for Everyone: Manually Resizing Web Parts
  12. JQuery for Everyone: Total Calculated Columns
  13. JQuery for Everyone: Total of Time Differences
  14. JQuery for Everyone: Fixing Configured Web Part Height
  15. JQuery for Everyone: Expand/Collapse All Groups
  16. JQuery for Everyone: Preview Pane for Multiple Lists
  17. JQuery for Everyone: Preview Pane for Calendar View
  18. JQuery for Everyone: Degrading Dynamic Script Loader
  19. JQuery for Everyone: Force Checkout
  20. JQuery for Everyone: Replacing [Today]
  21. JQuery for Everyone: Whether They Want It Or Not
  22. JQuery for Everyone: Linking the Attachment Icon
  23. JQuery for Everyone: Aspect-Oriented Programming with jQuery
  24. JQuery for Everyone: AOP in Action - loadTip Gone Wild
  25. JQuery for Everyone: Wiki Outbound Links
  26. JQuery for Everyone: Collapse Text in List View
  27. JQuery for Everyone: AOP in Action - Clone List Header
  28. JQuery for Everyone: $.grep and calcHTML Revisited
  29. JQuery for Everyone: Evolution of the Preview
  30. JQuery for Everyone: Create a Client-Side Object Model
  31. JQuery for Everyone: Print (Any) Web Part(s) Plugin
  32. JQuery for Everyone: Minimal AOP and Elegant Modularity
  33. JQuery for Everyone: Cookies and Plugins
  34. JQuery for Everyone: Live Events vs. AOP
  35. JQuery for Everyone: Live Preview Pane
  36. JQuery for Everyone: Pre-populate Form Fields
  37. JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)
  38. Use Firebug in IE
  39. JQuery for Everyone: Extending OWS API for Calculated Columns
  40. JQuery for Everyone: Accordion Left-nav with Cookies Speed Test
  41. JQuery for Everyone: Email a List of People with OWS
  42. JQuery for Everyone: Faster than Document.Ready
  43. jQuery for Everyone: Collapse or Prepopulate Form Fields
  44. jQuery for Everyone: Hourly Summary Web Part
  45. jQuery for Everyone: "Read More..." On a Blog Site
  46. jQuery for Everyone: Slick Speed Test
  47. jQuery for Everyone: The SharePoint Game Changer
  48. JQuery For Everyone: Live LoadTip
 

Please Join the Discussion

5 Responses to “JQuery for Everyone: Create a Client-Side Object Model”
  1. Willhlaw says:

    Paul,

    Excellent idea and excellent work. Are you familiar yet with the jPoint project? I have posted on my blog the my presentation at SharePoint Saturday DC. The slide deck has a slide attributing your work on your blogs as part of the inspiration and knowledge that helped us create jPoint.

    The jPoint project is at its core, an API for manipulating form pages and lists. In the future, we will expand the core to include APIs for other useful operations on the client side in SharePoint such as manipulating list views and webparts. When we get there, will you be kind enough to help us integrate your code into the Webparts subclass? The jPoint project is hosted on codeplex at http://jPoint.codeplex.com.

    Thanks!
    Will

  2. AutoSponge says:

    Will,

    Thanks for the kudos. I’ll reply in email about contributing to jPoint.

    Paul

  3. Mikael says:

    Hi Paul – I’m trying to get your solution to work on a MOSS 2007 intranet with jQuery 1.4.2. I get the web part titles and the web part GUID’s, but the ctx object is empty. Also when I type “ctx” in Firebug as you suggest in the article I just get a reference error: “ctx is not defined”.

    Do you have any idea why this is happening? Do I need to include any other JS files to get access to the standard ctx object?

    Thanks, Mikael

Trackbacks

Check out what others are saying about this post...
  1. [...] you mash this up with my other plugin, SharePoint Client-Side Object Model, you can find web parts no matter where they are on the page or which order they load in: [...]

  2. [...] When creating the ows object, the default settings will get the list and view GUIDs from the ctx object on the page. If there is more than one web part, the default settings use the ctx object for the first web part added to the page (not the first appearing in the DOM). To get the correct ctxId for a web part by name, see my other article. [...]




Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!