Limit number of allowed selections in Checkboxes choice

Change log
October 22, 2014
v1.1: Updated the code to support new versions of jQuery and added support for Surveys (tested in SP2010).

In this article will show you how to limit the number of allowed selections in a column of type “Choice: Checkboxes (allow multiple selections)”.

The reason for this is that a column of type “Choice: Radio Buttons”, cannot be “unselected” once it is selected.

The code gives you the ability to specify the number of options a user can select.

The script behaves differently for “single choice” and for “multi choice”.

Single: The selection “moves” when you select another option – only one “tick” is allowed
Multiple: A message appears beneath the checkboxes announcing the allowed number of selection. You cannot select another option until you have removed one of the previous selections.

IMG
The “errorText” will disappear after 4 seconds.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

October 22, 2014: Please note that the updated code example requires jQuery verions above v1.6

Add a CEWP below your NewForm and EditForm with this code:

<script type="text/javascript" src="/Javascript/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="/Javascript/LimitSelectionsInCheckboxes.js"></script>
<script type="text/javascript">
initLimitSelections('YourFieldInternalName',2,'Only 2 selections allowed.');
</script>

Parameters explained:

FieldInternalName: FieldInternalName of your “Checkboxes-column”.
allowedSelections: Number of selections allowed.
errorText: The text shown below the checkboxes if the selections exceed the allowed number of selections. Not used if the parameter “allowedSelections” is 1.

The sourcecode for the file “LimitSelectionsInCheckboxes.js” looks like this

/* 
 * Limit allowed selections in Checkboxes-column
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1
 * LastMod: 22.10.2014
*/

var multiChoiceFields = init_multiChoiceFields();

function initLimitSelections(FieldInternalName,allowedSelections,errorText){
	if(typeof errorText === "undefined" || errorText === ""){
		errorText = "You can only select " + allowedSelections + " options.";
	}
	$(multiChoiceFields[FieldInternalName]).find("input").click(function(){
		limitSelections($(this),FieldInternalName,allowedSelections,errorText);
	});
}

function limitSelections(currOpt,fin,n,errText){
	var f = $(multiChoiceFields[fin]), c, chk;
	$("#customMultiSelectValidation").remove();
	c = f.find("input:checked").length;
	// If allowedSelections = 1 move selection
	if(n === 1){
		chk = currOpt.prop("checked");
		f.find("input:checked").each(function(){
			$(this).prop("checked",false);
		});
		currOpt.prop("checked",chk);
	}else{
		// Uncheck current selection and give user a visual feedback on number of allowed selections
		if(c > n){
			currOpt.prop("checked",false);
			f.find("td[class^='ms-formbody']").append("<div id='customMultiSelectValidation' class='ms-formvalidation'>" + errText + "</div>");
			$("#customMultiSelectValidation").fadeOut(4000)
		}
	}
}

function init_multiChoiceFields(){
	var res = {}, myMatch, disp, fin, type;
	$("td[class^='ms-formbody']").each(function(){
	myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);	
		if(myMatch!=null){
			// Display name
			disp = myMatch[1];
			// FieldInternalName
			fin = myMatch[2];
			// FieldType
			type = myMatch[3];
			if(type!=='SPFieldMultiChoice'){
				return;
			}		
			// Build object
			res[fin] = this.parentNode;
			$(res[fin]).attr('FieldDispName',disp);
			$(res[fin]).attr('FieldType',type);
		}		
	});
	return res;
}

Save this code as “LimitSelectionsInCheckboxes.js” – mind the file extension, and upload to the scriptlibrary as shown above.

Ask if something is unclear.

Regards
Alexander

Highlight row by value in Yes/No-column

08.10.2011 Updated with SharePoint 2010 code.


22.04.2010 Updated the code to support multiple views of the same list in the same page, as requested by Mich.

The file “HighlightRowByYesNoColumn.js” is updated.


In this post i will show you how to highlight a row in a list view based on the value in a column of type “Yes/No (check box)”. The code would work on other types of columns as well.

IMG
This is from a standard list view, it does also work in grouped view’s.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

Add a CEWP below the list view and insert this code:

<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/HighlightRowByYesNoColumn.js"></script>
<script type="text/javascript">
highlightRowByYesNoField('Yes','YesNo','#FFD700','Highlighted rows awaiting action...');
</script>

Parameters explained:

  • valToTriggerHighlighting: The text you want to trigger the highlighting on – “Yes”
  • FieldInternalName: The FieldInternalName of the column to get the value from – must be in view
  • highlightColor: The background color of the highlighted row
  • mouseOverOnRow: The mouse over message when hovered over a highlighted row

The sourcecode for the file “HighlightRowByYesNoColumn.js” looks like this:

SharePoint 2007
/* Highlight row in list view based on value in a Yes/No-column
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1
 * LastMod: 22.04.2010
 * ---------------------------------------------
 * Include reference to jquery - http://jquery.com
 * ---------------------------------------------
 * Call from a CEWP below the list view with this code:
	<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
	<script type="text/javascript" src="/test/English/Javascript/HighlightRowByYesNoColumn.js"></script>
	<script type="text/javascript">
		highlightRowByYesNoField('Yes','YesNo','#FFD700','Highlighted rows awaiting action...');
	</script>
*/

function highlightRowByYesNoField(valToTriggerHighlighting,FieldInternalName,highlightColor,mouseOverOnRow){
	if(typeof(valToTriggerHighlighting)!='undefined'){
		valToFind = valToTriggerHighlighting;
	}
	if(typeof(FieldInternalName)!='undefined'){
		fin = FieldInternalName;
	}
	if(typeof(highlightColor)!='undefined'){
		bgColor = highlightColor;
	}
	if(typeof(mouseOverOnRow)!='undefined'){
		mouseOver = mouseOverOnRow;
	}
	
	$("table.ms-listviewtable").each(function(){
		var thisListView = $(this);
		// Find colindex of YesNo-field
		thisListView.find(".ms-viewheadertr th").each(function(){
			if($(this).text()==fin){
				colIndex = $(this).attr('cellIndex');		
			}
		});
		
		// Loop trough all rows and highlight matched rows
		thisListView.find("tbody:not([id^='aggr']) tr:has(td.ms-vb2)[highlighted!='1']").each(function(){			
			var rowVal = $(this).find("td[cellIndex='"+colIndex+"']").text();
			if(rowVal==valToFind){
				$(this).attr({'highlighted':'1','title':mouseOver}).css({'background-color':bgColor});		
			}		
		});
	});
}

// Attaches a call to the function to the "expand grouped elements function" for it to function in grouped listview's
function ExpGroupRenderData(htmlToRender, groupName, isLoaded){
	var tbody=document.getElementById("tbod"+groupName+"_");
	var wrapDiv=document.createElement("DIV");
	wrapDiv.innerHTML="<TABLE><TBODY id="tbod"+groupName+"_" isLoaded=""+isLoaded+"">"+htmlToRender+"</TBODY></TABLE>";
	tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
highlightRowByYesNoField();
}
SharePoint 2010
/* Highlight row in list view based on value in a Yes/No-column
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1 for SharePoint 2010
 * LastMod: 08.10.2011
 * ---------------------------------------------
 * Include reference to jquery - http://jquery.com
 * ---------------------------------------------
 * Call from a CEWP below the list view with this code:
*/

