Set datefield to first day of month, today’s date or last day of month

Change log
April 9, 2014
Updated the code example to fix some quotes that was formatted wrong due to migrating from my old server a long time ago. I also updated the function init_fields in the example.

I got this request from Charlie:

Hi Alexander:
Is it possible to add a clickable “button” or icon next to a date picker that would insert “Today’s Date” into the field box?

Yes it is. Here’s a solution for setting either “first day of month”, “today” or “last day of month” by clicking on a link above the date picker, or by pressing “F”, “T” or “L” in the date picker field itself.

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 code for the file “DateFieldValueOnClick.js” is found below.

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

<script type="text/javascript" src="/Javascript/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="/Javascript/DateFieldValueOnClick.js"></script>
<script type="text/javascript">
	// Array of fields to add this function to
	var arrOfFields = ['MyDateColumn1','MyDateColumn2'];
	setDateFieldValue(arrOfFields);
</script>

The variable “arrOfFields” is an array of the FieldInternalNames of all the date picker-fields you want to add this feature to.

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

/* Set datepicker value to "first day of month", "today" or "last day if month"
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1
 * LastMod: 09.04.2014 
*/

function setDateFieldValue(arrOfFieldInternalNames){
if(typeof fields === 'undefined')fields = init_fields_v2();
// Get today's date
var today = new Date();
var m = today.getMonth()+1;
var d = today.getDate();
var y = today.getFullYear();
// Find last day in month
var lastDayRaw = new Date(y,m,0);
var dLast = lastDayRaw.getDate();

// Format your date
var T = m + "/" + d + "/" + y; // Today
var F = m + "/" + 1 + "/" + y; // First day in month
var L = m + "/" + dLast + "/" + y; // Last day in month
var fieldMouseoverTitle = "Press \"F\" for " + F + ", \"T\" for " + T + ", \"L\" for " + L;
$.each(arrOfFields,function(idx,item){
if(fields[item]==undefined)return;
$(fields[item]).find('input').attr('title',fieldMouseoverTitle).keyup(function(e){
if(e.keyCode==70){
setDate(item,F);
}
if(e.keyCode==84){
setDate(item,T);
}
if(e.keyCode==76){
setDate(item,L);
}
}).parents('td.ms-formbody:first').prepend("<div><span title='Set field value to \"" + F + "\"' style='cursor:pointer;' onclick=setDate(\"" + item + "\",\"" + F +"\")>First</span> | <span title='Set field value to \"" + T + "\"' style='cursor:pointer;' onclick=setDate(\"" + item + "\",\"" + T + "\")>Today</span> | <span title='Set field value to \"" + L + "\"' style='cursor:pointer;' onclick='setDate(\"" + item + "\",\"" + L +"\")'>Last</span></div>");
});
}

function setDate(fieldName,date){
	$(fields[fieldName]).find('input').val(date);
}

function init_fields_v2(){
	var res = {};
	$("td.ms-formbody").each(function(){
	var myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);	
		if(myMatch!=null){
			// Display name
			var disp = myMatch[1];
			// FieldInternalName
			var fin = myMatch[2];
			// FieldType
			var type = myMatch[3];
			if(type=='SPFieldNote'){
				if($(this).find('script').length>0){
					type=type+"_HTML";
				}else if($(this).find("div[id$='TextField_inplacerte']").length>0){
					type=type+"_EHTML";
				}				
			}
			if(type==="SPFieldLookup"){
				if($(this).find("input").length>0){
					type=type+"_Input";
				}
			}
			// HTML Calc
			if(type==='SPFieldCalculated' && $(this).text().match(/(<([^>]+)>)/ig)!==null){
				$(this).html($(this).text());
			}		
			// Build object
			res[fin] = this.parentNode;
			$(res[fin]).attr('FieldDispName',disp);
			$(res[fin]).attr('FieldType',type);
		}		
	});
	return res;
}

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

