Using Javascript to Manipulate a List Form Field

Using Javascript to Manipulate a List Form Field

Rate This

Hi, my name is Rob Howard, and I’m a Program Manager with the SharePoint Designer team. Like several of the other people posting here, I also built many of the Application Templates for Windows SharePoint Services.

If you’re familiar with them, you may have noticed that in several of the application templates we use a bit of Javascript to set default form values based on the query string. Because we found this to be useful in many different cases throughout our applications, I wanted to share our method with you guys so that you can include it in the applications you develop.

When might you use this?

It’s pretty easy to set a field’s default value through the list settings in the browser UI, so why might you need Javascript to set a default field value? The reason is that field default values can only take static values or simple formulae based on the current user or today’s date. If that meets your needs, then I’d definitely recommend sticking with that method. Sometimes, though, you may want the form to fill with default values based on the user’s interaction with the previous page, and that’s exactly where this method comes in.

How does it work?

In short, we add some Javascript to the page that runs when the body is loaded. This Javascript parses the page’s query string, locates the HTML objects that are rendered by the relevant SharePoint fields, and sets their value based on the information in the query string.

getTagFromIdentifierAndTitle

The most important part of our solution is the “getTagFromIdentifier” function. This function finds the HTML element rendered by a given SharePoint FormField control. It takes the following parameters:

  • tagName – The name of the tag rendered in the form’s HTML
  • identifier – The string associated with the SharePoint type of the relevant field
  • title – The value of the relevant HTML tag’s “title” attribute, which also matches the field’s display name

Here’s a partial table of SharePoint column types and their corresponding “identifiers” and “tagNames”:

SharePoint Field Type identifier tagName
Single Line of Text TextField input
Multiple Lines of Text TextField input
Number TextField input
Currency TextField input
Choice (dropdown) DropDownChoice select
Lookup (single)* Lookup select
Lookup (multiple) SelectCandidate; SelectResult select
Yes/No BooleanField input

*Lookups are a bit more complicated because Lookup FormFields render differently when the target list contains more than 20 items. See the end of the post for an example.

function getTagFromIdentifierAndTitle(tagName, identifier, title) {

  var len = identifier.length;

  var tags = document.getElementsByTagName(tagName);

  for (var i=0; i < tags.length; i++) {

    var tempString = tags[i].id;

    if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {

      return tags[i];

    }

  }

  return null;

}

fillDefaultValues

Now that we have the HTML elements that we want to set, we need the values with which to set them. In our solution, we wrote the “fillDefaultValues” function, which parses the page’s querystring and then uses the values to set the field defaults.

function fillDefaultValues() {

  var qs = location.search.substring(1, location.search.length);

  var args = qs.split("&");

  var vals = new Object();

  for (var i=0; i < args.length; i++) {

    var nameVal = args[i].split("=");

    var temp = unescape(nameVal[1]).split('+');

    nameVal[1] = temp.join(' ');

    vals[nameVal[0]] = nameVal[1];

  } 

  // Set HTML element default values here

}

_spBodyOnLoadFunctionNames

In most cases SharePoint pages are based on a master page that contains the “body” element. These content pages can’t directly add a function to the body’s onload event. In order to work around this limitation, SharePoint provides the “_spBodyOnLoadFunctionNames” array. When the body is loaded, the onload event handler executes each function whose name is contained in this array. We added “fillDefaultValues” to the array so that it would run when the body’s onload event fires.

_spBodyOnLoadFunctionNames.push("fillDefaultValues");

All Together Now

With the script above, you can set most different field types to any value from the querystring – or any other source that javascript can access. Below is a full example of the script we use to set the default value of a Lookup field based on an ID stored in the querystring. You’ll notice that setting a Lookup field is a bit more complicated than some other field types. The reason is that Lookup FormFields are rendered with different HTML when the target list contains more than 20 items.

Enjoy!

<script type="text/javascript">

 

