Redirect from NewForm to EditForm or custom page

23.04.2011 Yet another article about the same topic can be found here

21.11.2009 A new article describing another method for redirecting a user to a custom page on “OK” and another page on “Cancel” is found here. This method is a good replacement for the “simple redirect” described in this article.

I have struggled a bit trying to redirect the user from NewForm to EditForm of the same list item – midway in filling the form. The reason i wanted to do this was to have access to the item ID when proceeding with the rest of the form fields (to make a relation between this list item and an item in another list).

I ended up using a brilliant solution called sessvars, from a guy named Thomas Frank. Read about it and get the sessvars.js here.

This technique can also be used to “redirect” the user to a custom “Thank you for participating…” – page after filling the form and clicking the “OK” button. I will provide examples of both methods.

In both examples you 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

A simple redirect from NewForm to a “Thank you for submitting” – page can be done like this.
Add a CEWP below the listform in NewForm and add reference to the scripts like this:

Img

The variable “sessvars.targetUrl” is set in a function called PreSaveAction which is always called when you click the “OK-button”. It must return true for the item to be saved. When this variable is set in this function, it is only set if the user actually saves the list item and not if the user clicks “Cancel”. this overcomes the problem with adding a ?Source=/test/English/ThankYou.aspx to the URL – which would redirect the user even if he clicks “Cancel”.

<script type="text/javascript" src="/test/English/Javascript/sessvars.js"></script>
<script type="text/javascript">
function PreSaveAction(){
  sessvars.targetUrl = '/test/English/ThankYou.aspx';
return true;
}
</script>

Then you have to add a CEWP to the standard view of your list (the view you normally would be redirected to after saving a list item if you have no ?Source= in the query string of your URL):
Img

This code checks if the variable “sessvars.targetUrl” is defined, and redirects the user to the specified address. Note that right before the redirect, the variable is cleared with “sessvars.$.clearMem()”, to prevent the user from getting redirected multiple times.

<script type="text/javascript" src="/test/English/Javascript/sessvars.js"></script>
<script type="text/javascript">
var targetUrl = sessvars.targetUrl;
if(targetUrl!=undefined){
  sessvars.$.clearMem();
  window.location.href = targetUrl; 
}
</script>

When the user adds a new item to the list, he is redirected to the URL specified in the variable “sessvars.targetUrl” like this:
Img

A redirect from NewForm to EditForm can be done like this:
Like in the example above, add the necessary scripts:
Img

Here i have used some new scripts published on CodePlex by a user named DuWei. Get them here. I have used interaction.js and stringBuffer.js in this example.

Add a CEWP to the NewForm with this code:
Img

You have to provide the URL to EditForm.aspx, and the list GUID of the list.

<script type="text/javascript" src="/test/English/Javascript/sessvars.js"></script>
<script type="text/javascript">
function PreSaveAction(){
  // SharePoint variable of current user's id
  sessvars.userId = _spUserId; 
  // Path of the list to redirect to - current list
  sessvars.targetUrl = '/test/English/Lists/NewFormToEditFormRedirect/EditForm.aspx'; 
  // The BaseUrl of the site or subsite you are located  	
  sessvars.listBaseUrl = L_Menu_BaseUrl; // SharePoint provides this
  // List Guid of the list to redirect to
  sessvars.listGuid = '{1791b3f2-9725-49fb-a8a4-561a57e38b34}'; 
  return true;
}
</script>

Then you add a CEWP to the standard view of your list:
Img

<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/interaction.js"></script>
<script type="text/javascript" src="/test/English/Javascript/stringBuffer.js"></script>
<script type="text/javascript" src="/test/English/Javascript/sessvars.js"></script>

<script type="text/javascript">
var userId = sessvars.userId;
var targetUrl = sessvars.targetUrl;
var listBaseUrl = sessvars.listBaseUrl;
var listGuid = sessvars.listGuid;

if(userId!=undefined && targetUrl!=undefined && listGuid!=undefined){
// Query to find the newest item added by current user
wsBaseUrl = listBaseUrl + '/_vti_bin/'; 
var res = queryItems(listGuid,"<Where><Eq><FieldRef Name='Author' LookupId='TRUE'/><Value Type='Integer'>" + userId  + "</Value></Eq></Where><OrderBy><FieldRef Name='ID' Ascending='FALSE'/></OrderBy>",['ID']);    
// Gets the ID of the item
var itemId = res.items[0]['ID']; // This is the newest item added by current user
// Clears the session variables to prevent redirecting multiple times
sessvars.$.clearMem();
// Redirects the user to the correct item and opens it in EditForm
window.location.href = targetUrl + "?ID=" + itemId; 
}
</script>

When a user saves the list item – he is redirected to the EditForm (or DispForm if you specify it in the URL) of the list item he just added.

Please ask if something is unclear.
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