Ask if something is unclear.

Regards
Alexander

Dynamic expand/collapse fields or array of fields by multi select

August 18, 2014 Brushed up the code example as it had some faulty quotes due to an error in the migration of the contents when I moved the blog some time ago.


25.03.2011 Fixed a bug in the DispForm code – thanks to Brian for noticing.


13.09.2010 Updated to support shared fields in the arrays – as requested by Larry.


This is a follow up on this article. You must read this article to get the basics before proceed with this one.

I will here give an example on how to use a multi select in stead of the single choice dropdown used in the previous article.

The only modification to the form from the previous , is the field “MySelect” which now should be changed to “Checkboxes (allow multiple selections)”.

The code for NewForm and EditForm should now be like this:

<!-- The jQuery version must be 1.6 or above -->
<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">

var fields = init_fields_v2();
// Arrays of fields to show or hide
var arrRed = ['ShowIfRed1','ShowIfRed2'];
var arrBlue = ['ShowIfBlue1','ShowIfBlue2'];

// Multiselect
$(fields['MySelect']).find('input').each(function(i){
	// On page load
	if(i==0){ // call this only once
		multiSelectdynamicDisplay($(this));
	}
	// Add onclick
	$(this).click(function(){
		multiSelectdynamicDisplay($(this));
	});
});

function multiSelectdynamicDisplay(inp){
	var objChecked = {};
	var arrToHide = [];
	var arrToShow = [];
	var inpAll = inp.parents('td.ms-formbody:first').find('input');
	$.each(inpAll,function(){
		objChecked[$(this).next().text()] = $(this).prop('checked');
	});
	// Check each option
	if(objChecked['Red']){
		arrToShow = arrToShow.concat(arrRed);
	}else if(!objChecked['Red']){
		arrToHide = arrToHide.concat(arrRed);
	}
	
	if(objChecked['Blue']){
		arrToShow = arrToShow.concat(arrBlue);
	}else if(!objChecked['Blue']){
		arrToHide = arrToHide.concat(arrBlue);
	}	
	if(objChecked['Yellow']){
		//alert("No array defined for "Yellow"");
	}else if(!objChecked['Yellow']){
		// Has no array defined
	}
	// Hide
	toggleArr(arrToHide,true);
	// Show
	toggleArr(arrToShow,false);
}

function toggleArr(arr,hide){
	if(hide){
		for(i=0;i<arr.length;i++){
			$(fields[arr[i]]).hide();
		}
	}else if(!hide){
		for(i=0;i<arr.length;i++){
			$(fields[arr[i]]).show();
		}
	}
}

function init_fields_v2(){
	var res = {};
	$("td.ms-formbody").each(function(){
	var myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);	
		if(myMatch!=null){
			// Display name
			var disp = myMatch[1];
			// FieldInternalName
			var fin = myMatch[2];
			// FieldType
			var type = myMatch[3];
			if(type=='SPFieldNote'){
				if($(this).find('script').length>0){
					type=type+"_HTML";
				}else if($(this).find("div[id$='TextField_inplacerte']").length>0){
					type=type+"_EHTML";
				}				
			}
			if(type==="SPFieldLookup"){
				if($(this).find("input").length>0){
					type=type+"_Input";
				}
			}
			// HTML Calc
			if(type==='SPFieldCalculated' && $(this).text().match(/(<([^>]+)>)/ig)!==null){
				$(this).html($(this).text());
			}		
			// Build object
			res[fin] = this.parentNode;
			$(res[fin]).attr('FieldDispName',disp);
			$(res[fin]).attr('FieldType',type);
		}		
	});
	return res;
}
</script>

The code for DispForm should now be like this:

<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
var fields = init_fields_v2();
// Arrays of fields to show or hide
var arrRed = ['Title','ShowIfRed1','ShowIfRed2'];
var arrBlue = ['Title','ShowIfBlue1','ShowIfBlue2'];

