little extension for SPDisplayRelatedInfo

Feb 4, 2010 at 11:02 AM
Edited Feb 4, 2010 at 3:17 PM

Hi.

I was a bit confused by not being able to use SPDisplayRelatedInfo on DispForm pages. So I wrote this function as a little modification.
It takes field's internal name (instead of Displayname, like original function does).

It shows

I removed all the dynamics functionality related to selector's changes monitoring and called it SPDisplayStaticRelatedInfo. Also added options to overwrite old container content and/or place info to specified container instead of default one (found in table).

Here is it.

	$.fn.SPServices.SPDisplayStaticRelatedInfo = function(options) {
		var opt = $.extend({}, {
			columnName: "",						// The display name of the column in the form
			relatedWebURL: "",					// [Optional] The name of the Web (site) which contains the related list
			relatedList: "",					// The name of the list which contains the additional information
			relatedListColumn: "",				// The internal name of the related column in the related list
			relatedColumns: [],					// An array of related columns to display
			displayFormat: "table",				// The format to use in displaying the related information.  Possible values are: "table".
			replaceContent: false,			// Replace original content in container control or append to it if 'false'. 
			containerID: null,		// Place info table into existing container, instead of creating new one
			headerCSSClass: "ms-vh2",			// CSS class for the table headers
			rowCSSClass: "ms-vb2",				// CSS class for the table rows
			CAMLQuery: "",						// [Optional] For power users, this CAML fragment will be <And>ed with the default query on the relatedList
			numChars: 0,						// If used on an input column (not a dropdown), no matching will occur until at least this number of characters has been entered
			matchType: "Eq",					// If used on an input column (not a dropdown), type of match. Can be any valid CAML comparison operator, most often "Eq" or "BeginsWith"
			completefunc: null,					// Function to call on completion of rendering the change.
			debug: false						// If true, show error messages; if false, run silent
		}, options);
		
		// this will be column on the right of our label
		var container = $("a[name='SPBookmark" + opt.columnName + "']").parent().parent().next();
		var values = $(container).text().split('; ');
	// Only get the requested columns
		var relatedColumnsXML = [];

		// Get information about the related list and its columns
		$().SPServices({
			operation: "GetList",
			async: false,
			webURL: opt.relatedWebURL,
			listName: opt.relatedList,
			completefunc: function(xData, Status) {
				// If debug is on, notify about an error
				$(xData.responseXML).find("faultcode").each(function() {
					if(opt.debug) errBox("SPServices.SPDisplayRelatedInfo",
						"relatedList: " + opt.relatedList,
						"List not found");
					return;
				});
				// Output each row
				$(xData.responseXML).find("Fields").each(function() {
					$(xData.responseXML).find("Field").each(function() {
						for (i=0; i < opt.relatedColumns.length; i++) {
							// If this is one of the columns we want to display, save the XML node
							if($(this).attr("Name") == opt.relatedColumns[i]) relatedColumnsXML[i] = $(this);
						}
					});
				});
			}
		});
		
		// if containerID specified - switching container to the object with ID supplied
		if (opt.containerID)
			container = $("#" + opt.containerID);
			
		var divId = "showRelated_" + encodeColumn(opt.columnName);
		
		// If replaceContent specified - removing all container content
		if (opt.replaceContent)
			container.html("");
			
		container.append("<div id=" + divId + "></div>");
		//$("#" + divId).remove(); // we do not need it anymore
		// and here we changed the whay the container for table is defined

		// Get the list items which match the current selection
		var camlQuery = "<Query><Where>";
		if(opt.CAMLQuery.length > 0) camlQuery += "<And>";

		// Here is the fix for multimple selected values
		if(values.length > 1) camlQuery += "<Or>";
		for (i = 0; i <values.length; i++)
			camlQuery += "<" + opt.matchType + "><FieldRef Name='" + opt.relatedListColumn + "'/><Value Type='Text'>" + escapeColumnValue($.trim(values[i])) + "</Value></" + opt.matchType + ">";
		if(values.length > 1) camlQuery += "</Or>";
		
		if(opt.CAMLQuery.length > 0) camlQuery += opt.CAMLQuery + "</And>";
		camlQuery += "</Where></Query>";

		var viewFields = " ";
		for (i=0; i < opt.relatedColumns.length; i++) {
			viewFields += "<FieldRef Name='" + opt.relatedColumns[i] + "' />";
		}
		$().SPServices({
			operation: "GetListItems",
			async: false,
			webURL: opt.relatedWebURL,
			listName: opt.relatedList,
			// Filter based on the column's currently selected value
			CAMLQuery: camlQuery,
			CAMLViewFields: "<ViewFields>" + viewFields +  "</ViewFields>",
			// Override the default view rowlimit and get all appropriate rows
			CAMLRowLimit: 0,
			completefunc: function(xData, Status) {
				$(xData.responseXML).find("faultcode").each(function() {
					if(opt.debug) errBox("SPServices.SPDisplayRelatedInfo",
						"relatedListColumn: " + opt.relatedListColumn,
						"Column not found in relatedList " + opt.relatedList);
					return;
				});
				// Output each row
				switch(opt.displayFormat) {
					// Only implementing the table format in the first iteration (v0.2.9)
					case "table":
						var outString = '<table border="0" cellspacing="0" width="100%" >';
						outString += "<tr>";
						for (i=0; i < opt.relatedColumns.length; i++) {
							if(relatedColumnsXML[i] == undefined && opt.debug) {
								errBox("SPServices.SPDisplayRelatedInfo",
									"columnName: " + opt.relatedColumns[i],
									"Column not found in relatedList");
								return;
							}
							outString += "<th class='" + opt.headerCSSClass + "'>" + relatedColumnsXML[i].attr("DisplayName") + "</th>";
						}
						outString += "</tr>";
						// Add an option for each child item
						$(xData.responseXML).find("[nodeName=z:row]").each(function(index) {
							// added alternating row stile
							outString += "<tr" + (((index % 2) !=0) ? ' class="ms-alternating"' : '') + ">";
							for (i=0; i < opt.relatedColumns.length; i++) {
								outString += "<td class='" + opt.rowCSSClass + "'>" + showColumn(relatedColumnsXML[i], $(this).attr("ows_" + opt.relatedColumns[i]), opt) + "</td>";
							}
							outString += "</tr>";
						});
						outString += "</table>";
						$("#" + divId).append(outString);
						break;
					// list format implemented in v0.5.0. Still table-based, but vertical orientation.
					case "list":
						var outString = "<table>";
						for (i=0; i < opt.relatedColumns.length; i++) {
							$(xData.responseXML).find("[nodeName=z:row]").each(function(index) {
								// added alternating row stile
								outString += "<tr" + (((index % 2) !=0) ? ' class="ms-alternating"' : '') + ">";
								outString += "<th class='" + opt.headerCSSClass + "'>" + relatedColumnsXML[i].attr("DisplayName") + "</th>";
								outString += "<td class='" + opt.rowCSSClass + "'>" + showColumn(relatedColumnsXML[i], $(this).attr("ows_" + opt.relatedColumns[i]), opt) + "</td>";
								outString += "</tr>";
							});
						}
						outString += "</table>";
						$("#" + divId).append(outString);
						break;
					default:
						break;
				}
			}
		});
	};

