Using Javascript to Manipulate a List Form Field

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.

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

Thanks for this. It’s great to see how you guys are doing it. We have been doing something similar since the Team Services days but I still gleaned a few good ideas from your code (especially in the genericizing aspects). One thing I have been stuck on is how to set one of the new People fields to the Current User by default. Would love to hear if you guys are doing this or have any ideas.

I’m trying to to do something similar were on the same form one field’s data is dependant on another field and both these field are lookup fields, it will be great If you can tell me the names of the application templates using this feature, so that I can take a look how its works.

You’re script is working like a charm on the lookup fields. I even found the application template where you used it and found out you used a content editor web part on the newform.aspx so you can edit the javascript directly from sharepoint. Beautiful. I’m not very good with java script and i’m trying to set the default values for two text fields (Single line of text). I’ve been struggling with your example for one week straight, where it probably takes you 1 minute.

Can you maybe give an example where two fields (Single line of text) are filled by default. Or maybe just explain what i have to specify in your example where you state (// Set HTML element default values here).

Is there a similar command to _spBodyOnLoadFunctionNames.push for onSubmit that can be fired when a user checks a page back in? I need to do some date checking (date C cannot be before date B which cannot be before date A etc…)

Also, I how can I check for and prevent duplicate titles from being added (with document version control on)?

I have tried using the ItemUpdating event (see code below). When I get a hit the condition arises

An example of the Application Template is the Job Requisitions Server Admin Template. In the list Candidates, the DispForm.aspx uses Data Views to show items from the Interview Calendar related to the display item. There is then the link to add a new Interview by passing the user to NewForm.aspx in the Interview Calendar list. This is where the javasript above lives.

On the example template, you can schedule an interview on the candidates dispform.aspx page. This gives the CandidateId as querystring parameter to the next target screen where it is used as input to determine the value of a dropdown box.

In my environment I have set up something similar, but I want to give an additional parameter to the following target page, which is used as input for a second dropdown box. My problem is that the second parameter is a lookup field to a list. I managed to pass the value through the target page, but in fact it shouldn’t give the value which is displayed on the screen, but the ID of the value in the lookup list. How can I get the ID of that lookup field and pass it through?

Additionally: will the script mentioned here be able to handle two parameters at the same time to determine the dropdown values in the second target page?

Can you please give the tag name and identifier for Person/Group field? I need to hide a UserField for my NewForm.aspx. I tried using the multiple Lookup for SharePoint Field Type, but it doesn’t work. I also tried few other combinations but no use. Please help.

An example of the Application Template is the Job Requisitions Server Admin Template. In the list Candidates, the DispForm.aspx uses Data Views to show items from the Interview Calendar related to the display item. There is then the link to add a new Interview by passing the user to NewForm.aspx in the Interview Calendar list. This is where the javasript above lives.

Look at this page and you’ll see they use a Content Editor Web Part. Insert this web part and you can insert code onto the page.

I was able to achieve something by creating a new aspx page and then importing sharepoint content into it.

This created a page that was detached from a master page. It contained <Head> … etc….

The problem with this method is, it is too much overhead to support these new pages…

I also tried to back them up and restore them but I think because of unique identifiers in the page

it caused issues…

Basically, I’ve found that trying to get a query string variable into a field causes to much damn pain that its just better to have the user imput the value, although this drives me crazy. You’d think there would be a more simpler out the box way to do this (and please correct me if I am wrong).

So, based on the above can you help me out… Maybe I’m just going off in the wrong direction, but something tells me there is more to this than what this blog states…..

PS, why is the interace for entering comments into this blog so crappy? I’m not complaing, but come on…

You’re not too far off. To execute the code on the newitem.aspx page of this one list, just insert a script tag (pretty much anywhere near the bottom), I generally put them near another script tag and then insert the call to _spBodyOnLoadFunctionNames and then the functions your want called

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’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!!

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:

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?

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.).

What they have noticed is every contol SharePoint creates marks it with a commented name. So by searching for the commented name you should be able to locate the control with in that area perdicably per each control… I just lack understand of the code and it use/syntax to figure out why it does not work for me.

thanks for the nice article. helped me out… yet i still have a javascript problem with sharepoint:

I have a publishing site with some pages. i wanted to do something basic stuff like toggling a div visibility when someone clicks a link. i managed to include the javascript function in the page (in the ArticleLinks.aspx page… adding it to the master did not do the job) but looks like there is no way to call the javascript function from the page!

each time i edit the page and go into the source code… adding the javascript function call to the URL or the OnClick is always removed… this is so annoying!!!

I struggled with the prepopulating of Lookups until I realized the above code is designed to work on the ID of the Lookup Field. I was passing the value displayed in the lookup field and nothing worked.