// This javascript sets the default value of a lookup field identified

// by <<FIELD DISPLAY NAME>> to the value stored in the querysting variable

// identified by <<QUERYSTRING VARIABLE NAME>>

 

 

// Customize this javascript by replacing <<FIELD DISPLAY NAME>> and

// <<QUERYSTRING VARIABLE NAME>> with appropriate values.

// Then just paste it into NewForm.aspx inside PlaceHolderMain

 

_spBodyOnLoadFunctionNames.push("fillDefaultValues");

 

function fillDefaultValues() {

  var qs = location.search.substring(1, location.search.length);

  var args = qs.split("&");

  var vals = new Object();

  for (var i=0; i < args.length; i++) {

    var nameVal = args[i].split("=");

    var temp = unescape(nameVal[1]).split('+');

    nameVal[1] = temp.join(' ');

    vals[nameVal[0]] = nameVal[1];

  } 

  setLookupFromFieldName("<<FIELD DISPLAY NAME>>", vals["<<QUERYSTRING VARIABLE NAME>>"]);

}

 

function setLookupFromFieldName(fieldName, value) {

  if (value == undefined) return;

  var theSelect = getTagFromIdentifierAndTitle("select","Lookup",fieldName);

 

// if theSelect is null, it means that the target list has more than

// 20 items, and the Lookup is being rendered with an input element

 

  if (theSelect == null) {

    var theInput = getTagFromIdentifierAndTitle("input","",fieldName);

    ShowDropdown(theInput.id); //this function is provided by SharePoint

    var opt=document.getElementById(theInput.opt);

    setSelectedOption(opt, value);

    OptLoseFocus(opt); //this function is provided by SharePoint

  } else {

    setSelectedOption(theSelect, value);

  }

}

 

function setSelectedOption(select, value) {

  var opts = select.options;

  var l = opts.length;

  if (select == null) return;

  for (var i=0; i < l; i++) {

    if (opts[i].value == value) {

      select.selectedIndex = i;

      return true;

    }

  }

  return false;

}

 

function getTagFromIdentifierAndTitle(tagName, identifier, title) {

  var len = identifier.length;

  var tags = document.getElementsByTagName(tagName);

  for (var i=0; i < tags.length; i++) {

    var tempString = tags[i].id;

    if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {

      return tags[i];

    }

  }

  return null;

}