function highlightRowByYesNoField(valToTriggerHighlighting,FieldInternalName,highlightColor,mouseOverOnRow){
	var fName;
	if(typeof(valToTriggerHighlighting)!='undefined'){
		valToFind = valToTriggerHighlighting;
	}
	if(typeof(FieldInternalName)!='undefined'){
		fin = FieldInternalName;
	}
	if(typeof(highlightColor)!='undefined'){
		bgColor = highlightColor;
	}
	if(typeof(mouseOverOnRow)!='undefined'){
		mouseOver = mouseOverOnRow;
	}
	$("table.ms-listviewtable").each(function(){
	
		var thisListView = $(this);
		// Find colindex of YesNo-field
		thisListView.find(".ms-viewheadertr th").each(function(){				
			fName = $(this).find('div:first').attr('name')
			if(fName==fin){
				colIndex = this.cellIndex;
			}
		});
		// Loop trough all rows and highlight matched rows
		thisListView.find("tbody:not([id^='aggr']) tr:has(td.ms-vb2)[highlighted!='1']").each(function(){
			var rowVal = $(this).find(">td:eq("+colIndex+")").text();
			if(rowVal==valToFind){
				$(this).attr({'highlighted':'1','title':mouseOver}).css({'background-color':bgColor});
			}
		});
	});
}

function customTimeoutLoop(id){
var obj = $("#"+id);
var isloaded = ($(obj).attr('isloaded')=='true')?true:false;
	if(!isloaded){
		$(obj).hide();
		setTimeout(function(){
			customTimeoutLoop(id);
		},10);
	}else{
		$(obj).show();
		highlightRowByYesNoField();		
	}
}

function ExpGroupRenderData(d, a, e) {
    ULSA13: {
    }
    var c = document.getElementById("tbod" + a + "_"), b = document.createElement("DIV"), f = a.split("-");
    b.innerHTML = "<TABLE><TBODY id="tbod" + a + "_" isLoaded="" + e + "">" + d + "</TBODY></TABLE>";
    c.parentNode.replaceChild(b.firstChild.firstChild, c); 
 customTimeoutLoop("tbod" + a + "_");   
}

Save the code as a file named “HighlightRowByYesNoColumn.js” – mind the file extension, and upload to the scriptlibrary as shown above.

Note when combining with other scripts that embeds the function “ExpGroupRenderData”: The function “ExpGroupRenderData” is not to be added twice. You must leave the one in the script called last, and include the function call to both/all custom function that is to be triggered by expanding grouped view’s – like in line 58 in the SP2007-code above.

Ask if something is unclear

Regards
Alexander

CEWP – one click edit: Rich text or Sourcecode

This script adds “one click edit of an CEWP”. It supports both “Rich text editor…” and “Source code editor…”.

NOTE: You must add the site to “Local Intranet” in IE, if not the one click edit might not work.

The function checks that the logged in user has “Edit Page rights” before adding these links. The check is simply done by checking if the “Edit Page” link is present in the page.

IMG

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The file “sessvars.js” is found here.

The code for the file “OneClickEditCEWP.js” is provided below.

Add a CEWP below the WebPart’s you want to add this feature to, and add this code to it:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/EMSKJS/jquery-1.3.1.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/EMSKJS/sessvars.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/EMSKJS/OneClickEditCEWP.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
   var EditText = 'Edit rich text|Edit code'; // The text of the edit link
   var EditTextMouseOver = 'Click to edit'; // Mouseover on edit-link
&lt;/script&gt;

This is the code for the file “OneClickEditCEWP.js”:

/* One click edit of CEWP - Rich text or code edit
 *  Author Alexander Bautz
 *  alexander.bautz@gmail.com
 *  https://spjsblog.com
 *  v1.0
 *  LastMod: 22.12.2009
 *
 * Requirements:
 * jQuery library http://jquery.com
 * sessvars.js from http://www.thomasfrank.se/sessionvars.html
 *
 * Define these variables in CEWP at the bottom of the page:
 * var EditText = 'Edit rich text|Edit code'; // The text of the edit link
 * var EditTextMouseOver = 'Click to edit'; // Mouseover on edit-link
 * 
 Example of CEWP in WebPartPage:
 	&lt;script type=&quot;text/javascript&quot; src=&quot;../EMSKJS/jquery-1.3.1.min.js&quot;&gt;&lt;/script&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;../EMSKJS/sessvars.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;../EMSKJS/OneClickEditCEWP.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
		var EditText = 'Edit rich text|Edit code'; // The text of the edit link
		var EditTextMouseOver = 'Click to edit'; // Mouseover on edit-link
	&lt;/script&gt;
 * --------------------------------------------------------
 * To exclude a webpart, add an empty DIV with class &quot;customSkipThisCEWP&quot; to the webpart body
 * &lt;div class=&quot;customSkipThisCEWP&quot;&gt;&lt;/div&gt;
 * --------------------------------------------------------
 */ 