If you don’t have the ID of the lookup field but you do have the text simply change

It looks like at least one person has been able to make this work for fields in the Insert Template. I would appreciate some ideas on how to make this work on my page with two web parts with Insert Templates. To clarify, the javasicript code fails on page load (throwing some annoying javascript errors)…then when the Insert Template is initiated on one web part, the code does run again and still gives the same error. If I initiate the second Insert Template link, the script works fine and adds the default values to each Insert Template. So, I know what the problem is, I just don’t know how to fix it.

It doesn’t seem that the FillDefaultValues script can run on page load in my scenerio, and I believe I’ll have to have two seperate functions (one for each Insert Template on the page). But, when and how can the function be called? Ideally it would be called when I click ‘Add’ to initiate the Insert Template… If anyone knows how to do that, please fill me in…

but i have a question.. If i want to set the selected value in a combo (lookup) and i have 500 items or more what it happens with the time that you need to make the sequential search? Is there any faster way?

Can someone tell me how to use JavaScript with a multiple select lookup, I already got it working with the single lookup field. But when I change Lookup for SelectCandidate or SelectResult it doesn’t works.

I was wondering if anyone knows how to edit/append the query string that the ok button on a Document Upload.aspx page is creating.

I am trying to set a drop down field on the EditForm.aspx page after a user selects a document.

I already have what I need passed in the query string to the Upload.aspx page but I am unsure on how to go about pushing what I need from there to the EditForm.aspx page when the "ok" button is clicked.

I also desparately need to find a way of getting, then passing an ID to the newitem.aspx – but I have no idea what you people are talking about – so I will continue Googling until I find a blogger who will write about this on a 4th grade level.

Same question as above from Monty… I’ve found this question on many other sites, but no posted answers.

… how to edit/append the query string that the OK button on a Document Upload.aspx page is creating.

I am trying to set a drop down field on the EditForm.aspx page after a user selects a document.

I already have what I need passed in the query string to the Upload.aspx page but I am unsure on how to go about pushing what I need from there to the EditForm.aspx page when the "ok" button is clicked.

I have a question about drop-down lists. I am fairly new to sharepoint so please bear with me. I have data form with a connection to SQL server 2000. I have a table with multiple foreign keys. Instead of displaying the foreign key (number), i want to display a drop down list for the name in that table. Here is the example below:

Table Mentor (m.ID, name, role, d.ID, p.ID)

Table Division d(ID, division)

Table Plant p(ID, plant)

I want to display a data view form that i am able to insert, delete, and update. I want the table to display m.name, m.role, d.division (drop down from existing data in division table), p.plant (drop down from existing data in plant table).

I’d like to reuse the setLookupFromFieldName or setSelecttedOption in an inline javascript to change the value of the ListForm field bound to a Sharepoint List.

1. Project ID is the field name for the dropdown I’m trying to set.

2. @Timesheet_ID is the value I want to set the dropdown to. It will always be known, and will always be in the dropdown list as an option.

My design is this: The user clicks on the link below (timesheet ID is loaded prior) to fire off the javascript. I want the dropdown in the other web part to go to that timesheet ID. Is this possible or am I continuing to waste time?

I’m trying to use something semilar sukebeta code which does not seem to be working. I have a script at the bottom of the Edit.aspx page, I need to prevent users setting a drop down field to approved if a couple fields are left empty. I can’t set these fields to be required as the person that enters the request does not do approval and those semi required fields doe not pertain to him.

I have this working in a simple html and JScript page but the sharepoint portion makes it complicated.

Here is a workarround for setting the values for start/end hours and start/end minute in a Task form. Since the ID for those select contros is generated dinamically i’ve implemented 2 functions which search for the ones that have the string "00:" for hours and "05" for minutes. I know it’s not an elegant way to do it but it will have to do until i can find a way to get the ID for those controls. (Hopefully SP will always render the controls in the same order, because otherwise the values will get set in the wrong order).

Thanks to Rob and to the many commenters for this code. I needed to populate a custom column when uploading documents so I used this tip on EditForm.aspx. My parameter value is in the URL when the upload button is pushed, but by the time I get to EditForm.aspx, the Source URL has been encoded (the "?" to "%3F" and "=" to "%3D"). So I just had to insert a couple of lines to convert those characters. If I had more than one parameter, I guess I would have had to add an additional line to convert "%26" to "&".

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

qs = qs.replace("%3F","&");

qs = qs.replace("%3D","=");

The other thing I added was to check to see if "Mode=Upload" was in the URL so it would only populate the field on upload.

Above is the asp code from a page, say page A, where people fill out a form like name, phone, email, etc and hit submit button. In my sharepoint site, say page B, I have created a custom list with exactly same fields as it appears in the form. When the user fills the information in page A and hits submit button, how do I pass those values to prepopulate in the custom list when I open page B. both page A and page B are on different servers now? How would it be done if they were in the same server. if it can be done, where exactly I need to do the change in code?

