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
[javascript]
<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>
[/javascript]

Sourcecode for DispForm.aspx
[javascript]
<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>
[/javascript]
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

101 thoughts on “Dynamic expand/collapse fields or array of fields”

  1. I feel like I am always looking on your site. Havent figured out how to make this work off the headers yet, but I started looking into another option. Is there a way to hide/show the fields by userID, or better yet possibly a sharepoint group?

    Example: Hide the field(s) if user is not part of SPGroupOwners1

  2. Hi again larry,
    To answer your question regarding showing or hiding based on membership – or not membership in a SharePoint group:
    Yes you can!

    I do not have time to write that article right now, but nag me in the beginning of next week if you do not get any response…

    I actually use this method myself.

    Alexander

  3. Hi Alexander,

    I work for Mark Miller at EndUserSharePoint.com. I really enjoyed this article.

    We would like to cross-post your article. As with other authors, we would publish your entire article on EndUserSharePoint.com giving you full attribution with links.

    Please let me know if this is something you would be interested in.

    Best,
    Natasha

  4. Hi again Alexander:
    Can I assume that if I have 30+ questions that each need a dynamic 2nd or 3rd field/question, that this script would get quite lengthy?

    Charlie Epes
    Buffalo, NY

  5. Well…yes, you would need to write code for all questions.
    If you have some sort of logic to them – like if you select option number two – you shall always fill inn some sort of additional question, you can make a function which is called on “click” or “change” event on all questions and build your logic in this function.

    Alexander

  6. Works fantastic, with one exception.. When creating a new list item, the script works fine. But if you go to edit that item, everything is hidden again until you unselect, and then re-select the filter. It would be nice if when going in to edit the item, the script will read what is already in the dropdown and filter the fields accordingly instead of having to select another choice and re select the original.

  7. I ahve been trying to add to this script for a previous request. I should be able to add a line of code on 22 or 25 like this:
    $(fields[arrRed]).val(“”); or $(fields[arrBlue]).val(“”);
    to clear the fields in one array or the other when I toggle between the two arrays, but working. Is it the array reference? or the line of code?

    1. Hi,
      This approach does not work as $(fields[arrRed]).val(“”) tries to address an array, and not a single field – you must loop trough the array and apply the action to each field.

      Secondly the $(fields[‘FieldInternalName’]) gives you the table row, and not the input field itself. To get the input you must write it like this:
      $(fields[‘FieldInternalName’]).find(‘:input’).val(“”).

      If what you want is to clear the value from the field when collapsing, try to set the input field to “disabled” like this: $(fields[‘FieldInternalName’]).find(‘:input’).attr(“disabled”, true).

      This should clear the value for most fields, but i am not sure if this approach does the trick for all field types.

      Alexander

      1. Alexander,

        Can you please elaborate a little more how you can reset (clear) the options in the fields once you toggle between arrays. I’m have trouble getting this to work.

        Thanks,

        Justin

      2. Alexander,

        Can you please elaborate a little more how you can reset (clear) the options in the fields once you toggle between arrays. I’m having trouble getting this to work.

        Thanks,

        Justin

  8. Hi Alexander,

    I don’t know why, but the script doesn’t work for me. I tried to follow your example with the fileds “MySelect” “ShowIfRed1” etc.. I created a list with those columns, after that I added a Content Editor Webpart in my newform.aspx, where I added your source code. But… nothing ^^. After that I checked the FieldInternalNames, and they’re the same like the DisplayNames.
    Is it possible that the code doesn’t work with WSS!? I don’t think so… ^^

    Greez Izzy

    1. Hi Izzy,
      A common mistake is forgetting to move the CEWP below the list form.

      If it is placed below, check if jquery is loaded by adding this alert to the CEWP-code:

      alert($);
      

      It will confirm that the jQuery library is loaded by alerting this text:

      function (E, F) {
          return new (o.fn.init)(E, F);
      }
      

      Alexander

  9. Hi Alexander,
    Thanks for posting this great javascript, I got it working!
    I would appreciate any help you could provide in getting a ReadOnly function to work. Here is what I have found:

    function SetReadOnly()
    { // find all the elements with tag Name as INPUT
    var elements=document.body.getElementsByTagName(“Input”);
    // loop through all the elements till we find an element with type text and title as name of our field
    for (index=0; index < elements.length;++index)
    { if(elements[index].type==“text”) { if(elements[index].title==“My column”) { elements[index].readOnly=true; } } } }
    _spBodyOnLoadFunctionNames.push(“SetReadOnly()”);

  10. Also found this script. Does not work. the field names that are disabled or read only are Title and Choice. put into a CEWP on the EditForm.aspx

    _spBodyOnLoadFunctionNames.push(“disableForm”);
    function disableForm () {
    var disableInput=document.getElementsByTagName(‘input’)
    var disableSelect=document.getElementsByTagName(‘select’)
    for(var i=0; i < disableInput.length; i++) {
    if(disableInput[i].title == "Title" ||
    disableInput[i].title == "Choice") {
    disableInput[i].disabled = true;
    }
    }
    for(var i=0; i

    1. Hi,
      I’m glad you liked the script!

      You find a good solution for setting fields readonly here.

      You find the solution in the file “fieldutility.js”.

      Erucy’s solution uses the function init_fields() to locate the fields, but his function uses DisplayName to identify them and not the FieldInternalName as mine does. My function “init_fields” is adapted from his original one, but you will have to replace his function in the file with the one used in the above script.

      Alexander

  11. Alexander,
    Thanks for your response!
    Sorry to be troublesome. I downloaded the Word Doc, it looks like this:

    SharePoint 2007 JavaScript Lib Document

    作者:杜伟(Erucy) MVP of SharePoint Services
    版本:1.0
    最后更新:2009-2-3

    一、概述
    1、简介
    本JavaScript库主要分为两部分:使用js访问SharePoint列表(列表条目的增加、删除、修改和查询);使用js控制SharePoint默认的列表表单(新建和编辑页面),提供各字段的读取、设置、只读、隐藏以及字段之间的关联等功能。
    本库基于jQuery完成。在MOSS 2007企业版(with SP1)、jQuery 1.2.6、IE6/IE7/FireFox 3.0下经过测试。如果由于SharePoint本身对浏览器功能的支持不同,可能会导致部分功能仅针对IE有效,会在各方法说明中会具体指出。

    1. If your Chinese is a little rusty, run it trough Google Translate – you can upload the file and get a full translation (not perfect, but absolutely readable).

      If you use some of the script examples – pull them from the original file and not from the translated version.

      Alexander

  12. Here is what I have working to make multiple TEXT items ReadOnly:

    function check()
    {
    var elements=document.body.getElementsByTagName(“*”);
    for (index=0; index < elements.length;++index)
    {
    if(elements[index].tagName=="INPUT" && elements[index].type=="text" && (elements[index].title=="Review Item" || elements[index].title=="Primary Fail Reason" || elements[index].title=="Secondary Fail Reason" || elements[index].title=="Title" ))
    {
    elements[index].readOnly=true;
    }
    }
    }

    _spBodyOnLoadFunctionNames.push("check()");

    1. Hi,
      I was maybe not to detailed in my last answer. What i wanted you to do was to download the scripts from the codePlex-page, and make a CEWP-code like this (placed BELOW the form in EditForm):

      <script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
      <script type="text/javascript" src="/test/English/Javascript/fieldutility.js"></script>
      <script type="text/javascript">
      fields = init_fields();
      // To make a MultiLineText field of type HTML - with FieldInternalName of 'MultiLine'
      readonlyField(fields,'MultiLine','html');
      
      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>
      
      

      Note that the function “init_fields()” from the “fieldutility.js” needs to be replaced with the one from the code above (to shift the identifier from DisplayName to FieldInternalName).

      Alexander

  13. Hi Alexander,

    How would you need to amend the code in order to make this work if you have different drop down fields hiding and showing a different field for each drop down?

    Thanks

    Andrew

  14. Hi,
    In line 13-21 i have added a function to the click-event on the dropdown, and a onload-call to the function to deal with the selection when the page loads (either EditForm or NewForm on refresh by form validation).

    In this code i have specified the FieldInternalName (MySelect) of my dropdown.

    This code has to be duplicated x-number of times to adapt to your fields.

    Alternative you could make some sort of looping function (to avoid duplicating the code) – depending on the names of your fields.

    Arrays of the fields to hide must also be made.

    Ask again if you do not get it right.

    Alexander

  15. Thanks Alexander I have tried duplicating the code you mentioned but each of the drop down fields unhide the same field. I want each of the drop down fields to unhide a specific field.

    Andrew

  16. I think it is due to this code when toggling as it only looks at my first array:

    function dynamicDisplay(answer){
    // Hide all initially
    toggleArr(arrToHide,true);
    if(answer==’Yes’){
    toggleArr(arrYes,false);
    }
    }

    1. Hi Andrew,
      This code is tested in a list containing two drop-downs with FieldInternalName “MyFirstDropDown” and “MySecondDropDown”. The choises in these drop-downs are “Yes” and “No”.

      I have two additional fields (not important what type), named “MyFirstField” and “MySecondField”.

      This code shows the corresponding field if the drop-down’s value is “Yes”, and hides it if it is anything else (blank or “No”).

      NewForm and EditForm

      <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 - can contain unlimited number of fields
      var arrFirstDropDown = ['MyFirstField'];
      var arrSecondDropDown = ['MySecondField'];
      
      // Concatenate all arrays
      var arrToHide = [];
      arrToHide = arrToHide.concat(arrFirstDropDown,arrSecondDropDown);
      
      // Onchange
      	// First
      	$(fields['MyFirstDropDown']).find('select').change(function(){
      	var thisVal = $(this).find('option:selected').text();
      		dynamicDisplay(arrFirstDropDown,thisVal);
      	});
      	// Second
      	$(fields['MySecondDropDown']).find('select').change(function(){
      	var thisVal = $(this).find('option:selected').text();
      		dynamicDisplay(arrSecondDropDown,thisVal);
      	});
      
      // Onload
      	// First
      	var thisVal = $(fields['MyFirstDropDown']).find('option:selected').text();
      	dynamicDisplay(arrFirstDropDown,thisVal);
      	// Second
      	var thisVal = $(fields['MySecondDropDown']).find('option:selected').text();
      	dynamicDisplay(arrSecondDropDown,thisVal);
      
      function dynamicDisplay(arr,myVal){
      // Hide all initially
      toggleArr(arr,true);
      	// Show the array if the value is "Yes"
      	if(myVal=='Yes'){
      		toggleArr(arr,false);
      	}
      }
      
      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>
      

      DispForm

      <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 - can contain unlimited number of fields
      var arrFirstDropDown = ['MyFirstField'];
      var arrSecondDropDown = ['MySecondField'];
      
      // Concatenate all arrays
      var arrToHide = [];
      arrToHide = arrToHide.concat(arrFirstDropDown,arrSecondDropDown);
      
      // Onload
      	// First
      	var thisVal = $(fields['MyFirstDropDown']).find('.ms-formbody').text().replace(/s|xA0/g,'');
      	dynamicDisplay(arrFirstDropDown,thisVal);
      	// Second
      	var thisVal = $(fields['MySecondDropDown']).find('.ms-formbody').text().replace(/s|xA0/g,'');
      	dynamicDisplay(arrSecondDropDown,thisVal);
      
      function dynamicDisplay(arr,myVal){
      // Hide all initially
      toggleArr(arr,true);
      	// Show the array if the value is "Yes"
      	if(myVal=='Yes'){
      		toggleArr(arr,false);
      	}
      }
      
      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>
      

      Regards
      Alexander

  17. Hi Alexander,

    Awesome scripts and support! So now.. How do I get this to work with custom list form controls? It seems to only work on the default list form control.

    My use case – I need a custom “New” list form control that has hidden fields that are pulling data from some string variables for a parent child relationship and some DVWPs. I have that part. But if I use this code on a custom list form it wont hide the feilds… Help!!!
    Thanks in advance!!!
    -J

    1. So this is me “asking again”. I was able to make the custom form work. But now I was wondering how to refine the code. Using the link that you linked “Wrap choice-field in multiple columns”, you made mention (11/5/09 11:41pm) in a post:

      “To address the fields on a custom form you have to find another way of addressing these fields and to “objectify” them in the same matter as the script init_fields(). Basically you could insert some kind of “identifyer-attribute” on the tr’s”

      Can you please provide an example of this for this form? I tried to give the ifreds and ifblues, id’s and call it on in the code and I couldnt get it to work.

      Thank you so much for your time Alexander!!!

  18. Beautiful genius!!!! It took me a bit to figure out that I had to change the “fields = init_fields();” to “fields = init_fields_CustomForm();” but after I did that it works like a charm! Thank you for all the awesome work, please keep it up!

    -J

  19. Hello,

    i first added the jquery-1.3.2.min.js to document libary Javascript and created the colums to the list test. then i added the cewp below the form in newForm.aspx with the sourcecode for newForm.aspx.
    but it doesn’t work.
    i also tried to insert alert($); and i think that the jquery is not loaded.

    thanks

  20. hello,

    there is a field “date” in my newform and i want to add days to the current date depending on the value of a dropdown list.

    can somebody help me?

    thanks

  21. Hi Alexander

    How do you create the script to work if you have one drop down field that shows a field based on yes and no and another drop down that shows a number of fields depending on a numbers (1,2,3,4,etc)?

    Thanks

    Andrew

    1. Hi,
      Sorry for late reply – very busy at work these days, and not so much spare time to attend to my blog…

      You would have to add another function like “dynamicDisplay”, and add the logic on the selected numbers rather than the colors.

      You must also add the “Onload” and the “Onclick” to the choice-field. Reuse the ones in the example, just replace the function name to point to your new function.

      Alexander

      Alexander

  22. Great Post just ike your Blog.

    But i have just one Question. How can i fixed the following Problem. I show a Textfield when status has changed, but how can i proof that there is content in the new field wich is showing up. I want customers to have to write something in the textbox when it´s expand.
    Setting the Property in the Columnpoperty doesn´t do the Trick because it allways wants to be that there is Content in the field when clicking the OK- Button even when it is collapsed.

    1. Hi,
      Sorry, but i missed this. Here is an example:

      function PreSaveAction(){
      var okToSave = true;
      var myTriggerFieldVal = $(fields['MyYesNoTriggerField']).find('input:checkbox').attr('checked');
      	if(myTriggerFieldVal){
      		var arrToCheck = ['CheckThisColumn'];
      		$.each(arrToCheck,function(i,fin){
      			var thisVal = $(fields[fin]).find(':input').val();
      			if(thisVal==''){
      				alert("You must enter a value for "My field name here".");
      				okToSave = false;
      			}
      		});
      		return okToSave;
      	}
      // If validation is not triggered, return true
      return true;
      }
      

      This example looks at a Yes/No-field named “MyYesNoTriggerField”, and if it is checked, it looks if the fields specified in the array “arrToCheck” is filled (example uses a single line text field to check, you must adapt the code for radio button or other field types).

      If they are not, it gives an alert and interrupts the save process.

      Add this function to the script in the original post.

      Alexander

  23. I am very new at this and have had no success in getting this to work for me. I’ve placed the CEWP under the form. I’ve added to the script …
    alert($);
    function (E, F) {
    return new (o.fn.init)(e, f)’
    }

    As you outlined in a response. I’m just wondering if it’s calling the jquery at all? Please Help! Thanks Ron

    1. Hi,
      To test if the jQuery library is loaded, you write this line:

      alert($);
      

      The alert this one gives if jQuery is loaded is this:

      function (E, F) {
          return new (o.fn.init)(E, F);
      }
      

      Alexander

  24. Thanks…. This is working for me now. Always end up being (do I dare say it?) User Error.
    So now I need help again.
    I have the code running perfectly for one select and opens other fields but I need to have another field select to open hide/open other fields. Cant figure out how to code this.

  25. Pasted code into a CQWP and create fields as shown. Nothing happens! Tested jQuery and it is obviously loaded and working. Any idea why code does not work. Something missing?

  26. Hello,
    i have some problems with this script.
    When putting alert($) before line 11 it shows me that jquery is loaded. Putting puttin it after Line 11

    toggleArr(arrToHide,true);

    it shows me nothing. Anny help on that?

    Thanks Maik

  27. Hey Alexander,

    Great Code, this is really helping me build a great feedback form. A question though, is there anyway to sort the array alphabetically if I add a new item to the end of the array?

    For example –>

    Array 1: [0,1,10,2]
    Array 2: [3,4,5,6,7,8,9]

    On the newform.aspx however it appears

    Array 1: 0, 1, 2, 10

    I’d like for it to display:

    Array 1: 0,1,10,2

    I’d rather not have to rhift the numbers every time I add a new choice, thanks for your help!

    1. Hi,
      Yes it does, sorry for the delayed response, but I’m a bit overloaded with questions…

      The sorting is not altered in this script, it is the same sorting as the original choices configured when creating the field in the list settings.

      I guess it would be possible to rearrange the options without breaking the field, but I’m afraid i do not have the time to do that right now.

      Alexander

  28. Is there an easy way to incorporate this with the side by side script and toggle the fields aligned in a single row?

    Cant quite figure out how to hide that row now the the format of it has changed

    1. Hi,
      I guess you will have to address the field with an extra “.parents(‘tr:first’)” to get the full row, but i have not had the time to test it.

      Alexander

  29. Hi Alex,

    Using your code above to check for blank fields, how would I modify this to work with a Person or Group field? I’ve tried both input and select, input will always return the field as blank, select always sees the field as having data.

    Also, I think this question is similar to Larry’s above but if I have a row of fields, is there a way I can mark the entire and hide that? Here’s an example of a row (I hope):

    
    
    
    
    
    
    
    
    
    
    
    
  30. Thanks, here’s the code. Can I tag the TR with an empty class just to identify it for the script? I have 30 of these rows and I want to hide them in groups of 5.

    <tr>
    <td valign="top" class="ms-formbody">
    <SharePoint:FormField runat="server" id="ff47{$Pos}" ControlMode="New" FieldName="Column1" __designer:bind="{ddwrt:DataBind('i',concat('ff47',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Column1')}"/>
    </td>
    <td valign="top" class="ms-formbody">
    <SharePoint:FormField runat="server" id="ff48{$Pos}" ControlMode="New" FieldName="Column2" __designer:bind="{ddwrt:DataBind('i',concat('ff48',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Column2')}"/>
    </td>
    <td valign="top" class="ms-formbody">
    <SharePoint:FormField runat="server" id="ff49{$Pos}" ControlMode="New" FieldName="Column3" __designer:bind="{ddwrt:DataBind('i',concat('ff49',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Column3')}"/>
    </td>
    </tr>
    
    1. Hi,
      As long as you can identify them, you can hide them. Using jQuery, you can hide a row by using its id. Add an id attribute like “yourUniqueIdHere” to your <TR> and hide it like this:

      $("#yourUniqueIdHere").hide();
      

      Alexander

  31. Hi Alexander,

    great peace of work.
    Your solution helped me out with a WSS 3.0 solution i had to build for a customer.

    Now i’m migration to sharepoint foundation 2010. I’m trying to use your code in the new forms. Unfortunally it does not work.

    Is there a possibility to get your code running under SP 2010 ?

    Greets
    Marco

    1. Hi Alexander,

      sorry for my late reply …
      you’re absolutely right. it works fine with SP2010 forms.

      i tried it on a form which already had injected your code from “Cascading dropdowns in SharePoint text fields – populated by lookup in another list (version 2)”.

      combining these two scripts doesn’t seem to work. depending on how i arrange the CEWPs eather one or the other script works.

      is there a way to get both of your scripts running in one form ?

      Greets
      Marco

    2. There can be some difficulties because both the scripts hide and show fields. If the scripts refer the same fields, you may want to wrap the call to the “cascading dropdowns” in the “expand” function so that it is not called when the fields are supposed to be hidden.

      Alexander

  32. Hi Alexander,

    ive been running your script for some time and it worked perfectly. the users that had access to the list using it till now had rights to all intranet sites so far.
    Now i added some new users that only have access to this one list with add/remove/edit rights.

    For those new users, all forms show all fields all the time and ignore the jquery/javascript code.
    The Source code is the same and the javascript is in there for both type of users.

    i am using wss3.0 and have no idea why it doesnt work for those restricted users.

    if u know what could be the problem id really appreciate if you could give me some advice.

    Tim

    1. Hi,
      This certainly has to do with user rights, but i have no immediate fix. Try to load jQuery from Google and see if that does any difference:

      <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
      

      Alexander

  33. I tried your code and it does not work. Do you see anything wrong here? I have data in my list and I have renamed most of the fields to match the code. Would this cause issues?

    fields = init_fields();

    // Arrays of fields to show or hide
    var arrPM = [‘pm1′,’pm2′,’pm3′,’pm4′,’pm5′,’pm6’];
    var arrPO = [‘po1′,’po2′,’po3′,’po4′,’po5′,’po6’];
    var arrCM = [‘cm1′,’cm2′,’cm3′,’cm4′,’cm5′,’cm6′,’cm7′,’cm8’];

    // Hide all onload
    var arrToHide = [];
    arrToHide = arrToHide.concat(arrPM,arrPO,arrCM);
    toggleArr(arrToHide,true);

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

    // Onload
    var c = $(fields[‘SelectRole’]).find(‘option:selected’).text();
    dynamicDisplay(c);

    function dynamicDisplay(Role){
    // Hide all initially
    toggleArr(arrToHide,true);
    if(Role==’Project Manager’){
    toggleArr(arrPM,false);
    }
    else if(Role==’Program Office’){
    toggleArr(arrPO,false);
    }
    else if(Role==’Change Management’){
    toggleArr(arrCM,false);
    }
    }

    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;
    }

    1. Hey Meghan,
      Implemented correctly this code works. When I compared your code side by side I found slight minor differences and these differences may only be cause by the blog posting. Some of the single ticks as different
      Some like this: ‘
      and Some like this: ’
      slight variations, and as I said may be attributed to the blog post.

      This first this that comes to mind when I read “I have renamed most of the fields to match the code.” in your post is there is a difference in the DisplayName and the FieldInternalName (FIN). A’s script always uses the FIN. If you renamed your fields then you may not have the correct FIN.

      A has a post on how to find the FIN. I have found the most likely reason for script failure is me having the wrong FIN, The second is my source path.

    1. This site A has put together has many resources. It may take some time but if you look and read you will eventually find what your looking for. On is home page he has several links related to using this site and other references. If you go through this post it may help you to understand the FIN and also has a link to what your looking for.
      http://spjsblog.com/2010/01/25/how-to-use-these-scripts-in-a-customized-form/
      It is important you try to read most of the stuff on the home page. it has steps for troubleshooting and other impportant information.

      good luck

  34. Hi,
    I need to add in each array 20 fields,
    like var arrRed = [‘ShowIfRed1′,’ShowIfRed2’………’ShowIfRed20’];

    And Myselect have 6 different colors.For the above script is not working.Could you please help the required changes i have to do.

    1. Hi,
      Try duplicating this part for your second dropdown:

      // 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"");
      	}
      }
      

      The function name for “dynamicDisplay” should be changed for the second instance to not interfere with the first.

      Alexander

    1. Hi,
      I put together an example for you:

      <script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
      <script type="text/javascript">
      fields = init_fields();
      
      /************* First choice column *******************/
      // Arrays of fields to show or hide
      var arrRed = ['Field1','Field2'];
      var arrBlue = ['Field3','Field4'];
      
      // Hide all onload
      var arrToHide = [];
      arrToHide = arrToHide.concat(arrRed,arrBlue);
      toggleArr(arrToHide,true);
      
      // Onchange
      $(fields['MySelect1']).find('select').change(function(){
      var c = $(this).find('option:selected').text();
      	dynamicDisplay(c);
      });
      
      // Onload
      var c = $(fields['MySelect1']).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);
      	}
      }
      
      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();
          }
        }
      }
      
      /************* Second choice column *******************/
      // Arrays of fields to show or hide
      var arrGreen = ['Field5','Field6'];
      var arrPurple = ['Field7','Field8'];
      
      // Hide all onload
      var arrToHide2 = [];
      arrToHide2 = arrToHide2.concat(arrGreen,arrPurple);
      toggleArr(arrToHide2,true);
      
      // Onchange
      $(fields['MySelect2']).find('select').change(function(){
      var c = $(this).find('option:selected').text();
      	dynamicDisplay2(c);
      });
      
      // Onload
      var c = $(fields['MySelect2']).find('option:selected').text();
      dynamicDisplay2(c);
      
      function dynamicDisplay2(color){
      // Hide all initially
      toggleArr(arrToHide2,true);
      	if(color=='Green'){
      		toggleArr(arrGreen,false);
      	}
      	else if(color=='Purple'){
      		toggleArr(arrPurple,false);
      	}
      }
      
      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>
      

      Alexander

    2. Alexander,
      I’ve tried your revised script to accommodate two drop-downs, but when I choose from the second drop-down, the fields expanded by the first drop-down are collapsed again. Any thoughts?

      Tim

    3. Soooo weird. So, I took your code and created a new list with the field numbers as you have. I tested and it worked. Now, if I implement this to my edit form, it does not show the second colum if I add the field in the array nor it would work with any of the choices. Going to try again later!

  35. should this function be a second one on line 78? Mine is still not working.
    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();
    }
    }
    }

  36. Hi, can this be applied to a custom form? It works great when I use the default NewForm.aspx, etc. but I have created a New.aspx in order to add some functionality, but I cannot get this to work via CEWP or by putting the code on the page via Designer. Any thoughts?

  37. Hi, this script is fantastic. It works great in IE8 and IE9, but I am not able to get this working in any browser other than IE. Safari and Chrome simply will not hide the fields on either a Mac or PC. Any suggestions to make this work would be greatly appreciated.

Leave a Reply