// Hide all onload
var arrToHide = [];
arrToHide = arrToHide.concat(arrRed,arrBlue);
toggleArr(arrToHide,true);

// Find the ones selected
var c = $(fields['MySelect']).find('.ms-formbody').text().replace(/xA0/g,'');
cSplit = c.split('; ');
$.each(cSplit,function(idx,color){
	dynamicDisplay($.trim(color));
});

function dynamicDisplay(color){
var arrToShow = [];
	if(color=='Red'){
		arrToShow = arrToShow.concat(arrRed);
	}	
	if(color=='Blue'){
		arrToShow = arrToShow.concat(arrBlue);
	}	
	if(color=='Yellow'){
		// No array defined
	}
	// Show
	toggleArr(arrToShow,false);
}

function toggleArr(arr,hide){
  if(hide){
    for(i=0;i<arr.length;i++){
      $(fields[arr[i]]).hide();
    }
  }else if(!hide){
    for(i=0;i<arr.length;i++){
      $(fields[arr[i]]).show();
    }
  }
}

function init_fields_v2(){
	var res = {};
	$("td.ms-formbody").each(function(){
	var myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);	
		if(myMatch!=null){
			// Display name
			var disp = myMatch[1];
			// FieldInternalName
			var fin = myMatch[2];
			// FieldType
			var type = myMatch[3];
			if(type=='SPFieldNote'){
				if($(this).find('script').length>0){
					type=type+"_HTML";
				}else if($(this).find("div[id$='TextField_inplacerte']").length>0){
					type=type+"_EHTML";
				}				
			}
			if(type==="SPFieldLookup"){
				if($(this).find("input").length>0){
					type=type+"_Input";
				}
			}
			// HTML Calc
			if(type==='SPFieldCalculated' && $(this).text().match(/(<([^>]+)>)/ig)!==null){
				$(this).html($(this).text());
			}		
			// Build object
			res[fin] = this.parentNode;
			$(res[fin]).attr('FieldDispName',disp);
			$(res[fin]).attr('FieldType',type);
		}		
	});
	return res;
}
</script>

This article is, as mentioned above, a follow up on anther article. Read the previous article to get the basics.

Ask if anything is unclear.

Regards
Alexander

Hide menu items in list view toolbar and views in view selector

This is a short one on how to remove menu items from the “New”, “Actions”, “Settings”, and “List view’s” menu in a list or document library.

This method requires a CEWP added below the list view web part with the code, and is a “per view code” which must be added to every view where the menu items shall be removed.

I will first give a list of the “names” of the “standard” elements found in the list view toolbar menu and list view menu, then i will give an example of how to remove selected items from the menu’s.

The menu items in the “Actions”, and the “Settings” menu has these “names” (the part of the ID used to locate them):

  • _EditInGridButton
  • _ExportToSpreadsheet
  • _ExportToDatabase
  • _ViewRSS
  • _SubscribeButton
  • _AddColumn
  • _AddView
  • _ListSettings

The “New” menu (the one containing all the “New-button” for all your content types) uses “_New0” for the first “_New1” for the next and so on.

The “view’s” menu uses these names for the “standard” menu items:

  • _DefaultView
  • _ModifyView
  • _CreateView

The custom made views uses the “DisplayName” of the view to identify it.

Code for hiding elements in “New”, “Actions”, “Settings” and “View’s” menu:

&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;&gt;
/* Hide menu items in list view toolbar and views in view selector
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.0
 * LastMod: 26.11.2009
 * ---------------------------------------------
 * Include reference to:
 *  jquery - http://jquery.com
 * ---------------------------------------------
*/

// Remove menu items - in this example all items in the &quot;Settings&quot; menu are removed (and therefore the menu is removed)
// This is the array of menu items to hide
var arrOfMenuItemsToHide = ['_EditInGridButton','_AddView','_AddColumn','_ListSettings'];
$.each(arrOfMenuItemsToHide,function(idx,item){	
	$(&quot;*[id$='&quot; + item + &quot;']&quot;).next().andSelf().remove();
});