Do i have to define them into dataview?? I m currently using this logic to auto populate one drop down. Works gr8, but wne i try and do it for 2 drop down, i get random values selected into second drop-down. Would you please share something that can help little extra.

Do i have to define them into dataview?? I m currently using this logic to auto populate one drop down. Works gr8, but wne i try and do it for 2 drop down, i get random values selected for second dropdown. I m using ID – query string to pass the values from previous page. Would you please share something that can help little extra.

Can anyone please help me hide a form field of type "Persons and Groups" in newform.aspx using the javascript I used here in the following post. Everything hides except the "Persons and Groups" type of field 🙁

I have tried to add some script code to my SharePoint site (NewForm.aspx and EditForm.aspx ) but it is not working. I simply added the following code near the bottom of the script directly above the </body> tag:

<script>

_spBodyOnLoadFunctionNames ("Bob");

function Bob()

{

alert(‘Hello World’)

};

</script>

When opening the two pages nothing happens. Normaly I expected to see a message box.

This is NOT working for me!!! I don’t know why, but after pasting the code into my "NewForm.aspx" and testing it in a browser, I notice that regardless of what I put in my querystring I only get the first item from my list in the dropdown. If I leave the querystring off completely the dropdown is empty, so I’m confident the script is running and attempting to set the dropdown, but for some odd reason, its setting it to the first drop down value no matter what I put in the query string.

I wonder if there is a method to retrieve the data in the lookup when it has more than 20 items. The "ShowDropdown" function fails, I really don’t know why. Can someone help me? It is really important!

I’ve just spent days building out a similar set of functions to prefill form elements, hide "columns", convert other editable fields to read-only, etc. only to discover that when viewing sharepoint pages with Internet Explorer some of the dropdown fields are rendered as some sort of highly modified input field instead of a standard select element (while other dropdown fields use the select element – bizarre!). Where have the select elements gone?!

In an input-element-dropdown field how do you add, remove or sort "options"? How do you determine which "option" is selected? How do you programatically select an "option".

I managed to take control of a single lookup with less than 20 items and of a multiple lookup; still, the simple lookup with more than 20 items fails on "ShowDropdown" function! I really don’t understand why… could someone help me? It is really important! I have the ID of the lookup (that is an input, correct); if I query the value of this Lookup it is undefined. I can’t access objects inside the lookup when they have more than 20 items.

For Frank W: Try to put the ;(semicolon) after alert(‘Hello World’); instead of putting it after the bracket!

Referring to the original post, please can someone explain to me like i’m a 10 year old how to get this script to work???

I’m assuming its a CEWP in the newform.aspx. What is the <<FIELD DISPLAY NAME>> supposed to be and what is the <<QUERYSTRING VARIABLE NAME>>? Is one a column name and the other an entry in the column?

What does this function do exactly? I don’t quite understand this: "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. "

Sorry but I am completely lost and judging by the responses, this is something not to be missed!

I am working on a sharepoint intranet portal, Initially on the master page of the portal it was the simple search option but i want advance search so i changed the search option from simple to advance but litrally i am facing one error when i open my site it shows an error that is error on the page & when i click on the error the description is "document.getElementByID(…) is null or not an object" on the left bottom side of my page.

