CRM 4.0: Checkbox style Multi-Select Picklist

Our guest blogger is CRM MVP Jim Wang joining us from Reading England. Jim blogs regularly at Microsoft Dynamics CRM – Jim Wang’s technical blog [MVP].

CRM 4.0 doesn’t have many out-of-box user controls, such as multi-select picklists. The standard CRM picklist can only save one value in the database, it’s not easy to extend this functionality, in addition, you have to deal with the Advanced Find feature.


You can make a picklist multi-selectable by enable the picklist multiple attribute , e.g: crmForm.all.new_picklist.multiple = true; And then save the selected values somewhere else. However, it does not very impressive the user because the user has to use the CTRL key to select options, which is not user-friendly (Thanks for Alastair Westland (PM @ Parity) who work with me to improve the interface design:)

The script below will draw a checkbox style multi-select picklist control on the CRM form, and then get options from the real picklist attribute. So how to use it?

1. Create a standard picklist attribute with all options in CRM, put it on the CRM Form. e.g: new_picklist;
2. Create another nvarchar attribute in CRM to save the selected text, put it on the CRM Form and hide the label. e.g. new_picklistvalue;
3. Put the following script in the Form.OnLoad() event.

   1: 01./* 
   2: 02.Checkbox style Multi-Select Picklist 
   3: Jim Wang @ January 2009 
   4: 04. 
   5: 05.*/  
   6: 06.  
   7: 07.// PL – the picklist attribute; PLV – used to save selected picklist values  
   8: 08.var PL = crmForm.all.new_picklist;  
   9: 09.var PLV = crmForm.all.new_picklistvalue;  
  10: 10.  
  11: 11.if( PL != null && PLV != null )  
  12: 12.{  
  13: 13. = “none”;  
  14: 14. = “none”;  
  15: 15.  
  16: 16.  // Create a DIV container  
  17: 17.  var addDiv = document.createElement(“<div style=’overflow-y:auto; height:80px; border:1px #6699cc solid; background-color:#ffffff;’ />’);  
  18: 18.  PL.parentNode.appendChild(addDiv);  
  19: 19.  
  20: 20.  // Initialise checkbox controls  
  21: 21.  for( var i = 1; i < PL.options.length; i++ )  
  22: 22.  {  
  23: 23.    var pOption = PL.options[i];  
  24: 24.    if( !IsChecked( pOption.text ) )  
  25: 25.      var addInput = document.createElement(“<input type=’checkbox’ style=’border:none; width:25px; align:left;’ />’ );  
  26: 26.    else  
  27: 27.      var addInput = document.createElement(“<input type=’checkbox’ checked=’checked’ style=’border:none; width:25px; align:left;’ />’ );  
  28: 28.  
  29: 29.    var addLabel = document.createElement( “<label />”);  
  30: 30.    addLabel.innerText = pOption.text;  
  31: 31.  
  32: 32.    var addBr = document.createElement( 
  33: 33.”); //it’s a ‘br’ flag  
  34: 34.  
  35: 35.    PL.nextSibling.appendChild(addInput);  
  36: 36.    PL.nextSibling.appendChild(addLabel);  
  37: 37.    PL.nextSibling.appendChild(addBr);  
  38: 38.  }  
  39: 39.  
  40: 40.  // Check if it is selected  
  41: 41.  function IsChecked( pText )  
  42: 42.  {  
  43: 43.    if(PLV.value != “”)  
  44: 44.    {  
  45: 45.      var PLVT = PLV.value.split(“||”);  
  46: 46.      for( var i = 0; i < PLVT.length; i++ )  
  47: 47.      {  
  48: 48.        if( PLVT[i] == pText )  
  49: 49.          return true;  
  50: 50.      }  
  51: 51.    }  
  52: 52.    return false;  
  53: 53.  }  
  54: 54.  
  55: 55.  // Save the selected text, this filed can also be used in Advanced Find  
  56: 56.  crmForm.attachEvent( “onsave” , OnSave);  
  57: 57.  function OnSave()  
  58: 58.  {  
  59: 59.    PLV.value = “”;  
  60: 60.    var getInput = PL.nextSibling.getElementsByTagName(“input”);  
  61: 61.  
  62: 62.    for( var i = 0; i < getInput.length; i++ )  
  63: 63.    {  
  64: 64.      if( getInput[i].checked)  
  65: 65.      {  
  66: 66.        PLV.value += getInput[i].nextSibling.innerText + “||”;  
  67: 67.      }  
  68: 68.    }  
  69: 69.  }  
  70: 70.}  


Jim Wang

UPDATE: This technique is actually an unsupported customization. Implementing this will place your implementation in an unsupported state. Be sure to remove this customization before calling support for any issue.

Comments (33)

  1. pankaj lahoti says:

    hai ,

    i m newbie .I was searching for this it helped me alot thanks alot and hope will find more help in near future

  2. Kamaldeep Singh says:

    It doesnt seem to work for me 🙁

    Error on page .. any help will be great !!!

  3. Jeremy says:


    A description of the error would be needed in order to trouble shoot.

  4. stella7113 says:

    How can I add this script for multiple lists?

    In the form event? it will become too long.

  5. John says:

    Jim, thanks for the code.

    Line 32 & 33 of your code is split up; what is the actual argument value between the double quotes " "? is it supposed to be a blank character?


  6. Jim Wang says:

    Hi John,

    It’s a  <br />  flag.



  7. Jim Wang says:

    Hi guys,

    You can go to my blog to copy the whole source code. Please let me know if you have trouble about it.



  8. stella7113 says:

    How can I add this script for multiple lists?

    In the form event? it will become too long.


  9. Linna Tomlinson says:


    Thank you so much for the code.  Worked like a charm!  I had 2 multipicklist on the form putting your entire code into a function and calling it with the 2 form elements as parameters.  And voila!

    Thanks again!


  10. Prince says:

    Hi Jim,

    I tried your code and it works pretty smooth, Thanx. But then the issue crops up if I am giving the new_picklist attribute as "Business Required" and trying to save the form, CRM is prompting "No value for products". Hence I have to remove the business required field and assign it as no constraints and it works well.

    Any suggestions would be appreciated?


  11. AlexMC says:

    Hi, I trayed, but it doesn´t works, just appears both fields (Picklist and Navchar) but not the boxes; what I´m doing bad?

  12. Pierre says:

    I am just getting the 2 boxes on the screen.  I have named the fields exactly what you did in your code.   This is the only script on the object.  


  13. Ketki says:

    I have done everything as you mentioned but it is not displaying anything. Textbox and picklist are coming in their normal formats.

    Suggest something?

  14. John says:

    Brilliant, works really well.  Thanks a lot for this.  I have 5 picklists all using your code wrapped up in a function working just the same as Linna describes above.

    function customerproblems(pickList, pickListValue)


    // PL – the picklist attribute; PLV – used to save selected picklist values

    var PL = pickList;

    var PLV = pickListValue;

    …then all other code as supplied







  15. Sonny says:

    Hello, I have the same problem like the others above.

    I created the attributes, printed them on the form and copied the code into onLoad. Also corrected the br-flag. But I’m still getting two boxes on the screen and no checkboxes with multipicklist style.

    Soon answer would be great!

  16. Heti says:

    Hi Jim

    Thanks for the code, works nicely. Our biggest problem was when using advanced find. In order to get the correct search results, we have to enter || in the search criteria to search for more that one entry and to spell the attribute name exactly as it is in the code. Is there an easier way to get this customization to work with advanced find in an easier manner?

  17. yiannis t says:


    may anyone knows how can we fire the onchange event when we change a value in the field (crmForm.all.new_picklist)?

    Thanks Yiannis

  18. Matthew S says:

    for the guys and gals who couldn’t get this to work, you need to make sure the break tag is added and that you make sure that things like:

    var addInput = document.createElement("<input type=’checkbox’ style=’border:none; width:25px; align:left;’ />’ );


    var addInput = document.createElement("<input type=’checkbox’ style=’border:none; width:25px; align:left;’ />" );

    notice the double quotes at the end.  that fixed it for me. works great.

  19. Bill G. says:

    I have this code working wonderfully in an implementation of CRM on a SBS2003 server.  The system redeployed to a 64 bit, SBS2008 server with SQL 2008 and it no longer works.  It looks good in the preview page and there are no script errors at run time, but publish the changes as I may, the GUI shows the pick list as a standard pick list instead of a multi-select format.  

    Any thoughts?

  20. Raji says:

    Great post. It worked like a charm

  21. Suzan says:

    Hello Jim,

    I have the code working good.  However, I am getting an error msg "You must provide a value for the picklist.  Plus the textbox has no value displaying.  Do I missing something.  Please let me know. Thanks.

  22. Augusto says:

    Hi Jim

    Great post. It worked like a charm. This particular field I would like to make it mandatory. Do you have an idea how can I make it to work?


  23. Shawn G. says:

    For those people who are wondering how to make this required.  It should be something like this:

    NOTE: I have not tried this myself, but it should work.

    1. Change the OnSave function to the following

    function OnSave()  


     PLV.value = "";  

     var getInput = PL.nextSibling.getElementsByTagName("input");  

    var oneItemChecked = false;

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


       if( getInput[i].checked)  


         PLV.value += getInput[i].nextSibling.innerText + "||";  

         oneItemChecked = true;





       alert("At least one item must be selected."); //<–Change this text

       // You could also show an error label here.  This lets the user know why the save failed…

       // Appending a div to PL.parentNode would accomplish this


       return false;



    2. You should probably also require the nvarchar attribute (to make sure you don't have issues with plugins, if this javascript fails, etc.).  

  24. Joe Arkley says:

    I could not get it to work either. I am using SQl 2008 and Server 2008 64 bit so guessing its version specific

  25. srinivas says:

    Hi, its brilliant its help me alot.nice code

  26. kevin says:

    For those of you having difficulty getting the code to work, put this code into the Onload event code and it will work –

    Be sure to change the lines to use your attribute name

    var PL = crmForm.all.new_role;  

    var PLV = crmForm.all.new_hiddenrole;  

    I used new_role for the picklist and new_hiddenrole for the hidden string that carries the multiple picklist selections.

    The initialize checkbox loop is wrong in the example and should count form '0' and not '1'. The error shows up as not seeing the first picklist selection.


    Checkbox style Multi-Select Picklist

    author: Jim Wang @ January 2009 Updated by Kevin Morris 11/26/2010


    // PL – the picklist attribute; PLV – used to save selected picklist values  

    var PL = crmForm.all.new_role;  

    var PLV = crmForm.all.new_hiddenrole;  

    if( PL != null && PLV != null )  

    { = "none"; = "none";  

     // Create a DIV container  

     var addDiv = document.createElement("<div style='overflow-y:auto; height:80px; border:1px #6699cc solid; background-color:#ffffff;' />");  


     // Initialise checkbox controls  

     for( var i = 0; i < PL.options.length; i++ )  


       var pOption = PL.options[i];  

       if( !IsChecked( pOption.text ) )  

          var addInput = document.createElement("<input type='checkbox' style='border:none; width:25px; align:left;' />" );  


          var addInput = document.createElement("<input type='checkbox' checked='checked' style='border:none; width:25px; align:left;' />" );  

        var addLabel = document.createElement( "<label />");  

        addLabel.innerText = pOption.text;  

       var addBr = document.createElement( "<br>"); //it's a 'br' flag  





      // Check if it is selected  

      function IsChecked( pText )  


        if(PLV.value != "")  


          var PLVT = PLV.value.split("||");  

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


            if( PLVT[i] == pText )  

              return true;  



        return false;  



     // Save the selected text, this filed can also be used in Advanced Find  

     crmForm.attachEvent( "onsave" , OnSave);  

     function OnSave()  


       PLV.value = "";  

       var getInput = PL.nextSibling.getElementsByTagName("input");  

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


         if( getInput[i].checked)  


           PLV.value += getInput[i].nextSibling.innerText + "||";  




  27. Daniel Lagerwaard says:

    This does not seem to be possible on the CRM 2011 Online Beta. There is only an OnChange event handler available.

  28. Diamond says:

    Hello, I hope that you still watch this blog, i know it was posted a long time ago. I was wondering if you could tell me what parts of the script need to be changed so that I can put my own field names, and do i also need to put in the picklist values into the script? I am a newbie so all the information you can give me would be appreciated greatly.

  29. Puneet Joshi says:


    This is really helpful… But i am concerned how to use this in CRM 2011. Can anybody help and guide me step by step pls. I am newbie.


  30. Julie says:

    Any updates to the script to make it function in Dynamics CRM 2011?

  31. Jason says:

    The first box in the picklist is blank. Is there a way to hide or remove the blank entry?

  32. Nitesh Kumar says:

    great article… thanks a lot.. 🙂

  33. I have Category(which is an optionset) and Subcategory( Multi Select Option Set(as above)) and Mutliselect with name sc_ServiceInterest_value ,

    now when a category is changed accordingly subcategory should be changed or listed(Multiple Cascading)

    how should I do it ?  Thanks!!