Category Archives: Form modification

Dynamic expand/collapse fields or array of fields

28.11.2009 A follow up article on using multi select checkboxes is found here.

13.11.2009 Updated code for better function in EditForm and DispForm

This is a short intro on how to dynamically expand or collapse a field or array of fields based upon selection made in another field.

As always  we begin 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 subsite named “test” with a subsite named “English” with a document library named “Javascript”):
IMG

This is the only script you need to refer for this example.

Create a custom list with these fields:
IMG

Pay attention to the FieldNames. Always create names without spaces or special character to get a nice “FieldInternalName” – then you can rename the field to whatever you want – the “FieldInternalName” newer changes!

The field “MySelect” looks like this:
IMG

Then you add a CEWP below the list form in NewForm like this:
IMG

Sourcecode for NewForm.aspx and EditForm.aspx

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

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

// Onchange
$(fields['MySelect']).find('select').change(function(){
var c = $(this).find('option:selected').text();
	dynamicDisplay(c);
});

// Onload
var c = $(fields['MySelect']).find('option:selected').text();
dynamicDisplay(c);

function dynamicDisplay(color){
// Hide all initially
toggleArr(arrToHide,true);
	if(color=='Red'){
		toggleArr(arrRed,false);
	}
	else if(color=='Blue'){
		toggleArr(arrBlue,false);
	}
	else if(color=='Yellow'){
		alert("No array defined for "Yellow"");
	}
}

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(){
var res = {};
$("td.ms-formbody").each(function(){
if($(this).html().indexOf('FieldInternalName="')<0) return;
var start = $(this).html().indexOf('FieldInternalName="')+19;
var stopp = $(this).html().indexOf('FieldType="')-7;
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}
</script>

Sourcecode for DispForm.aspx

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

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

// Show the array for the selected color
var c = $(fields['MySelect']).find('.ms-formbody').text().replace(/s|xA0/g,'');
dynamicDisplay(c);

function dynamicDisplay(color){
// Hide all initially
toggleArr(arrToHide,true);
	if(color=='Red'){
		toggleArr(arrRed,false);
	}
	else if(color=='Blue'){
		toggleArr(arrBlue,false);
	}
	else if(color=='Yellow'){
		alert("No array defined for "Yellow"");
	}
}

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(){
var res = {};
$("td.ms-formbody").each(function(){
if($(this).html().indexOf('FieldInternalName="')<0) return;
var start = $(this).html().indexOf('FieldInternalName="')+19;
var stopp = $(this).html().indexOf('FieldType="')-7;
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}
</script>

The function “init_fields” is a modified version of the one created by Erucy and posted here. I have modified it to use “FieldInternalName” instead of “DisplayName” for locating the fields.

The end result should look like this:
IMG
IMG
IMG
IMG

Other fields can be used to trigger the event – look here to learn how to refer the various types of fields:
http://docs.jquery.com/Selectors

Have fun!
Alexander

Wrap choice-field in multiple columns

Change log
October 19. 2014
Updated the code to get rid of a few wrong single quotes introduced when migrating this code from another server.

I received a comment on another post requesting a function to wrap the choice-field into any given number of columns. Say you have a choice-field of “Checkbox” or “Radio” type with 20 choices and want to arrange them in multiple columns like this:
IMG

Here we go:
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 subsite named “test” with a subsite named “English” with a document library named “Javascript”):
IMG

You find the sourcecode for “WrapChoiceField.js” below.

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 listform in NewForm and EditForm and add reference to the scripts like this:
IMG

Create the list-fields as normal:
IMG

Sourcecode for the file WrapChoiceField.js:

/* Wrap choice-field in multiple columns
* ----------------------------------------------------
* Author: Alexander Bautz
* alexander.bautz@gmail.com
* Version: 1.3
* LastMod: 19.10.2014
* ----------------------------------------------------
* Must include reference to jQuery
* ----------------------------------------------------
  Example:
  wrapChoiceField("FieldInternalName of your field",number of columns to wrap it into);
* ----------------------------------------------------
*/

var fields = init_fields_v2();
 
function wrapChoiceField(fin,breakAfter){
	var toFind, index, counter, table, fillIn, len;
	toFind = "td.ms-formbody";
	if($("td.ms-formbodysurvey").length>0){
		toFind = "td.ms-formbodysurvey";
	}
	if(fields[fin]!==undefined){
		index = 0;
		counter = 0;
		table = $(fields[fin]).find(toFind+' table:first');
		fillIn = $(table).find("tr:last").find("input:text").length === 1;
		len = $(table).find("tr").length;
		$(table).prepend("<tr id='vertical_"+fin+"_"+index+"'></tr>");
		$(table).find('tr:first').nextAll().each(function(i,tr){
			if(counter > 0 && counter%breakAfter === 0){				
				$("#vertical_"+fin+"_"+index).after("<tr id='vertical_"+fin+"_"+(index+1)+"'></tr>");
				index += 1;
			}else if((fillIn && i === (len-1)) || (fillIn && i === (len-2))){
				$("#vertical_"+fin+"_"+index).after("<tr><td valign='top' colspan='"+breakAfter+"'><table><tr id='vertical_"+fin+"_"+(index+1)+"'></tr></table></td></tr>");
				index += 1;
			}						
			$(tr).find('td:first').css("white-space","nowrap").appendTo($("#vertical_"+fin+"_"+index));
			$(tr).remove();
			counter += 1;
		});
	}
}
 
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 the sourcecode to a file named “WrapChoiceField.js”, and upload to your document library as shown above.
Be sure to get the file type correct – the file extension is .js

That’s it!

Customized form?
How to use these scripts in a customized form

Regards
Alexander

Cascading dropdowns

14.06.2010 A new version of this script is released Cascading dropdowns in SharePoint text fields – populated by lookup in another list (version 2)

I recommend using the new version.


Updated 14.08.2009
This script “converts” singleline textfields to lookup-dropdowns. One dropdown filteres the next. You can have 2-5 connected dropdowns in each “collection”. You can have as many “collections” as you want in each listform.

The source of the cascading dropdowns is a standard custom list containing the information to populate each of the dropdowns. This list can reside in the current site, the rootsite or in any subsite as long as users has access to it.

The script uses the original textfield to hold the value selected, and “spawns” a dropdown to take it’s place. In editform (or on refresh of the form on validation) the script updates the dropdown to hold the correct value – read from the original textfield.

If you open in editform and the original value selected in no longer a valid choice (the value is deleted from the source list), the dropdown and the corresponding hidden textfield is cleared.

When changing a “parent” dropdown, the children is cleared for the previously selected values and repopulated with the new choices.

To use this script you have to reference jQuery (tested with jquery-1.3.2.min.js) and these scripts:
* SPAPI_Core.js
* SPAPI_Lists.js
* SPAPI_dspsts.js
* Made by Darren Johnstone http://darrenjohnstone.net
download the scripts here. This download contains more scripts than you need to refer – only the scripts named over is used.

How to use:
Make a sourceList to hold the selectable values to fill your dropdowns.
Img
Create the fields like this:
Img

The calculated column (_Lookup) that concatenates all these columns is the field the script uses to find matching values to populate the next dropdown.

Find the ListGuid of your SourceList like this:
Img
You need it in the function call later.

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 subsite named “test” with a subsite named “English” with a document library named “Javascript”):
Img

In the consumer list (the list where your dropdowns is supposed to be), add corresponding columns (standard SharePoint single line textfields) for all but the calculated field. The final “product” looks like this:
Img

Insert a CEWP below the listform in NewForm and EditForm and add reference to the scripts like this:
Img
The source looks like this (copy the source below):
Img
The listGuid of your sourceList is used here

Sourcecode:
<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/SPAPI_Core.js"></script>
<script type="text/javascript" src="/test/English/Javascript/SPAPI_Lists.js"></script>
<script type="text/javascript" src="/test/English/Javascript/SPAPI_dspsts.js"></script>
<script type="text/javascript" src="/test/English/Javascript/CascadingDropDowns.js"></script>

<script type="text/javascript">
/*
* providerArr = Array of FieldInternalNames of the fields in the source-list.
* consumerArr = Array of FieldInternalNames of the fields in the list where the dropdowns will be created.
* dropDownIdPrefix = Unique prefix if there are more then one instance of cascading dropdowns in one list.
* lookupSourceCalculatedField = FieldInternalName of the calculated column in the source-list that concatenates all lookup values in one string – separated by "delimiter".
* lookupSourceListGuid = GUID of the source-list.
* dropDownDefaultvalue = The default value of dropdowns that are not empty – ex. <select>.
* numberOfDropdowns = Number of levels of cascading dropdowns – (2-5).
* delimiter = Separator character between the values of the calculated column in "lookupSourceCalculatedField". Must be the same as the delimiter used in the "_Lookup" in the sourceList.
* sourceListURL = relative URL to site/subsite. If root site use only two apostrophes representing a blank string – like this: ”.
* debug = true or false – if true: the textfield that holds the dropdownvalue is visible.
*/
// You don’t have to use the same names in providerArr and consumerArr, but you have to use the FieldInternalName and not the Displayname.
providerArr = [‘Title’,’Model’,’Color’,’Year’,’Milage’];
consumerArr = [‘Title’,’Model’,’Color’,’Year’,’Milage’];
cascadingDropDowns(providerArr,consumerArr,’CascNr1′,’_Lookup’,'{83eb224b-03fa-4a8b-b493-80253373a962}’,'<Select>’,5,’ – ‘,true,’/test/English’,false);
// For description of all the parameters see the sourcecode.
</script>
[/javascript]
Be sure to use the correct path to your script in the reference – mine is located at “/test/English/Javascript”.

How to find the FieldInternalName? – Click here

Get the sourcecode for “CascadingDropDowns.js” here and save it as CascadingDropDowns.js. Make sure you get only the script and not other text – copy manually – do not use Ctrl+A.

Upload in the document library with the other scripts needed – as shown above.

If you need more info to setup this script, feel free to ask.

PS. I have other scripts for single filtered lookup’s both for for obtaining value only, and for link to list item or to document. Ask for it and i will post it.

Regards
Alexander