I am trying to ‘grab’ the values from a newform.aspx (customized) using Javascript in order to calculate a total for an expense form. I have an expense field, a miles field, a mileage rate field (prepopulated with the default federal standard .550 and ControlMode = "display" so the user cannot accidentally edit the rate. I have "hidden" this field by enclosing it with a span tag and setting the color to "white" via style. All fields are given default values. The idea I am going for is that onload, the script executes, gets the values from the appropriate fields, calculates total = mileagerate*miles + expense and prints the total amount at the bottom of the table. Additionally, I would like to set the "miles" and "expense" fields to trigger the same function onchange.

My problem is that I am grabbing something, but what i am storing in my variables is not the text or value that the control contains but (I assume) the object ID. I think this because when I test by printing to screen via document.write([a variable]) I end up with a td cell containing [object]. I am very new to Javascript, everythin I’ve figured out is from the past two days, some experience with programming. My script is below, all of which is located immediately the placeholdermain ID.

I’ve spent a while now trying to get this to work now, and have found that setSelectedOption() is not working cause it’s trying to match a title string which appears in the lookup field to the corresponding item ID…

Is there something that can be simply changed in the script rather than having to change all the calling pages?

In case anyone had the same issue as me, whereby the passed value is the lookup value rather than it’s ID, just change the test inside setSelectedOption()’s loop from opts[i].value to opts[i].text, so it should look like blow afterwards.

Has anyone run into the situation where when re-populating a choice field drop down, this generates an error when the user hits ok to save the data? I believe it is because my choice drop down starts with only one option in it (<<Select>>). I then populate it with several pieces of data using:

function SetOptions(select, value)

{

var opts = select.options;

opts.length=value.length+1;

var l = opts.length;

if (select == null) return;

for (var i=1; i < l; i++)

{

opts[i].innerText=value[i-1];

}

return false;

}

select is the drop down and value is the array of values to populate the control with. If I select the first option in the array, my form will save using the <<Select>> value. Any ideas on how to get it to accept my new array of values?

I am supposed to populate a sharepoint form created by ANOTHER team (so I have no developer/admin access to make any code changes)

When I populate this form, it has many fields which have fixed values

I am looking for a way to automate filling these fields, and leaving just the other fields unpopulated. As you can see, I cannot use any code/designer method that involves THAT team having to make code changes (although that woldbe the cleanest and most efficient method – but that’s corp culture for you)

Maybe a VBA script/macro..is there a way?

FYI – its a custom list form, and has text boxes, lists and radio buttons

Here is the code that you can cut and paste onto your own site, but it is recommended to download the jPoint.zip file at http://jPoint.codeplex.com and put the files into a document library. For the field names in the URL parameter, remove whitespace and special characters. Just the field names; the values can have spaces and such. (i.e. ?AssignedTo=The Team!)

If you are looking for a solution with cascading lookups for MOSS 2007 I can recommend the following over all recipe:

Use regular text fields (columns) and change them dynamically at runtime to combo boxes with help of Jquery. Then use SPlookup (Codeplex, library to easily use MOSS/WSS web service calls like "get list items) to get/filter values. Lookup values are stored in Sharepoint lists instead of lookup fields. The code for this is implemented as Java Script and then linked in to your master pages with logic to determine what pages the script should be active on (edit form & new form for example). No need to use CEWP to activate code (just messy).

This gives you two important benefits: A) The values (eg corporate taxonomy) can be managed by permissions on lists/sites instead of giving persons access to "site admin functions" needed to alter lookup column values. B) You avoid the hassle with lookup fields (described above). This "architecture" also lend itself well to be implemented for DIP (Document Information Panel) where you can easily add combo boxes with values from these SharePoint lists and filter them accordingly.

NOTE: The "People Picker" control was embedded 12 levels "deep" from the <tr> tag in my NewForm.aspx, and hence I had to use the code in the hideFields() function with 12 "parent" references. I used the awesome Firebug tool to view this hierarchy and to also find out the elusive tagName, identifier, and title info for the People Picker control. The Firebug tool is a FireFox browser addon, and is incredibly helpful when you need to look at raw HTML and JavaScript code that renders SharePoint pages.

Sorry for the delay in my answer. I spent quit a lot of time doing research around this area for one of my customers. All the solutions I found (like 3:e party and such) had some major drawbacks. This was the cleanest solution (in my opinion) although it required some script coding. I especially needed a "no binary install" solution to this project. Here is the link to the Jquery Web Service utility: http://spservices.codeplex.com/. If you want to ask me more questions I can be reached at talk2andrej@hotmail.com

I have created a Parent / Child list releationship on a modified DisplayForm and also then used the above code in a CEWP on an EditForm for the adding new items to the child list. I found a good series of videos on the subject here…

One question though, will a site using these techniques backup & restore ok?

I created a backup of my site, but when I restored it the associated “children” aren’t displayed on the “parent” form (the webpart gives a “non-specific” error), and also the “create new child” page which magically inserts the FK won’t display either…. any ideas why?

I was using backup/restore in SP Designer to create a copy of the site.

I also used Save Site as Template method and also export as Personal Webpackage method these also resulted in similar errors

I'm not sure if this was already mentioned in the comments – didn't feel like browsing through 11 pages of them to find out. But I wanted to mention how to use getTagFromIdentifierandTitle to find a Date Picker field:

Well, I struggled to get this working for a while only to realize my link is passing the display value rather than the ID # of my lookup item. While I am looking for a way to pass the ID in my URL, anyone have a clever method to translate the lookup Value – ID?

When the lookup field item count exceeds to 20 items, it is rendered as different control and setLookupFromFieldName method throws "object expected" error. Use following updated method to resolve this issue.

I have two datetime column type(say 'Business PVE' and 'Proposed Date For Go-Live').Now my requirment is 'Proposed Date For Go-Live' should'nt be earlier than 'Business PVE'..for that i have written client side code using j-Query in SP Designer.the codes are below.for the below code i get error as 'parentNode' is null or not an object…and when i put alert(control); its returning me null..I dont know why this is happening and what's the problem..pls help me out Rob…