1,804 articles and 15,142 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
Saturday, May 16, 2009

JQuery for Everyone: Email a List of People with OWS

Eric posted a good question on our forum:

What I’d like to be able to do, is create a hyperlink or button on the page that iterates through the list of users and when clicked, opens a mailto: href that is populated with all the users.

Any ideas on how this could be accomplished with jQuery?

I had done something like this before, but when I got the time I decided to look into doing this without a Data View Web Part.

First, I needed to upgrade my OWS API with some new functions. I originally used .getValues() to get the values from a field and only parsed out the ;# for calculated columns. Now, I also need to parse that out for lookups.

While making the changes, I noticed I was using the same code for getting the schema node in a few places, so I now have the .getSchema() method.

To tell if something is a lookup, I use the new .isLookup() method. As a utility, I keep finding more things this can do, so I added .getUnique(), .getId(), and .getUniqueId() which can get the unique members of a list or the unique Id values in the case of lookups.

So, how do we put this together to make our List View Web Part give up the goods? In my example below, I used the .getUnique() method to make sure I’m only sending one email to each person (although I think Outlook filters this anyway).

  1. Change the person field in the list to display email instead of the default, Name (with presence).
  2. Put jQuery on the page (I’m using 1.3.1).
  3. Put the new OWS script on the page (see below or follow the “Read more…” link).
  4. Add something like the following to the page:
$(function(){
	$("td.ms-toolbar[width='99%']").append("<a id="emailall" title="email all Assigned To" href="#"><img src="/_layouts/images/gmailnew.gif" border="0" alt="email all" /></a>");
	$.fn.ows({"view":"","command":"&amp;Query=*"},function(){
		var addy = ows.getUnique('ctx1','Assigned To');
		$("#emailall").click(function(){window.location='mailto:'+addy.join(';');});
	});
});
add a button

Here’s the breakdown of what’s happening:

  1. On document.ready, find the space in the toolbar (obviously this won’t work without the toolbar visible).
  2. Append a .gif (from WSS /images) with a link we can bind an event to.
  3. Fire $.ows() to get our List View’s context data, we override view with an empty parameter (to pull back all of the data) and we append the ‘Query=*’ command to pull back the entire schema (otherwise, we’re locked into the default view).
  4. In the ows callback function, we fetch the unique values for Assigned To and pass that to an onClick event for the “email all” button.

After the page loads, even if the list of people remains hidden under groups, we can kick off an email to all of our people with a single click.

send an email
(function(){
	Array.max = function(array){
		return Math.max.apply( Math, array );
	};
	Array.min = function(array){
		return Math.min.apply( Math, array );
	};
	var defaults = {
		ctx: "ctx1",
		baseUrl: "",
		list: "",
		view: "",
		command: ""
	},
	isNumber = function(val){
		return (/^-?((\d+\.?\d*)|(\.\d+))$/).test(val);
	},
	ows_url = function(o){
		o.baseUrl = (!o.baseUrl)?L_Menu_BaseUrl:o.baseUrl;
		o.list = (!o.list)?window[o.ctx].listName:o.list;
		o.view = (!o.view)?window[o.ctx].view:o.view;
		return o.baseUrl+"/_vti_bin/owssvr.dll?XMLDATA=1&amp;List="+
				o.list+"&amp;View="+o.view+o.command;
	},
	create_ows = function(){
		ows = {
			getSchema : function(ctx,rsname){
				var n = $.grep($(ows[ctx].schema),function(e,i){
					return ($(e).attr("rs:name")==rsname);
				});
				return n;
			},
			getName : function(ctx,rsname){
				var n = ows.getSchema(ctx,rsname);
				return $(n).attr("name");
			},
			getType : function(ctx,rsname){
				var n = ows.getSchema(ctx,rsname);
				return $(n).find("[nodeName='s:datatype']").attr("dt:type");
			},
			getNumber : function(ctx,rsname){
				var r = $.grep($(ows[ctx].schema),function(e,i){
					return ($(e).attr("rs:name")==rsname);
				});
				return $(r).attr("rs:number");
			},
			getPosition : function(ctx,rsname){
				var pos = ows.getNumber(ctx,rsname);
				return parseInt(pos)-1;
			},
			isLookup : function(ctx,rsname){
				var n = ows.getSchema(ctx,rsname),
					l = $(n).find("[nodeName='s:datatype']").attr("dt:lookup");
				return l?l:false;
			},
			getValues : function(ctx,rsname){
				var v = [],
					vname = ows.getName(ctx,rsname);
				$(ows[ctx].data).each(function(i,e){
					var vx = $(e).attr(vname);
					if(vx){
						if(ows.getType(ctx,rsname)=='variant'||ows.isLookup(ctx,rsname)){
							v.push(vx.split(';#')[1]);
						}else{
							v.push(vx);
						}
					}
				});
				return v;
			},
			getId : function(ctx,rsname){
				if(ows.isLookup(ctx,rsname)){
					var v = [],
						vname = ows.getName(ctx,rsname);
					$(ows[ctx].data).each(function(i,e){
						var vx = $(e).attr(vname);
						if(vx){
							v.push(vx.split(';#')[0]);
						}
					});
					return v;
				}else{
					return false;
				}
			},
			getUnique : function(ctx,rsname){
				var b = ows.getValues(ctx,rsname),
					a = [], l = b.length;
				$(b).each(function(i,e){
					if(a.indexOf(e,0,b)&lt;0){a.push(e);}
				});
				return a;
			},
			getUniqueId : function(ctx,rsname){
				var b = ows.getId(ctx,rsname),
					a = [], l = b.length;
				$(b).each(function(i,e){
					if(a.indexOf(e,0,b)&lt;0){a.push(e);}
				});
				return a;
			},
			getAll : function(ctx,rsname){
				var a = [],
					aname = ows.getName(ctx,rsname);
				$(ows[ctx].data).each(function(i,e){
					a.push($(e).attr(aname));
				});
				return a;
			},
			getSum : function(ctx,rsname){
				var svals = ows.getValues(ctx,rsname),
					sum=0;
				$(svals).each(function(i,e){
					if(e &amp;&amp; isNumber(e)){
						sum += parseFloat(e);
					}
				});
				return sum;
			},
			getAvg : function(ctx,rsname){
				var avgsum = ows.getSum(ctx,rsname),
					avgcount = ows.getValues(ctx,rsname).length;
				return avgsum/avgcount;
			},
			getMax : function(ctx,rsname){
				var xvals = ows.getValues(ctx,rsname);
				xvals = $.grep(xvals,function(e,i){
					return (e &amp;&amp; isNumber(e));
				});
				return Array.max(xvals);
			},
			getMin : function(ctx,rsname){
				var nvals = ows.getValues(ctx,rsname);
				nvals = $.grep(nvals,function(e,i){
					return (e &amp;&amp; isNumber(e));
				});
				return Array.min(nvals);
			},
			getTable : function(ctx){
				var t = $("[id='"+window[ctx].listName+"-"+window[ctx].view+"']");
				return t;
			}
		};
	};
	jQuery.fn.ows = function(options,callback){
		var o = $.extend({},defaults,options);
		if(typeof ows=='undefined'){create_ows();}
		$.get(ows_url(o),function(data){
			ows[o.ctx] = {
				schema:$(data).find("[nodeName='s:AttributeType']"),
				data:$(data).find("[nodeName='z:row']")
			};
			return callback(o);
		});
	};
})();

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

6 Responses to “JQuery for Everyone: Email a List of People with OWS”
  1. Lee Reed says:

    Great post, Paul. I would like to be able to use it but I’m not certain what I need to do to enable this feature on my site.

    Can you provide some instruction on how to make this live on my SharePoint site?

    Thanks!

  2. Frank says:

    This is great and I can use this for our SharePoint. We are using WSS 3.0 as our Intranet. We can use this for our intera-department slides and documents. I would like the instructions or screen shots.
    Thanks

  3. AutoSponge says:

    This is the third post about using OWSSVR.DLL. As I get more ideas, it may continue to evolve, so keep looking here. If there is enough support/request for it, I’ll work up some real documentation and it’s own dedicated page, versioning, etc.

    Right now, it’s just me, not many people seem to care (you’re an exception //grin//), and documenting takes time away from coding :)

    Check the previous articles and let me know if you have specific questions either here or on STP.

  4. AutoSponge says:

    @Lee,

    I’ll see if I can work up another solution and this time put some clear steps into the article.

  5. John says:

    Great; another example that doesn’t work. This code will not even display the gmailnew.gif in the tool bar. Please double check what you have posted to ensure it actually works. Whne I have attempted to use this, nothign changes. I am using a default Tasks list, with Assigned To modified to display email address, but the code does not work.

  6. AutoSponge says:

    @John,

    Sorry you’re getting frustrated. Which version of jQuery are you using? Which page did you add this to? For #4, did you use exactly that example? And did you add it after the owsapi code (outside of the owsapi closure)?

    I honestly did test this, hence the screenshots. I’m using WSS on a Tasks list’s default allitems view page, jQuery 1.3.1. Perhaps I can provide some more detailed instructions if I know where things went wrong.

    Thanks for trying it out.
    Paul


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!