$(document).ready(function(){
var split = EditText.split('|');
var editRichText = split[0];
var editCode = split[1];
if($(&quot;*[id$='MenuItem_EditPage']&quot;).length&gt;0){
		$(&quot;td[id ^= 'MSOZoneCell_WebPartWPQ']&quot;).each(function(){
		if($(this).find(&quot;.customSkipThisCEWP&quot;).length==0){
			var uniqueID = $(this).find(&quot;.ms-WPBody&quot;).attr('webpartid');
			var wpIdRaw = $(this).attr('id');
			var wpId = wpIdRaw.substring(wpIdRaw.indexOf('_')+4);			
				if(uniqueID != undefined){			
					var editLink = &quot;&quot;;			
						editLink += &quot;&lt;a title='&quot; + EditTextMouseOver + &quot;' href='#' &quot;;
						editLink += &quot;onclick='javascript:sessvars.wpId=&quot;&quot; + wpId + &quot;&quot;;MSOTlPn_ShowToolPane2Wrapper(&quot;Edit&quot;,&quot;129&quot;,&quot;&quot; + uniqueID + &quot;&quot;);sessvars.EditCode=false'&gt;&quot;;
						editLink += editRichText + &quot;&lt;/a&gt;&amp;nbsp;|&amp;nbsp;&lt;a title='&quot; + EditTextMouseOver + &quot;' href='#' &quot;;
						editLink += &quot;onclick='javascript:sessvars.wpId=&quot;&quot; + wpId + &quot;&quot;;MSOTlPn_ShowToolPane2Wrapper(&quot;Edit&quot;,&quot;129&quot;,&quot;&quot; + uniqueID + &quot;&quot;);sessvars.EditCode=true'&gt;&quot;;
						editLink += editCode + &quot;&lt;/a&gt;&quot;;
						editLink = &quot;&lt;div style='display:none;font-size:xx-small;color:gray;' id='customEditLink_&quot; + wpId + &quot;'&gt;&quot; + editLink + &quot;&lt;/div&gt;&quot;;
					$(this).prepend(editLink);
					$(this).hover(function(){	
						var offset = $(this).offset();
						$(&quot;#customEditLink_&quot; + wpId).css({'position':'absolute','left':offset.left,'top':(offset.top-12)}).show().stop().fadeTo('fast',1);
					},function(){
						$(&quot;#customEditLink_&quot; + wpId).stop().fadeTo('slow',0);
					});
				}
			}
		});	
		// Open the editor only if it has been triggered by the custom link
		if($(&quot;#MsoContentToolpartBasicContentProperty&quot;).length&gt;0 &amp;&amp; sessvars.wpId!=undefined){
			if(sessvars.EditCode){
				$(&quot;#MsoContentToolpartBasicSourceViewLiteral&quot;).click();
			}else{
				$(&quot;#MsoContentToolpartBasicDesignViewLiteral&quot;).click();				
			}
			sessvars.$.clearMem();
			window.location.href(window.location.href);
		}			
	}
});

Save the file as “OneClickEditCEWP.js”, and upload to the scriptlibrary as shown above.

Note:

  • The reason for using the “sessvars.js”, it so prevent “hijacking” of the page if manually edited trough “Edit page-link”
  • If the page only refreshes without showing the “edit window”, you may have a pop up-blocker activated. Manually edit the page, and allow any pop up’s
  • To exclude a CEWP from being equipped with an “Edit-link”, add a “dummy” DIV-tag with class “customSkipThisCEWP” to the CEWP code.

Ask if something is unclear

Regards
Alexander

Show current row wrapped in a floating table when hovered

This one is an attempt to answer Charlie’s request:

Hi Alexander:
On several of my lists, I struggle with the width of the page and too many fields. I use some simple javascript to wrap the column headers but I still need to prevent users from having to scroll side to side…

IMG

This script adds a mouse over preview of the current row in a floating DIV. It is related to the script Preview metadata in list view on mouseover, but is simpler as it does only wrap up the content of the current row.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

Add a CEWP below the list view and add this code:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/mouseOverWrapRowTableStyle.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// Initiate mouse over when hovered for 1000 milliseconds
initShowRowAsTable(1000);
&lt;/script&gt;

This is the sourcecode for the file “mouseOverWrapRowTableStyle.js”:

function initShowRowAsTable(delay){
	if(typeof(delay)=='number'){
		hoverDelay = delay;
	}
	if(typeof(hoverDelay)=='undefined'){
		hoverDelay = 500;
	}
	// Add a &quot;description&quot; in the list view toolbar
	if($(&quot;#hoverDelayInfo&quot;).length==0){
		var str = &quot;Hover over a row for &quot; + hoverDelay/1000 + &quot; second to view content &quot;table-style&quot;&quot;;
		$(&quot;td.ms-toolbar[width='99%']&quot;).append(&quot;&lt;div id='hoverDelayInfo' class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'&gt;&quot; + str + &quot;&lt;/div&gt;&quot;);
	}

	// Build object of all headings
	if(typeof(objTH)=='undefined'){
		objTH = {};
		$(&quot;.ms-viewheadertr th&quot;).each(function(){
		var colIndex = $(this).attr('cellIndex');
			if($(this).text()!='' ){
				objTH[colIndex] = $(this).text();
			}
		});
	}

	$(&quot;table.ms-listviewtable tbody:not([id^='aggr']) tr:has(td.ms-vb2)[beenthere!='1']&quot;).each(function(){	
		$(this).attr('beenthere','1');
		// Add hover function
		$(this).hover(function(e){
		// Add highlighting of &quot;hovered&quot; row
		$(this).addClass(&quot;ms-dialogHoverRow&quot;);	
		var row = $(this);
		// If hovered more than &quot;hoverDelay&quot; - show contents
		setTimeout(function(){
				if(row.hasClass('ms-dialogHoverRow')){
					$(&quot;#customHoverDiv&quot;).remove();
					pX = e.pageX + 10;
					pY = e.pageY + 15;	
					showRowAsTable(row);
				}
			},hoverDelay);
		},function(){
			// Remove highlighting of &quot;hovered&quot; row
			$(this).removeClass(&quot;ms-dialogHoverRow&quot;);
			// Remove floating div
			$(&quot;#customHoverDiv&quot;).remove();
		});
	});
}

function showRowAsTable(obj){
	// Create new hidden DIV	
	var newDiv = $(&quot;&lt;div style='display:none'&gt;&lt;/div&gt;&quot;).attr('id','customHoverDiv').html(obj.html()).appendTo(&quot;.ms-bodyareaframe&quot;);
	str = '';
	
	// Extract the contents of the row and build a new table
	newDiv.find('&gt;td').each(function(idx){
		if(objTH[idx]!=undefined){
			if($(this).attr('class')=='ms-vb-title'){
				var value = $(this).text();
			}else{
				var value = $(this).html();
			}
			str += &quot;&lt;tr&gt;&lt;td class='ms-formlabel' valign='top'&gt;&quot; + objTH[idx] + &quot;:&lt;/td&gt;&lt;td class='ms-formbody'&gt; &quot; + value + &quot;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&quot;;		
		}
	});
	
	// Replace the DIV-content with the newly buildt table
	newDiv.html(&quot;&lt;table cellpadding='0' cellspacing='0' class='ms-formtable'&gt;&quot; + str + &quot;&lt;/table&gt;&quot;);
	var contentWidth = '400';
	var contentHeight = $(&quot;#customHoverDiv&quot;).height();			
	var winHeight = $(window).height();
	var winWidth = $(window).width();
	var winScroll = $(window).scrollTop();
	// Calculate the best position for the popup Y-axis
	if((winHeight - pY) &lt; contentHeight){
		if((pY - winScroll) &lt; contentHeight){
			pY = winScroll + 10
		}else{
			pY = (pY - contentHeight) - 30
		}
	}
	// Calculate the best position for the popup X-axis
	if((winWidth - pX) &lt; contentWidth){
		pX = (pX - contentWidth) - 30;
	}
	// Show popup			
	newDiv.css({'position':'absolute',
		'left':pX,
		'top':pY,
		'background-color':'f8f8ff',
		'border':'2px silver ridge',
		'padding':3})
	.show().mouseenter(function(){
		$(this).hide();
	});
}

// Attaches a call to the function to the &quot;expand grouped elements function&quot; for it to function in grouped listview's
function ExpGroupRenderData(htmlToRender, groupName, isLoaded){
	var tbody=document.getElementById(&quot;tbod&quot;+groupName+&quot;_&quot;);
	var wrapDiv=document.createElement(&quot;DIV&quot;);
	wrapDiv.innerHTML=&quot;&lt;TABLE&gt;&lt;TBODY id=&quot;tbod&quot;+groupName+&quot;_&quot; isLoaded=&quot;&quot;+isLoaded+&quot;&quot;&gt;&quot;+htmlToRender+&quot;&lt;/TBODY&gt;&lt;/TABLE&gt;&quot;;
	tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
initShowRowAsTable();
}

Save this as a file – name it “mouseOverWrapRowTableStyle.js”, and upload it to your script library as shown above.

Ask if something is unclear.

Alexander

Accordion in SharePoint form

12.03.2011: I have posted a new release, you find it here.


In this example i will show how to use the jQuery UI widget “Accordion” in a SharePoint form.

NewForm:
IMG
On form validation (refresh) it selects the first section containing empty fields:
IMG
DispForm with attachment:
IMG

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

A folder named “jQueryUI” containing the scripts and the “images”-folder for the selected theme:
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The jQuery UI-library is found here. Find the theme of your choice – mine is “smootness” – and download the files (select the widgets and effects you want – the file is dynamically built according to your selection).

Add a CEWP below your NewForm, DispForm and EditForm.

Add this code:

&lt;DIV id=&quot;accordion&quot; style=&quot;font-size:14px&quot;&gt;	
	&lt;H3&gt;&lt;A href=&quot;#accordion-0&quot;&gt;Section 1&lt;/A&gt;&lt;/H3&gt;
	&lt;div&gt;&lt;table width=&quot;100%&quot; id=&quot;accTable-0&quot;&gt;&lt;/table&gt;&amp;nbsp;&lt;/div&gt;
	&lt;H3&gt;&lt;A href=&quot;#accordion-1&quot;&gt;Section 2&lt;/A&gt;&lt;/H3&gt;
	&lt;div&gt;&lt;table width=&quot;100%&quot; id=&quot;accTable-1&quot;&gt;&lt;/table&gt;&amp;nbsp;&lt;/div&gt;
	&lt;H3&gt;&lt;A href=&quot;#accordion-2&quot;&gt;Section 3&lt;/A&gt;&lt;/H3&gt;
	&lt;div&gt;&lt;table width=&quot;100%&quot; id=&quot;accTable-2&quot;&gt;&lt;/table&gt;&amp;nbsp;&lt;/div&gt;
	&lt;H3&gt;&lt;A href=&quot;#accordion-3&quot;&gt;Attachments&lt;/A&gt;&lt;/H3&gt;
	&lt;div&gt;&lt;table width=&quot;100%&quot; id=&quot;accTable-3&quot;&gt;&lt;/table&gt;&amp;nbsp;&lt;/div&gt;	
&lt;/DIV&gt;

&lt;link type=&quot;text/css&quot; href=&quot;/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

// Array of all fields - format: accID|FieldInternalName
// Note that accID is zero-indexed
arrOfFields = ['0|Title','0|SectionOneText','0|Section1Choice',
		  '1|Responsible','1|Section2Text',
		  '2|Section3Multiline','2|Section3Choice'];

// Initiate all the fields
fields = init_fields();

// Add the &quot;accordion&quot; to the formtable	
$(&quot;#accordion&quot;).insertAfter('.ms-formtable').accordion({autoHeight: false,animated: false});
// Loop trough all fields and move them to the right accordion section
fValAccID = '';
$.each(arrOfFields,function(idx,item){
	var split = item.split('|');
	var accID = split[0];
	var fieldName = split[1];
	if(fields[fieldName]!=undefined){
		currField = $(fields[fieldName]);
		currField.appendTo('#accTable-'+accID);
		
		// Formvalidation - find the first tab with empty required fields
		if(fValAccID == '' &amp;&amp; currField.find('.ms-formbody span.ms-formvalidation').length&gt;0){
			fValAccID = accID;
		}
	}
});

// Move the Attachment's to the last section
$(&quot;#idAttachmentsRow&quot;).appendTo('#accTable-3');

// Are there any required fields not filled? - select the section containing the first field
if(fValAccID !=''){
	// Show the right section
	setTimeout(function(){$('#accordion').accordion('activate',parseInt(fValAccID));},10);
}

// Fix IE8 issue with content not showing (because it is in a table within the DIV) + remove the default padding
$(&quot;.ui-accordion-content&quot;).css({'zoom':1,'padding':'0px'});

// function - to make &quot;object&quot; of all tr's in the form
function init_fields(){
  var res = {};
  $(&quot;td.ms-formbody&quot;).each(function(){
	  if($(this).html().indexOf('FieldInternalName=&quot;')&lt;0) return;
	  var start = $(this).html().indexOf('FieldInternalName=&quot;')+19;
	  var stopp = $(this).html().indexOf('FieldType=&quot;')-7;
	  var nm = $(this).html().substring(start,stopp);
	  res[nm] = this.parentNode;
  });
  return res;
}
&lt;/script&gt;

The only parameters you need to edit in the script is the array of FieldInternalNames. The format of the variable “arrOfFields” is accID|FieldInternalName.

In the html above the script, adapt the number’s of sections – and the section’s display name. The accID corresponds with the index of the table to insert the content in (zero-indexed).

All fields must be added to a section – if not it looks ugly….

Note: As for the “Tabs in SharePoint form”, by now i have tested and found that columns of type “Multiple lines of text (Rich text or Enhanced rich text) do not work. What happens is that the section shows some of the fields hidden parts.

I have not done any testing on how to prevent this issue, so feel free to notify me if you find a workaround.

Note: The animation is disabled because of a “flicker problem” in IE8 due to the page being rendered in “Quirks Mode”.

Regards
Alexander

Tabs in SharePoint form

18.01.2011 I have posted a new solution compatible with both SP2007 and SP2010 and fixes the problems with rich text fields and “single lookup with more than 20 items under Internet Explorer – problem”. You find it her


23.01.2010 Updated the code to fix two issues regarding date and time columns. I added a <style> tag to set the font size of “.ms-dtinput” and “.ms-dttimeinput” to 0.7em.

I also added a custom handler to select the right tab on “empty field validation” on a date and time field. These are validated without page reload, and therefore did not work in the previous version.

Thank you all for the feedback and the testing.

15.12.2009 Update to support form validation. On submit – if there are required fields not filled – the tab containing the first required field is selected.


I got this request:

We have a custom list with a lot of fields. I need to divide it into sections and then easily show/hide those sections. I am going to try dividing the form into div tags and then use jQuery to display the sections in either Tabs or an accordion…

And made this demo based on the jQuery UI Widget “Tabs”.

NewForm:
IMG
DispForm:
IMG
DispForm with attachment:
IMG

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

A folder named “jQueryUI” containing the scripts and the “images”-folder for the selected theme:
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The jQuery UI-library is found here. Find the theme of your choice – mine is “smootness” – and download the files (i have plucked only the necessary files – “UI Core” and “Tabs”).

Add a CEWP below your NewForm, DispForm and EditForm.

Add this code:

&lt;!-- Date field text size --&gt;
&lt;style type=&quot;text/css&quot;&gt;
.ms-dtinput,.ms-dttimeinput{
	font-size:0.7em;
}
&lt;/style&gt;
&lt;DIV id=&quot;tabs&quot;&gt;
	&lt;UL style=&quot;font-size:12px&quot;&gt;
		&lt;LI&gt;&lt;A href=&quot;#tabs-1&quot;&gt;Tab 1&lt;/A&gt;&lt;/LI&gt;
		&lt;LI&gt;&lt;A href=&quot;#tabs-2&quot;&gt;Tab 2&lt;/A&gt;&lt;/LI&gt;
		&lt;LI&gt;&lt;A href=&quot;#tabs-3&quot;&gt;Tab 3&lt;/A&gt;&lt;/LI&gt;
		&lt;LI&gt;&lt;A href=&quot;#tabs-4&quot;&gt;Attachments&lt;/A&gt;&lt;/LI&gt;
	&lt;/UL&gt;

	&lt;div&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; id=&quot;tabs-1&quot;&gt;&lt;/table&gt;&lt;/div&gt;
	&lt;div&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; id=&quot;tabs-2&quot;&gt;&lt;/table&gt;&lt;/div&gt;
	&lt;div&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; id=&quot;tabs-3&quot;&gt;&lt;/table&gt;&lt;/div&gt;
	&lt;div&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; id=&quot;tabs-4&quot;&gt;&lt;/table&gt;&lt;/div&gt;
&lt;/DIV&gt;

&lt;link type=&quot;text/css&quot; href=&quot;/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// Array of all fields - format: tabID|FieldInternalName
arrTab = ['1|Title','1|Tab1Text','1|Tab1Choice',
		  '2|Responsible','2|Tab2Text','2|Tab2Choice','2|Date',
		  '3|Tab3Text','3|Tab3Choice','3|Tab3MultilinePlain'];

// Initiate all the fields
fields = init_fields();

// Add the &quot;tabs&quot; to the formtable
$(&quot;#tabs&quot;).insertAfter('.ms-formtable').tabs();
// Loop trough all fields and move them to the right tab
$.each(arrTab,function(idx,item){
	var split = item.split('|');
	var tabID = split[0];
	var fieldName = split[1];
	if(fields[fieldName]!=undefined){
		currField = $(fields[fieldName]);
		currField.appendTo('#tabs-'+tabID);		
	}
});

// Are there any required fields not filled? - select the tab containing the first field
selectTabOnFormValidation(false);
function selectTabOnFormValidation(preSave){
var formvalidationTab = '';
// Formvalidation - find the first tab with empty required fields
	$.each(arrTab,function(idx,item){
		var split = item.split('|');
		var tabID = split[0];
		var fieldName = split[1];
		currField = $(fields[fieldName]);
		// Handles DateTimeField (empty field validation is performed without page reload)
		if(currField.find(&quot;SPAN[ID*='_DateTimeField_']&quot;).length&gt;0){
			if(currField.find('input:first').val()=='' &amp;&amp; preSave){
				formvalidationTab = tabID;
			}
		}
		if(formvalidationTab == '' &amp;&amp; currField.find('.ms-formbody span.ms-formvalidation').length&gt;0){
			formvalidationTab = tabID;
		}
	});
	// Select the first tab containing an empty required field
	if(formvalidationTab!=''){
		$('#tabs').tabs('select', formvalidationTab);
	}
}

// Move the Attachment's to the last tab
$(&quot;#idAttachmentsRow&quot;).appendTo('#tabs-4').find('.ms-formlabel').attr('width','165px');

// function - to make &quot;object&quot; of all tr's in the form
function init_fields(){
  var res = {};
  $(&quot;td.ms-formbody&quot;).each(function(){
	  if($(this).html().indexOf('FieldInternalName=&quot;')&lt;0) return;
	  var start = $(this).html().indexOf('FieldInternalName=&quot;')+19;
	  var stopp = $(this).html().indexOf('FieldType=&quot;')-7;
	  var nm = $(this).html().substring(start,stopp);
	  res[nm] = this.parentNode;
  });
  return res;
}

// Catch &quot;empty field validation&quot; on date and time columns
function PreSaveAction(){
selectTabOnFormValidation(true);
return true;
}
&lt;/script&gt;

The only parameters you need to edit in the script is the array of FieldInternalNames. The format of the variable “arrTab” is tabID|FieldInternalName.

In the html above the script, adapt the number’s of tabs – and the tab’s display name. The tabID corresponds with the number in the id attribute of the table to insert the tab content in.

All fields must be added to a tab – if not it looks ugly….

Note: By now i have tested and found that columns of type “Multiple lines of text (Rich text or Enhanced rich text) do not work. What happens is that the tabs script shows some of the fields hidden parts.

I have not done any testing on how to prevent this issue, so feel free to notify me if you find a workaround.

Regards
Alexander

Edit date, single line text, number or boolean columns directly in list view

31.03.2010 updated the code and reworked the article:

This solution enables you to edit a column of type “Date and Time (Date Only)”, “Single line of text”, “Number”, “Currency”, “Yes/No” and “single choice people picker” directly in a list view.

I’m planning on updating with support for columns columns later on.

Double click on a “TD” to edit – this action is per “TD”.
IMG

In this picture all “TD’s” are double clicked on.
IMG

The people picker is created with the jQuery UI widget “Autocomplete”.
IMG

When saved OK – a picture is appended to indicate “Save OK”.
IMG

A different picture is appended on save error.
IMG

This can be used in lists and document library’s, but requires that a the ID column is in the view (it can be hidden in the script by setting the argument “hideIdColumn” to true).

I have added support for “date”, “single line text”, “number”, “currency”, “boolean” and “single choice people picker” columns. I will update this article with support for choice columns later on.

All these columns – for filtering purposes – supply their FieldInternalName in the list header. This way i do not have to specify the column index where it is found – it dynamically adapts to changing column order.

This solution can be used with plain list view’s and grouped view’s.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

In addition to the above scripts, i have the jQuery UI 1.8 in a separate folder. See the CEWP code and point the links to your jQuery UI location.

The jQuery UI-library is found here. The pictures and the sourcecode refers to jquery-ui-1.8. The autocomplete widget is not found in previous releases.

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.4.min. The autocomplete widget is not supported in previous releases.

The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.

Read here how to find the list Guid of your list, and how to find the FieldInternalName of your columns.

I have made one modification in the file “jquery-ui-1.8.custom.css” to correct the datepicker positioning of the date and year dropdowns. The style “.ui-datepicker select.ui-datepicker-year { width: 49%;}” is modified like this: “.ui-datepicker select.ui-datepicker-year { width: auto;}”. This might not affect your setup, and is merely a detail.

The sourcecode for “EditInListView.js” is provided below.

Add a CEWP below the list view webpart, and add this code:

&lt;style type=&quot;text/css&quot;&gt;
.ui-menu .ui-menu-item {
	font-size:xx-small;
}
&lt;/style&gt;
&lt;link type=&quot;text/css&quot; href=&quot;/test/English/jQueryUI18/smoothness/jquery-ui-1.8.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/jQueryUI18/jquery-ui-1.8.custom.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/EditInListView.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// Set variables
	hoverImgSrc = '/_layouts/images/DOWNARRW.GIF';
	hoverImgMouseOver = 'Double click to edit';
	successImgSrc = '/_layouts/images/ServiceInstalled.gif';
	failureImgSrc = '/_layouts/images/ServiceNotInstalled.gif';
	dateFormat = 'm/d/yy'; // alternative d.m.yy
	decimalSeparator = '.'; // The symbol used to mark the boundary between the integral and the fractional parts of a decimal number
	boolYesNoText = 'Yes|No'; // The display text in list view for a Yes/No-field
	userListGuid = '570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF';
	userListBaseUrl = ''
	arrToEdit = ['MyDateField','SingleLine','Number','YesNo','MyPeoplePicker'];
	
// Call function
	initCustomEditFunction(true);
&lt;/script&gt;

Edit the array “arrToEdit” to hold your FieldInternalNames, the “userListGuid” to hold your list guid, and other parameters if necessary.

Parameter’s explained:

  • hoverImgSrc: The source of the image indicating editable field
  • hoverImgMouseOver: The mouse over on the “hoverImgSrc-image”
  • successImgSrc: The source of the image displayed when saving the new value succeeds
  • failureImgSrc: The source of the image displayed when saving the new value fails
  • dateFormat: ‘m/d/yy’ – alternative ‘d.m.yy’
  • decimalSeparator: The symbol used to mark the boundary between the integral and the fractional parts of a decimal number
  • boolYesNoText: The display text in list view for a Yes/No-field – format: Yes|No
  • userListGuid: The list guid for the userlist, used for the people picker
  • userListBaseUrl: Base URL for the list “People and Groups”. If in a managed path, reflect this path, else set to “” (blank string)
  • arrToEdit: Array of FieldInternalNames to address

The sourcecode for the file “EditInListView.js” looks like this:

/* Edit date, single line text, number, currency, boolean or single choice people picker directly in list view
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1
 * LastMod: 31.03.2010
 * ---------------------------------------------
 * Must include reference to:
 *  jquery-1.4 - http://jquery.com
 *  jquery-ui-1.8 - http://jqueryui.com/
 *  interaction.js - http://spjslib.codeplex.com
 *  stringBuffer.js - http://spjslib.codeplex.com
 * ---------------------------------------------
 *
 * Call from CEWP BELOW the list view like this:  
	&lt;style type=&quot;text/css&quot;&gt;
	.ui-menu .ui-menu-item {
		font-size:xx-small;
	}
	&lt;/style&gt;
	&lt;link type=&quot;text/css&quot; href=&quot;/test/English/jQueryUI18/smoothness/jquery-ui-1.8.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/jQueryUI18/jquery-ui-1.8.custom.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/EditInListView.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
	// Set variables
		hoverImgSrc = '/_layouts/images/DOWNARRW.GIF';
		hoverImgMouseOver = 'Double click to edit';
		successImgSrc = '/_layouts/images/ServiceInstalled.gif';
		failureImgSrc = '/_layouts/images/ServiceNotInstalled.gif';
		dateFormat = 'm/d/yy'; // alternative d.m.yy
		decimalSeparator = '.'; // The symbol used to mark the boundary between the integral and the fractional parts of a decimal number
		boolYesNoText = 'Yes|No'; // The display text in list view for a Yes/No-field
		userListGuid = '570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF';
		userListBaseUrl = ''
		arrToEdit = ['MyDateField','SingleLine','Number','YesNo','MyPeoplePicker'];
		
	// Call function
		initCustomEditFunction(true);
	&lt;/script&gt;
*/

function initCustomEditFunction(hideIdColumn){
	if(typeof(hideIdColumn)!='undefined'){
		hideId = hideIdColumn;
		$(&quot;.ms-viewheadertr th&quot;).each(function(){
			if($(this).find('table:first').attr('name')=='ID'){
				IDcolIndex = $(this).attr('cellIndex');
				// Hide ID column
				if(hideId){
					$(this).addClass('dummyHideClass');
				}
			}
		});	
	}
	
	if(typeof(IDcolIndex)=='undefined'){
		alert(&quot;The ID column must be in the view.nYou may hide it in the script call by setting the argument &quot;hideIdColumn&quot; to true.&quot;);
	}

	if(typeof(arrTH)=='undefined'){
		arrTH = [];
		$(&quot;.ms-viewheadertr th&quot;).each(function(){
		var colIndex = $(this).attr('cellIndex');
			var table = $(this).find('table');
			if(table.attr('name')!=undefined){	
				var fldIntName = table.attr('name');
				var fldType = table.attr('fieldtype');			
				if($.inArray(fldIntName,arrToEdit)&gt;-1){
					arrTH.push({'colIndex':colIndex,'fldType':fldType,'fldIntName':fldIntName});
				}
			}
		});	
	}

	addCustomEditFunction(arrTH);
	// Hide ID column if specified
	if(hideId){
		$(&quot;.dummyHideClass&quot;).hide();
	}
}

function addCustomEditFunction(arrToInclude){
	$(&quot;table.ms-listviewtable tbody&quot;).each(function(){
		if($(this).attr('id').match('aggr')==null){
			$(this).find(&quot;tr:has(td.ms-vb2)[beenthere!='1']&quot;).each(function(){
				$(this).attr('beenthere','1');	
				var itemID = $(this).find(&quot;&gt;td[cellIndex=&quot; + IDcolIndex + &quot;]&quot;).text();
				// Hide ID column
				if(hideId){
					$(this).find(&quot;td[cellIndex=&quot;+IDcolIndex+&quot;]&quot;).addClass('dummyHideClass');
				}
				var pTR = $(this);	
				$.each(arrToInclude,function(idx,obj){		
					var col = obj['colIndex'];
					var type = obj['fldType'];
					var intName = obj['fldIntName'];		
					var TD = pTR.find(&quot;&gt;td[cellIndex=&quot; + col + &quot;]&quot;);
					var currVal = TD.text();
					// Add onclick and append image
					TD.dblclick(function(){editCurrentLine(type,itemID,intName)})
						.attr({'id':'customEdit_'+intName+&quot;_&quot;+itemID,'fieldType':type})
						.css({'cursor':'pointer'});
					if(type=='Number' || type=='Currency'){
						TD.find('div').append(&quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&quot;);
					}else if(type=='User'){
						if(TD.find('tr').length&gt;0){
							TD.find('tr:first').append(&quot;&lt;td&gt;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/td&gt;&quot;);
						}else{
							TD.append(&quot;&lt;div style='padding-left:12px'&gt;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/div&gt;&quot;);
						}
					}else{
						TD.append(&quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&quot;);
					}		
				});
			});
		}else if($(this).attr('id').match('aggr')!=null &amp;&amp; $(this).attr('beenthere')!='1' &amp;&amp; hideId){
			$(this).attr('beenthere','1');
			$(this).find(&quot;td[cellIndex=&quot;+IDcolIndex+&quot;]&quot;).addClass('dummyHideClass');
		}	
	});
}

function editCurrentLine(type,id,intName){
var currField = $(&quot;#customEdit_&quot; + intName+&quot;_&quot;+id);
var currVal = currField.text();
// Remove &amp;nbsp;
currVal = $.trim(currVal.replace(/xA0/g,''));
	if(type=='DateTime'){
		if(currVal.indexOf(' ')&gt;-1){
			currVal = currVal.substring(0,currVal.indexOf(' ')); // Strip off any &quot;time-value&quot;
		}	
		if($(&quot;#customEditInput_&quot;+intName+&quot;_&quot;+id).length==0){
			currField.css({'width':currField.width()}).html(&quot;&lt;div&gt;&amp;nbsp;&lt;a title='Cancel' href='javascript:' onclick='javascript:cancelCustomSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;)'&gt;cancel&lt;/a&gt;&amp;nbsp;|&amp;nbsp;&quot; +
			&quot;&lt;a title='Clear' href='javascript:' onclick='javascript:customSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;,&quot; + true + &quot;)'&gt;clear&lt;/a&gt;&lt;br&gt;&quot; +
			&quot;&lt;input class='ms-input' id='customEditInput_&quot;+intName+&quot;_&quot;+id+&quot;' style='width:1px;height:1px;border:0px' value='&quot; + currVal + &quot;' /&gt;&lt;/div&gt;&quot;);
			// Datepicker
			$(&quot;#customEditInput_&quot; + intName+&quot;_&quot;+id).datepicker({ 
				dateFormat: dateFormat,
		    	changeMonth: true,
		   		changeYear: true,
		   		showButtonPanel: true,
		   		onSelect: function(dateText, inst){		   			
		   			customSaveLine(intName,id,currVal);
		   		}		   			
		   	}).datepicker('show');
		}
	}else if(type=='Text' || type=='Number' || type=='Currency'){
		if($(&quot;#customEditInput_&quot;+intName+&quot;_&quot;+id).length==0){
			currField.css({'width':currField.width()}).html(&quot;&lt;div&gt;&amp;nbsp;&lt;a title='Save' href='javascript:' onclick='javascript:customSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;)'&gt;save&lt;/a&gt;&amp;nbsp;|&amp;nbsp;&quot; +
				&quot;&lt;a title='Cancel' href='javascript:' onclick='javascript:cancelCustomSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;)'&gt;cancel&lt;/a&gt;&lt;br&gt;&quot; +
				&quot;&lt;input class='ms-input' id='customEditInput_&quot;+intName+&quot;_&quot;+id+&quot;' style='width:99%' value='&quot; + currVal + &quot;' /&gt;&lt;/div&gt;&quot;);								
			// Focus on the input
			setTimeout(function(){currField.find('input').focus();},250);		
			// Add keyup/down function
			currField.find('input').keyup(function(e){
			// If number - restrict input to numbers only - may need a little more tweaking
				if(type=='Number' || type=='Currency'){
				var reg = new RegExp(&quot;[^0-9|\&quot; + decimalSeparator + &quot;]&quot;,'g');
					var thisVal = $(this).val().replace(reg,'');
					$(this).val(thisVal);					
				}
			}).keydown(function(e){
				// Enter = save
				if(e.keyCode==13){
					customSaveLine(intName,id,currVal)
				}
			}).keyup();							
		}
	}else if(type=='Boolean'){
		if($(&quot;#customEditInput_&quot;+intName+&quot;_&quot;+id).length==0){		
			if(currVal=='' || currVal.toLowerCase().indexOf('n')&gt;-1){ // 'n' is found in 'No' and in Norwegian 'Nei'
				chk='';
			}else{
				chk='checked';
			}			
			currField.css({'width':currField.width()}).html(&quot;&lt;div&gt;&amp;nbsp;&lt;a title='Cancel' href='javascript:' onclick='javascript:cancelCustomSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;)'&gt;cancel&lt;/a&gt;&lt;br&gt;&quot; +
				&quot;&lt;input type='checkbox' id='customEditInput_&quot;+intName+&quot;_&quot;+id+&quot;' &quot; + chk + &quot;/&gt;&lt;/div&gt;&quot;);								
			$(&quot;#customEditInput_&quot;+intName+&quot;_&quot;+id).click(function(){
				customSaveLine(intName,id,currVal)
			}).focus();					
		}
	}else if(type=='User'){
		if($(&quot;#customEditInput_&quot;+intName+&quot;_&quot;+id).length==0){
			currField.css({'width':currField.width()}).html(&quot;&lt;div&gt;&amp;nbsp;&lt;a title='Cancel' href='javascript:' onclick='javascript:cancelCustomSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;)'&gt;cancel&lt;/a&gt;&amp;nbsp;|&amp;nbsp;&quot; +
				&quot;&lt;a title='Clear' href='javascript:' onclick='javascript:customSaveLine(&quot;&quot;+intName+&quot;&quot;,&quot;&quot;+id+&quot;&quot;,&quot;&quot;+currVal+&quot;&quot;,&quot; + true + &quot;)'&gt;clear&lt;/a&gt;&lt;br&gt;&quot; +
				&quot;&lt;input title='Type into the textfield to get a list of users' class='ms-input' id='customEditInput_&quot;+intName+&quot;_&quot;+id+&quot;' style='width:99%' value='&quot; + currVal + &quot;' /&gt;&lt;/div&gt;&quot;);								
			// Autocomplete
			if(typeof(allUsers)=='undefined'){
				allUsers = getUsers();
			}
			currField.find('input').autocomplete({
				source: allUsers,
				select: function(event, ui){
					$(this).attr('hiddenVal',ui.item.userID);
					customSaveLine(intName,id,currVal);									
					return false;
				}		
			});
			// Focus on the input
			setTimeout(function(){currField.find('input').focus();},250);						
		}
	}
}

function getUsers(){
	var query = &quot;&lt;Where&gt;&lt;And&gt;&lt;IsNotNull&gt;&lt;FieldRef Name='EMail' /&gt;&lt;/IsNotNull&gt;&quot; +
				&quot;&lt;Eq&gt;&lt;FieldRef Name='ContentType' /&gt;&lt;Value Type='Text'&gt;Person&lt;/Value&gt;&lt;/Eq&gt;&lt;/And&gt;&lt;/Where&gt;&quot; +
				&quot;&lt;OrderBy&gt;&lt;FieldRef Name='Title' Ascending='TRUE'/&gt;&lt;/OrderBy&gt;&quot;;
	wsBaseUrl = userListBaseUrl + '/_vti_bin/';	
	var res = queryItems(userListGuid,query,['ID','Title','Name','EMail','ContentType']); 
    var ret = [];
    $.each(res.items,function(idx,item){ 	
    	ret.push({label:item['Title']+&quot;&lt;br&gt;&quot;+item['EMail']+&quot;&lt;br&gt;&quot;+item['Name'],value:item['Title'],userID:item['ID']});	
    });
    return ret;    
}

function cancelCustomSaveLine(intName,id,currVal){
var pTD = $(&quot;#customEdit_&quot;+intName+&quot;_&quot;+id);
var type = pTD.attr('fieldType');
	if(type=='Number' || type=='Currency'){
		pTD.html(&quot;&lt;div align='right'&gt;&quot; + currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/div&gt;&quot;);
	}else if(type=='User'){
		pTD.html(&quot;&lt;div style='padding-left:12px'&gt;&quot; + currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/div&gt;&quot;);
	}else{
		pTD.html(currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' src='&quot; + hoverImgSrc + &quot;'&gt;&quot;);		
	}
}

function customSaveLine(intName,id,currVal,clear){
wsBaseUrl = ctx.HttpRoot + '/_vti_bin/';
listGuid = ctx.listName;

if(clear==undefined)clear=false;
var pTD = $(&quot;#customEdit_&quot;+intName+&quot;_&quot;+id);
	var type = pTD.attr('fieldType');
	var inpField = pTD.find('input');
	// Determine type and get value
	if(type=='Boolean'){
		var bSplit = boolYesNoText.split('|');
		var newVal = inpField.attr('checked');
		if(newVal){
			newVal='1';
			newValText=bSplit[0];
		}else{
			newVal='0';
			newValText=bSplit[1];
		}		
	}else{	
		var newVal = $.trim(inpField.val());
	}
	// Check if value has changed	
	if(newVal!=currVal || clear){
		var data = {};
		if(type=='DateTime'){
			if(clear){
				data[intName] = '';
				newVal = '';
			}else{
				var isoDate = parseISO8601Date(newVal);
				data[intName] = isoDate;
			}
		}else if(type=='User'){
			if(clear){
				data[intName] = &quot;&quot;;
				newVal = '';
			}else{
				data[intName] = inpField.attr('hiddenVal');
			}
		}else{
			data[intName] = newVal;
		}
		// Write back data
		var res = updateItem(listGuid,id,data);
		// Success or failure
		if(res.success){ // Save success
			if(type=='Number'){
				pTD.html(&quot;&lt;div align='right'&gt;&quot; + newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='Saved' src='&quot; + successImgSrc + &quot;' width='14' height='14' border='0'&gt;&lt;/div&gt;&quot;);
			}else if(type=='Boolean'){
				pTD.html(newValText + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='Saved' src='&quot; + successImgSrc + &quot;' width='14' height='14' border='0'&gt;&quot;);
			}else if(type=='User'){
				pTD.html(&quot;&lt;div style='padding-left:12px'&gt;&quot; + newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='Saved' src='&quot; + successImgSrc + &quot;' width='14' height='14' border='0'&gt;&lt;/div&gt;&quot;);
			}else{
				pTD.html(newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='Saved' src='&quot; + successImgSrc + &quot;' width='14' height='14' border='0'&gt;&quot;);
			}
		}else{ // Failed to save
			if(type=='Number'){
				pTD.html(&quot;&lt;div align='right'&gt;&quot; + currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' style='vertical-align:middle' title='&quot; + res.errorText + &quot;' src='&quot; + failureImgSrc + &quot;' width='14' height='14' border='0'&gt;&lt;/div&gt;&quot;);
			}else if(type=='User'){
				pTD.html(&quot;&lt;div style='padding-left:12px'&gt;&quot; + currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + res.errorText + &quot;' src='&quot; + failureImgSrc + &quot;' width='14' height='14' border='0'&gt;&lt;/div&gt;&quot;);
			}else{
				pTD.html(currVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + res.errorText + &quot;' src='&quot; + failureImgSrc + &quot;' width='14' height='14' border='0'&gt;&quot;);
			}
		}
	}else{ // If value is not changed, restore currVal
		if(type=='Number'){
			pTD.html(&quot;&lt;div align='right'&gt;&quot; + newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/div&gt;&quot;);
		}else if(type=='User'){
			pTD.html(&quot;&lt;div style='padding-left:12px'&gt;&quot; + newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&lt;/div&gt;&quot;);
		}else{
			pTD.html(newVal + &quot;&amp;nbsp;&lt;img style='vertical-align:middle' title='&quot; + hoverImgMouseOver + &quot;' src='&quot; + hoverImgSrc + &quot;'&gt;&quot;);
		}
	}
}

function parseISO8601Date(str){
	if(str!=''){
	var strSplit = str.split(dateFormat.charAt(1));
		switch(dateFormat){
			case 'm/d/yy':
				return strSplit[2] + &quot;-&quot; + strSplit[0] + &quot;-&quot; + strSplit[1] + &quot;T12:00:00Z&quot;; // set's clock to 12:00 PM
			break;
			case 'd.m.yy':
				return strSplit[0] + &quot;-&quot; + strSplit[2] + &quot;-&quot; + strSplit[1] + &quot;T12:00:00Z&quot;; // set's clock to 12:00 PM
			break;
		}
	}else{
		return '';
	}		
}

// Attaches a call to the function to the &quot;expand grouped elements function&quot; for it to function in grouped listview's
function ExpGroupRenderData(htmlToRender, groupName, isLoaded){
	var tbody=document.getElementById(&quot;tbod&quot;+groupName+&quot;_&quot;);
	var wrapDiv=document.createElement(&quot;DIV&quot;);
	wrapDiv.innerHTML=&quot;&lt;TABLE&gt;&lt;TBODY id=&quot;tbod&quot;+groupName+&quot;_&quot; isLoaded=&quot;&quot;+isLoaded+&quot;&quot;&gt;&quot;+htmlToRender+&quot;&lt;/TBODY&gt;&lt;/TABLE&gt;&quot;;
	tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
initCustomEditFunction();
}

// Size of datepicker
$(&quot;body&quot;).css({'font-size':'55%'}); 

Save this code as “EditInListView.js”, and upload to your scriptlibrary as shown above.

Note: Due to the number of DOM-modifications there might be a performance issue (prolonged load time of the page) when used.

To minimize the issue you can try:

  • Limit the number of columns this feature is applied to
  • Limit the item count in each page
  • Group your items and set “By default, show groupings: Collapsed”

Test it in your environment to find what settings suites you.

Ask if something is unclear.

Regards
Alexander

Link to fill user login name in people picker

By request from Charlie:

Hi:
Similar to the “Date Picker Clicker”, do you know if I could click a link and the users login name would fill a People Picker (person or group)?… on a newform or editform?

Charlie Epes

Here is a solution for inserting current user’s login name in a people picker by clicking on a link above the field.

IMG

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The file “AccessUserProfileInWSS.js” is found here. Read the article as you have to set your “user list GUID” in the script.

The code for the file “SetPeoplePicker.js” is found below.

Add a CEWP below – it is essential that it is placed below – your list-form as described here, and add this code:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/AccessUserProfileInWSS.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/SetPeoplePicker.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// Array of fields to add this function to
  var arrOfFields = ['MyPeoplePicker','AnotherPeoplePicker'];
  initSetPeoplePicker(arrOfFields);
&lt;/script&gt;

The code for the file “SetPeoplePicker.js” looks like this:

/* Set people picker to current user login by click on a link above the field
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.0
 * LastMod: 04.12.2009
 * ---------------------------------------------
 * Include reference to jquery - http://jquery.com
 *  interaction.js - http://spjslib.codeplex.com/
 *  stringBuffer.js - http://spjslib.codeplex.com/
 *  AccessUserProfileInWSS.js - https://spjsblog.com/2009/09/20/accessing-user-profile-information-in-wss-3-0-with-javascript/
 * ---------------------------------------------
 * Call from a CEWP below the list form in NewForm or EditForm like this:
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/AccessUserProfileInWSS.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/SetPeoplePicker.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
	// Array of fields to add this function to
	  var arrOfFields = ['MyPeoplePicker','AnotherPeoplePicker'];
	  initSetPeoplePicker(arrOfFields);
	&lt;/script&gt;
*/

// Build the user information object
var ui = getUserInfo();

function initSetPeoplePicker(arr){
if(typeof(fields)=='undefined')fields = init_fields();
	$.each(arr,function(idx,item){
		// Check if FieldInternalName is correct
		if(fields[item]==undefined)return;
		// Add clickable link over field - ui.Title=DisplayName of current user
		$(fields[item]).find('.ms-formbody').prepend(&quot;&lt;div&gt;&lt;a title=&quot;Set field's value to &quot; + ui.Title + &quot;&quot; href=&quot;javascript:setPeoplePicker('&quot; + item + &quot;')&quot;&gt;[&quot; + ui.Title + &quot;]&lt;/a&gt;&lt;/div&gt;&quot;);	
	});
}

function setPeoplePicker(FieldInternalName){
var field = $(fields[FieldInternalName])
	if(field.find('.ms-inputuserfield:visible').length&gt;0){	
		// IE
		field.find('.ms-inputuserfield').html(ui.Name);
		field.find('img:first').click();	
	}else{
		// FF
		field.find(&quot;textarea:first&quot;).val(ui.Name);
	}
}

function init_fields(){
var res = {};
$(&quot;td.ms-formbody&quot;).each(function(){
if($(this).html().indexOf('FieldInternalName=&quot;')&lt;0) return; 
var start = $(this).html().indexOf('FieldInternalName=&quot;')+19;
var stopp = $(this).html().indexOf('FieldType=&quot;')-7; 
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}

Save this code as “SetPeoplePicker.js”, and upload to the script library as shown above.

Ask if something is unclear.

Regards
Alexander