// Views - hides &quot;Modify&quot;, &quot;Create&quot; and the custom made &quot;My Test View&quot;
// This is the array of view's or to hide
var arrOfViewsToHide = ['_ModifyView','_CreateView','My Test View'];
$.each(arrOfViewsToHide,function(idx,item){	
	$.each($(&quot;*[id$='_ViewSelectorMenu']&quot;).children(),function(){
		if($(this).attr('id').match(item) || $(this).attr('text')==item){
			$(this).next().andSelf().remove();
		}
	});
});

// Remove the menu if all menu items are removed
$(&quot;.ms-menutoolbar&quot;).find('menu').each(function(){
	if($(this).children().length==0){
		$(this).parents('td.ms-toolbar:first').prev().andSelf().remove();
	}
});
&lt;/script&gt;

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

This code can be adapted to hide elements based on group membership of the logged in user. I have written about a method to get the group collection for a user and to verify group membership here Showing or hiding list fields based on membership in a SharePoint group.

Ask if something is unclear.

Regards
Alexander

Count groups in grouped list view

This is a short one on counting groups in a grouped list view like this (group count in the list view toolbar):
IMG

Note: This counts only visible groups. If you set the “Number of groups to display per page” in the list view settings you will get max that number of groups when counting. An alternate approach would be to query the list for the total number of unique items based on the items the view is grouped by.

Add a CEWP below the list view with this code (alter the location of jQuery as needed):

&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;&gt;

// Grouping on level 1
var CountGrouping1 = $(&quot;.ms-listviewtable td.ms-gb&quot;).length;
var NameGrouping1 = $(&quot;.ms-listviewtable td.ms-gb:first a:eq(1)&quot;).text();

// Grouping on level 2
var CountGrouping2 = $(&quot;.ms-listviewtable td.ms-gb2&quot;).length;
var NameGrouping2 = $(&quot;.ms-listviewtable td.ms-gb2:first a:eq(1)&quot;).text();

var str = NameGrouping1 + &quot;'s: &quot; + CountGrouping1 + &quot; | &quot; + NameGrouping2 + &quot;'s: &quot; + CountGrouping2;