</script>

  • I agree with the previous posters. _spBodyOnLoadFunctionNames is undocumented. Should we settle for the fact that the SharePoint Designer Team bothered to mention it briefly in this blog post. Where is it in the SDK docs or MSDN? Is there a corresponding OnUnload function? Proper use of Google Maps requires unloading what you load and I can only guess without proper documentation.

  • I noticed a lot of folks want to set the People Picker (Assigned To) field.

    Adding this to the fillDefaultValues function worked for me:

    var assignedToInput = getTagFromIdentifierAndTitle("div", "", "People Picker");

    assignedToInput.innerHTML = vals["Assigned_To"];

    Cheers!

  • I've been trying to use the code listed above and have been having trouble getting it to execute.  I think it might be due to where I've placed the call to _spBodyOnLoadFunctionNames. One of the posts says to add a Content Editor Web Part and then add the call to the page. THis still does not work for me.  Is it possible to get an example showing where exactly this call has been inserted within a sharepoint page, meanign a good chunk of the page?  Thanks!!

  • Are there any other blogs or sites similar to this one which would help me understand how to create CSS/Javascript-based tooltips for each calendar event in the Month/Week/Day calendar views??

    Thank you, Tom

  • First off, to people having trouble getting it working, simply place the script block within any content area that renders on the page.  Probably the safest bet to make sure it gets on is the main page placeholder.

    <script language="javascript" type="text/javascript">

    _spBodyOnLoadFunctionNames.push("hideFields");

    function hideFields()

    {

      //test it first!

       alert('It Worked!!');

    }

    </script>

    Throw the script block from above in directly below <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server"> and if you get the message box on page load than you've taken care of loading javascript onto the page and can begin working on the next steps.  

    Now to my problem...

    I've had success with everything except the Recurrence and Workspace fields.  I'm using them as below:

    //Recurrence

    var control5 = getTagFromIdentifierAndTitle("INPUT","BooleanField","Recurrence");

    control5.parentNode.parentNode.parentNode.style.display="none";

    I'm getting 'parentNode is null or not an object'.  Any help would be greatly appreciated.

  • Thanks for this post!

    Can the same be accomplished with a document library where the properties are shown in for example the properties pane in Word (2007)? I need to accomplish the same for these libraries. Any other suggestions?

    Thank you, Ben

  • All -- I was able to get regular Text Fields auto-populating from a querystring {NewForm.aspx?myQueryStringName=some_value_here} with this script below. Note i used the function from Belchski {THX!!} called 'setTextFromFieldName' and called it at the bottom of the script like so:   [setTextFromFieldName("theFormFieldDisplayNametoPopulate", vals["myQueryStringName"]);]. I opened NewForm.aspx up in DEsigner & plopped the script right above the </asp:Content> tag.

    I hope this works for everyone...GREAT little script. I am using for a link from the Remedy Help Desk App to autopopulate a HD Ticket Number & Summary into a User Survey (how was your Ticket completed, etc.).

    ----------------------------------------------------------------------

    <script type="text/javascript">

    _spBodyOnLoadFunctionNames.push("fillDefaultValues");

    function getTagFromIdentifierAndTitle(tagName, identifier, title) {

     var len = identifier.length;

     var tags = document.getElementsByTagName(tagName);

     for (var i=0; i < tags.length; i++) {

       var tempString = tags[i].id;

       if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {

         return tags[i];

       }

     }

     return null;

    }

    function setTextFromFieldName(fieldName, value) {

    if (value == undefined) return;

      var theInput = getTagFromIdentifierAndTitle("input","TextField",fieldName);

    theInput.value=value

    }

    function fillDefaultValues() {

     var qs = location.search.substring(1, location.search.length);

     var args = qs.split("&");

     var vals = new Object();

     for (var i=0; i < args.length; i++) {

       var nameVal = args[i].split("=");

       var temp = unescape(nameVal[1]).split('+');

       nameVal[1] = temp.join(' ');

       vals[nameVal[0]] = nameVal[1];

     }  

     setTextFromFieldName("theFormFieldtoPopulate", vals["myQueryStringName"]);

    }

    </script>

    ----------------------------------------------------------------------

  • I was just about to try and write something like this myself for setting the value of a Lookup field but thought I'd do a quick google first.

    Thank god I did as this has saved me loads of time and was exactly what I was after.

    Thanks for sharing!!

  • my question revolves around the old fashioned document.myform.myfieldname.value='text';

    doesn't this work with SharePoint Designer (for the Form Web Part)?

  • hi,

    what should i use to get the ID of the current item in EditForm.aspx please?

  • Hi,

    Just in case anyone's wanted it, here's a routine to toggle a Yes/No field which is presented via a checkbox:

    function setYesNoFromFieldName(fieldName) {

      var theInput = getTagFromIdentifierAndTitle("input","BooleanField",fieldName);

      if (theInput.checked=="True") {

      theInput.checked="False";

      } else {

      theInput.checked="True";  

      }

    }

  • I recently found an application of the Blog template that was a great fit, but needed the Category title

  • I recently found an application of the Blog template that was a great fit, but needed the Category title

  • Anyone have an example of a Web Service call to get default field values?

  • The other title for this blog is &quot;For the Love of Pete, This Should be Easier!&quot; When you make

Page 3 of 12 (167 items) 12345»
Leave a Comment
  • Please add 4 and 6 and type the answer here:
  • Post