Feb 4, 2010 at 11:04 AM

I also added alternating item TR-classes and support for multiple selection values.

Coordinator
Feb 4, 2010 at 3:41 PM

Thanks, Mara.  The reason I haven't made the SPDisplayRelatedInfo function work with DispForm.aspx is that a much better solution is to just use a DVWP.  With DVWPs, you can have AggregateDataSources and display items "joined" from many lists is you want to.

There's nothing that is going to change on the client side, so client-side scripting doesn't really make sense.

M.

Feb 4, 2010 at 4:44 PM

For me is much more problematic to find the trough all that UI-crap with all that crazy logics, than just add some js-strings and get all the functionality I need and place it there, where I need it =)

Also I've lost about three hours trying to add such view to page using SP built-in controls and that resulted in some mind-blowing mix of webparts/filters/xsl-templates.. And this script took only 15 minutes to modify, test/debug and deploy.

Anyway - thanks for library itself. It saves my nerves =)

Coordinator
Feb 4, 2010 at 4:59 PM
Edited Feb 4, 2010 at 5:00 PM

Glad your nerves have been saved.  ;+)  As with all things SharePoint, there are always multiple ways to solve things, and sometimes the best solution is the one you can get to work!

Thanks for posting your code, as I'm sure it will help others.  I'll try it out and maybe add it into the library if it makes sense.

M.

Jun 17, 2010 at 9:03 PM

Hi Justmara,/Marc

I was looking for same functionality I copied above code and pasted to jquery.SPServices-0.5.5Use SHIFT+ENTER to open the menu (new window).. Further in CEWP added script tag for same. I couldnt get it working. I am dealing with three list.

- Master lists

   1) Country - Contains Country coulmn only

  2) City -  contains City, Country and Speciality

- Transasction list

 Trip - Contains Trip Name, Country ( Lookup ), City ( lookup - used cascade drop down so got the results based on country's selection).

I wanted speciality column it's visible in Edit Item and New Item by using display related info but I wanted on View Item ( i.e. dips form)

Can you tell me what I am missing.

This is the script in my CEWP

<script type="text/javascript" src="/Documents/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/Documents/jquery.SPServices-0.5.5.js"></script>
<script type="text/javascript" src="/Documents/jquery.SPServices-0.5.5.min.js"></script>

<script language="javascript" type="text/javascript">
 $(document).ready(function() {
  

                         $().SPServices.SPDisplayStaticRelatedInfo({
 columnName: "City",
 relatedList: "City",
 relatedListColumn: "Title",
 relatedColumns: ["Speciality"],
        displayFormat: "list",
 headerCSSClass: "ms-vh2",
 rowCSSClass: "ms-vb",
 matchType: "Eq",
        CAMLQuery: "",
 debug: true
    

 

});


 });
</script>

Thanks in advance for your help. Thanks Marc for this wonderful project. Also can you tell me any article for DVWP which is replica for dispform.aspx i.e shows single record and wid data from other list as well.

PP

 

Coordinator
Jun 18, 2010 at 3:03 AM
Edited Jun 22, 2010 at 3:46 PM

PP:

Your script references aren't right. Assuming that you have the jQuery library and SPServices in /Documents, you need this:

<script type="text/javascript" src="/Documents/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/Documents/jquery.SPServices-0.5.5.min.js"></script>

instead of this

<script type="text/javascript" src="/Documents/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/Documents/jquery.SPServices-0.5.5.js"></script>
<script type="text/javascript" src="/Documents/jquery.SPServices-0.5.5.min.js"></script>

The two versions of SPServices are a minified version and an uncompressed version.

Otherwise, this code above is not mine, so I'd suggest that you contact justmara directly if you have questions.

M.

Jun 21, 2010 at 6:26 PM
Hi Marc, So basically what I did is copy paste the code of justmara for SPDisplayStaticRelatedInfo to uncompressed version and refered it. But yeah I will contact to justmara. P.S. I was able to use DVWP and accomplish same functionality but would like to know how justmara had done it using his code. Thanks for reply Marc.