$(&quot;td.ms-toolbar[width='99%']&quot;).append(&quot;&lt;div class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'&gt;&quot; + str + &quot;&lt;/div&gt;&quot;);

&lt;/script&gt;

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

Ask if something is unclear.

Regards
Alexander

SharePoint list’s or document library’s: Primary key in selected field

05.01.2010 Small update to hide the “OK-button” if the “keyIsNotUniqueCount” is greater than 0.
25.11.2009 Small update to the script for placing the image correctly when used with the headings script.

In this article I will give you a solution for adding “primary key support” to a list or a document library with JavaScript.

This will work with fields of type “Single line of text”, “Multiple lines of text (Plain text)” and “Number”. Note that if you activate this feature for a field of type “Number”, it strips off all other than numbers 0-9. No spaces, commas or periods are allowed. This is done to avoid conflicts based on different formats used in different language settings.

You can enable this feature for more than one field in a list or document library.

Note: This does only work in NewForm and EditForm, not if edited in DataSheet.

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 sourcecode for the file “PrimaryKey.js” is found below.

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

The last file in this screen-shot is the Right click and select Save picture as. Right click on the image and select “Save picture as”.

Add a CEWP below your list-form in NewForm and EditForm.
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/PrimaryKey.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
   // Enables &quot;Primary key&quot; on the &quot;Title-field&quot;
   ensurePrimaryKey('Title','','/test/English/Javascript/PrimaryKey.gif','');
&lt;/script&gt;

Your “Title-field” will look like this:
IMG

The check is attached to the “blur” event, and triggers when you removes focus on the field. If you try to add a “non-unique-value” to that field, you end up with this warning, and cannot save the list item:
IMG

If used with a field of type “Number”, the code strips away spaces, commas and periods as described above.

Parameters explained:

  • FieldInternalName: FieldInternalName of the field to add this feature to
  • PrimaryKeyViolationWarning: [optional] The text shown under the field if the key is not unique.
  • keyImageSrc: [optional] Image source for the “key.image” added before the field label. If not supplied it default’s to “/_layouts/images/prf16.gif”.
  • PrimaryKeyHoverImageText: [optional] Description text if hovered over the “key-image”.

Sourcecode for the file “PrimaryKey.js”:

/* Primary key for lists or Document libraries
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.1
 * LastMod: 05.01.2010
 * ---------------------------------------------
 * Include reference to:
 *  jquery - http://jquery.com
 *  interaction.js - http://spjslib.codeplex.com/
 *  stringBuffer.js - http://spjslib.codeplex.com/
 * ---------------------------------------------
 * Call from a CEWP below the list form in NewForm orEditForm 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/PrimaryKey.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
		// Enables primary key for the &quot;Title-field&quot;
		ensurePrimaryKey('Title','This field's value has to be unique for this list.','/test/English/Javascript/PrimaryKey.gif','Primary key is enabled for this field');
	&lt;/script&gt;
*/

if(typeof(fields)=='undefined')fields = init_fields();
function ensurePrimaryKey(FieldInternalName,PrimaryKeyViolationWarning,keyImageSrc,PrimaryKeyHoverImageText){
	if(fields[FieldInternalName]!=undefined){
		listDisplayName = $(&quot;h2.ms-pagetitle a&quot;).text();
		keyIsNotUniqueCount = 0;
		// If PrimaryKeyViolationWarning is not defined, default to this text
		if(PrimaryKeyViolationWarning==undefined || PrimaryKeyViolationWarning==''){
			var PrimaryKeyViolationWarning = &quot;This field's value has to be unique for this list.&quot;;
		}
		// If PrimaryKeyHoverImageText is not defined, default to this text
		if(PrimaryKeyHoverImageText==undefined || PrimaryKeyHoverImageText==''){
			var PrimaryKeyHoverImageText = &quot;Primary key is enabled for this field&quot;;
		}
		if(keyImageSrc==undefined || keyImageSrc==''){
			keyImageSrc = &quot;/_layouts/images/prf16.gif&quot;;
		}
		// If number - trim off all spaces, commas and periods
		if($(fields[FieldInternalName]).html().match('SPFieldNumber')!=null){
			$(fields[FieldInternalName]).find(':input').keyup(function(e){
				var currVal = $(this).val();
				$(this).val(currVal.replace(/[^0-9]/g,''));
			});
		}
		
		// Determine where to put the image - if used with the Heading-script		
		if($(fields[FieldInternalName]).find(&quot;h3:has('div')&quot;).length&gt;0){
			var insertImageHere = 'h3 div';
		}else{
			var insertImageHere = 'h3';
		}
		
		// Add blur function
		$(fields[FieldInternalName]).find(':input').blur(function(){
			// Check if input value is unique in this list
			checkPrimaryKey(FieldInternalName,$(this),PrimaryKeyViolationWarning);
		})
		// Add key image before label
		.parents('tr:first').find(insertImageHere)
		.prepend(&quot;&lt;img title='&quot; + PrimaryKeyHoverImageText + &quot;' src='&quot; + keyImageSrc + &quot;'&gt;&quot;);
	}
}

function checkPrimaryKey(FIName,keyField,warningText){
wsBaseUrl = L_Menu_BaseUrl + '/_vti_bin/';
var ItemId = getIdFromFormAction(); // Returns 0 if NewForm
var keyFieldVal = keyField.val().replace(/&amp;/g,'&amp;amp;');

	if(ItemId==0){ // NewForm
		var query = &quot;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name='&quot; + FIName + &quot;'/&gt;&lt;Value Type='Text'&gt;&quot; + keyFieldVal + &quot;&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&quot;;
	}else{ // EditForm - skip current ID
		var query = &quot;&lt;Where&gt;&lt;And&gt;&lt;Eq&gt;&lt;FieldRef Name='&quot; + FIName + &quot;'/&gt;&lt;Value Type='Text'&gt;&quot; + keyFieldVal + &quot;&lt;/Value&gt;&lt;/Eq&gt;&quot; +
					&quot;&lt;Neq&gt;&lt;FieldRef Name='ID'/&gt;&lt;Value Type='Counter'&gt;&quot; + ItemId + &quot;&lt;/Value&gt;&lt;/Neq&gt;&lt;/And&gt;&lt;/Where&gt;&quot;;
	}
	var res = queryItems(listDisplayName,query,['ID']);
	if(res.count==-1){
		alert(&quot;An error occured in the query:n&quot; + query);
	}else if(res.count&gt;0){
		keyIsNotUniqueCount = keyIsNotUniqueCount + 1;
		keyField.parents('td:first').find(&quot;.customPrimaryKeyAlert&quot;).remove();
		keyField.parents('td:first').append(&quot;&lt;div class='customPrimaryKeyAlert' style='color:red'&gt;&quot; + warningText + &quot;&lt;/div&gt;&quot;);
	}else{
		keyField.parents('td:first').find(&quot;.customPrimaryKeyAlert&quot;).remove();
		if(keyIsNotUniqueCount&gt;0){
			keyIsNotUniqueCount = keyIsNotUniqueCount - 1;
		}
	}
	// Hide button
	if(keyIsNotUniqueCount&gt;0){
		$(&quot;input[id$='SaveItem']&quot;).hide();
	}else{
		$(&quot;input[id$='SaveItem']&quot;).show();
	}
}

// This function gets the list item ID from the form's action-attribute
function getIdFromFormAction(){
var action = $(&quot;#aspnetForm&quot;).attr('action');
var IdCheck = action.substring(action.indexOf('?')).indexOf('ID=');
	if(IdCheck==1){
	var end = action.indexOf('&amp;');
		if(action.indexOf('&amp;')&lt;0){
			id = action.substring(action.indexOf('ID=')+3);
		}else{
			id = action.substring(action.indexOf('ID=')+3,end);
		}
	}else{
		id = 0; // Called from NewForm returns 0
	}
	return id;
}

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 as “PrimaryKey.js” and upload to the “script-library” as shown above.

This is not a “guaranteed” primary key, as it does not work in datasheet-editing, and I’m sure someone finds a way to trick it. I’m nevertheless confident that someone can make use of this code.

Let me know if something is unclear.

Regards
Alexander

Redirect on NewForm and EditForm another method

This is another method for redirecting a user to a custom page on “OK” and another page on “Cancel”.

I have described two methods in this previous article. This method is a god replacement for the “simple redirect” described in the previous article.

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

Add a CEWP below your list-form in NewForm or EditForm, 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;&gt;
fields = init_fields();
// Where to go when cancel is clicked
goToWhenCanceled = '/test/English/YouCanceled.aspx';

// Edit the redirect on the cancel-button's
$('.ms-ButtonHeightWidth[id$=&quot;GoBack&quot;]').each(function(){
    $(this).click(function(){
			STSNavigate(goToWhenCanceled);
	  })
});

// Edit the form-action attribute to add the source=yourCustomRedirectPage
function setOnSubmitRedir(redirURL){
var action = $(&quot;#aspnetForm&quot;).attr('action');
var end = action.indexOf('&amp;');
	if(action.indexOf('&amp;')&lt;0){
		newAction = action + &quot;?Source=&quot; + redirURL;
	}else{
		newAction = action.substring(0,end) + &quot;&amp;Source=&quot; + redirURL;
	}
$(&quot;#aspnetForm&quot;).attr('action',newAction);
}

/*
// Use this for adding a &quot;static&quot; redirect when the user submits the form
$(document).ready(function(){
	var goToWhenSubmitted = '/test/English/ThankYou.aspx';
	setOnSubmitRedir(goToWhenSubmitted);
});
*/

// Use this function to add a dynamic URL for the OnSubmit-redirect. This function is automatically executed before save item.
function PreSaveAction(){
// Pass a dynamic redirect URL to the function by setting it here,
// for example based on certain selections made in the form fields like this:
	var mySelectVal = $(fields['MySelect']).find(':radio:checked').next().text(); 
	if(mySelectVal=='Option one'){
		var dynamicRedirect = '/test/English/YouSelectedOptionOne.aspx';
	}else if(mySelectVal=='Option two'){
		var dynamicRedirect = '/test/English/YouSelectedOptionTwo.aspx';
	}	
	
	// Call the function and set the redirect URL in the form-action attribute
	setOnSubmitRedir(dynamicRedirect);
	
	// This function must return true for the save item to happen
	return true;
}

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;

This script is by default setup with a “dynamic” redirect for “OK” based on the selection made in a “Choice-field” of type “Radio Buttons” with the options “Option one” and “Option two”.

The “OK” redirect can be set to a “static” value if you comment out the function “PreSaveAction()” and uncomment the “$(document).ready(…” function.

The cancel-redirect is set in the top pf the script in the variable “goToWhenCanceled”. The script modifies the “click” attribute of both cancel-buttons and adds this redirect.

Ask if something is unclear

Regards
Alexander

Identify content type to execute content type specific code

In another post i received a request on how to identify the content type in NewForm to execute “content type specific code”. Here’s a quick description of one method.

The method relies on a script, init_fields(), which loops trough all fields in the form and makes an object of all table rows and their HTML. This way all fields can be addressed by their FieldInternalName, returning the full HTML of that field.

The function init_fields() is a modified version of Erucy’s function for finding fields in a SharePoint form. My modified version uses FieldInternalName rather than DisplayName to locate the fields.

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 code below uses the FieldInternalName of a specific field to ensure that the field is rendered – if so – it executes the code wrapped in that “if-statement”. The field used to identify the ContentType must reside only in that content type.

Add a CEWP belowit is essential that it is placed below – your list-form as briefly 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;&gt;
fields = init_fields();
/*
 This example shows how you can check what ContentType is used by checking if
 a field you know is in that specific ContentType is rendered
*/

// Check if the field with FieldInternalName of &quot;OnlyInContentType1&quot; is rendered
if(fields['OnlyInContentType1']!=undefined){
	alert(&quot;This is content type nr 1&quot;);
	// Execute any code that addresses the first content type
}

// Check if the field with FieldInternalName of &quot;OnlyInContentType2&quot; is rendered
if(fields['OnlyInContentType2']!=undefined){
	alert(&quot;This is content type nr 2&quot;);
	// Execute any code that addresses the second content type
}

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 code above does work in NewForm, DispForm and EditForm.

To get the “FriendlyName” of the content type in DispForm or EditForm you can use the script below. This script also enables you to hide the “Content type selector” from EditForm.

&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;&gt;

// This example shows how you can get the &quot;FriendlyName&quot; of the ContentType
// You can optionally hide the &quot;ContentType selector from EditForm&quot;

// Get the name and hide the selector
var contentType = getContentFriendlyNameOptionalHide(true);
alert(contentType);

function getContentFriendlyNameOptionalHide(hide){
if(hide){
	$(&quot;select[id$='ContentTypeChoice']&quot;).parents('tr:first').hide();
}
	// EditForm
	var value = $(&quot;select[id$='ContentTypeChoice']&quot;).find('option:selected').text();
	// DispForm
	if(value==''){
		value = $(&quot;span[id$='InitContentType']&quot;).text();
	}
return value;
}
&lt;/script&gt;

Ask if something is unclear.

Regards
Alexander

Preview metadata in list view on mouseover

12.09.2011 A new version is posted here.

30.07.2010 A major update of the script to tidy up the code and to support previewing in a image library. Please read trough the article to get the changes to the CEWP code. The solution is tested in IE 8, Firefox v3.6.8 and in Google Chrome v5.0.375.125.

22.06.2010 Small update in line 118 and 125 to prevent “star” to be appended to lookup columns.

23.03.2010 Updated the code for “Preview_DispForm_metadata.js”. This update fixed compatibility with folders (thanks to Deano for finding the bug). Added support for a mix of lists and document libraries in the same webpart page.

19.02.2010 Fixed a bug if two different document libraries were present in the same webpartpage. The file “Preview_DispForm_metadata.js” is updated. Thanks to Ben for finding the bug.

09.01.2010: Fixed a major performance issue when viewing only selected fields from the metadata. Replace the code for the file “Preview_DispForm_metadata.js” to get the latest fixes.

10.12.2009: Fixed a hard coded “hoverImg” in the code – thanks to Amy.


By request from some of my readers i have, with basis in a solution created by Paul Grenier and published on EndUserSharepoint, made a solution that preview’s metadata from a list item or a document on mouse over.

The script i used as basis previewed metadata from DispForm in a CEWP beside a calendar view.

This modification adapts it to present a “floating” pop-up on mouse over when hovering over a table row, a calendar item, or on a small image added before a selected field.

The original script, made by Paul Grenier, previewed the full form from DispForm. I have adapted it so that one can display the full form, or specify an array of columns to display.

This script can be used in plain list view, grouped list views and calendar views.

New in this version is that the ID column must be in the view (not true for calendar view). The column can be hidden in the script.

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.4.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The sourcecode for the file “Preview_DispForm_metadata.js” is found below.

Add a CEWP below the list view and add the code – examples shown below the screen-shots.

Here are some screenshots and the CEWP code:
Plain list view – all fields
IMG

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/Preview_DispForm_metadata.js&quot;&gt;&lt;/script&gt;

To hide the ID column, change the CEWP code like this:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/Preview_DispForm_metadata.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    hideIdColumn = true;
&lt;/script&gt;

Plain list view – selected fields
IMG

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/Preview_DispForm_metadata.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    hideIdColumn = true;
    arrOfFieldsToShow = ['MultilinePlainText','Responsible'];
&lt;/script&gt;

“hoverImg” used
IMG

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/Preview_DispForm_metadata.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    hideIdColumn = true;
    arrOfFieldsToShow = ['MultilinePlainText','Responsible'];
    hoverImg = '/_layouts/images/OPENDB.GIF';
    hoverImgDescription = 'Hover mouse over this image to preview the metadata'; // If left blank, no description is displayed in the pagetitle area
    prependHoverImageTo = 'LinkTitle'
&lt;/script&gt;

Parameters explained:

  • hideIdColumn: true to hide the ID column. Defaults to false
  • arrOfFieldsToShow: Array of fields to show. Defaults to all fields.
    To have only a selection of fields, add to the array like this: [‘Title’,’MultilinePlainText,’Responsible’].
    To have only the value and not the label showing, add to the array like this: [‘MultilinePlainText|0’]
  • hoverImg: If you want to hover over an image and not the whole row, add the “src” to the image here. You must also set the parameter “prependHoverImageTo”.
  • prependHoverImageTo: A FieldInternalName to prepend the “hoverImg” to.
  • hoverImgDescription: A description that will be added to the page title area.

All parameters are optional.

Sourcecode for “Preview_DispForm_metadata.js” is found here

Note:

When new versions are released, they will be placed in a folder with the version number as label. Be sure to download the latest version.

If you are using a browser other than IE, right click the file and select “Save link as” or “Save linked content as…”.

Ask if something is unclear.

Regards
Alexander