User Story
A customer wanted to distribute a survey that would anonymously collect information from mobile device users. The survey needed to pre-fill certain known values such as UserName and Client OS. The UserName is not an AD account but a custom ID from the application they are using.
Challenges
SharePoint solutions (.wsp) are a last resort in this environment since the SharePoint team is small and any custom code would have to be maintained by them. The shop is a dev shop, however, and HTML / JavaScript is the lingua franca of the web.
I needed any code to be on the client side so that another non-SharePoint dev team could maintain it by editing HTML or JavaScript. This is SharePoint 2010 by the way, not 2013 with the new cool shiny CSOM that does everything.
Solution
I created a new NewForm.aspx in SPD and called it csNewForm.aspx. This turns the web part into a data view that allows you to edit the individual controls. This is desirable because I wanted to hide some of the fields later. We didn’t want the users to modify the values in the pre-populated fields.
Figure 1: the customized csNewForm.aspx for my survey
Some searching on the internet yielded a cool Regex that would parse out query string parameters. I implemented this into a PopulateNewForm.js file. The file calls the getUrlParameter function and passes the returned value to one of several functions that insert the value into the edit box or whatever control is appropriate.
//PopulateNewForm.js
//Parses values from query string parameters and inserts into custom Newform.aspx.
//Note that the code must change if the form changes as each form element has a unique
//identifier that can change. You can determine the element id by using the IE dev tools
function getUrlParameter( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null ) return"";
elsereturn results[1];
}
function populateNewForm()
{
//Populate User
document.getElementById("ctl00_m_g_a36f8597_64e7_4e22_a7a5_9ca279e224b4_ff21_ctl00_ctl00_TextField").value = getUrlParameter("User");
//Populate OS
var OS = getUrlParameter("OS");
switch (OS)
{
//Android
case"0": document.getElementById("ctl00_m_g_a36f8597_64e7_4e22_a7a5_9ca279e224b4_ff11_ctl00_ctl00").checked = true;
break;
//Apple
case"1": document.getElementById("ctl00_m_g_a36f8597_64e7_4e22_a7a5_9ca279e224b4_ff11_ctl00_ctl01").checked = true;
break;
//Blackberry
case"2": document.getElementById("ctl00_m_g_a36f8597_64e7_4e22_a7a5_9ca279e224b4_ff11_ctl00_ctl02").checked = true;
break;
}
}
_spBodyOnLoadFunctionNames.push("populateNewForm")
Snippet 1: PopulateNewForm.js
In the case of this particular survey I needed to select an appropriate radio button depending on the parameter value so I simply set it’s “checked” property to true.
The last line of the script uses the _spBodyOnLoadFunctionNames object to push the populateNewForm() function into the web page at runtime. That’s the main function that calls all other functions
The downside of this approach is that you have to reference each element by its DOM object using document.getElementById(). I used the IE Dev tools to inspect the csNewForm.aspx page and determine the exact id of the elements. If the csNewForm.aspx changes then the elements id’s are going to change and you’ll need to update the javascript file. The nice thing about it is that it can be update by another team and not you. I then uploaded the file to a “Scripts” library and referenced the file from the csNewForm.aspx page using a standard <script> tag.
The implementation benefits from having a url that specifies a "Source" parameter as shown above. It will redirect the user to a custom "Thank You" page after they fill in the survey.
Final step is to hide the fields that are to be pre-filled so the user can't modify at creation time. To do this you can use the built-in "ms-hidden" class in the definition of the cells that house the controls that are bound to those fields. I.e., the label and actual control cells need to have a class="ms-hidden" attribute.
The link that is distributed to the mobile users looks like this
http://TheSite/Lists/MobileDevice/csNewForm.aspx?Source=http://TheSite/pages/thankyou.aspx&User=TestUser&OS=0
The parameters get populated into the form, the mobile users fill in the rest of the values and they get a nice “Thank You” at the end of it, all of it maintainable by another team that doesn’t use Visual Studio or knows anything about SharePoint. Success!