Wrap choice-field in multiple columns: Updated version

I have preciously posted a solution for wrapping checkboxes or radio buttons in multiple rows. This one is a bit sleeker and easier to implement.

IMG

I have added a slightly modified version of “init_fields” to accommodate for lists and surveys.

Add this code to a CEWP below the form:

<style type="text/css">
.ms-RadioText label{
	white-space:nowrap;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript">

var fields = init_fields_v3();

multichoiceVertical(['Checkboxes'],4);

function multichoiceVertical(arr,breakAfter){
	var toFind, index, counter, table;
	toFind = "td.ms-formbody";
	if($("td.ms-formbodysurvey").length>0){
		toFind = "td.ms-formbodysurvey";
	}
	$.each(arr,function(i,fin){
		if(fields[fin]!==undefined){
			index = 0;
			counter = 0;
			table = $(fields[fin]).find(toFind+' table:first');
			$(table).prepend("<tr id='vertical_"+fin+"_"+index+"'></tr>");
			$(table).find('tr:first').nextAll().each(function(){
				if(counter%breakAfter===0){
					$("#vertical_"+fin+"_"+index).after("<tr id='vertical_"+fin+"_"+(index+1)+"'></tr>");					
					index += 1;
				}				
				$(this).find('td:first').appendTo($("#vertical_"+fin+"_"+index));
				$(this).remove();
				counter += 1;
			});			
		}
	});
}

function init_fields_v3(){
	var toFind, res, myMatch, disp, fin, type
	res = {};
	toFind = "td.ms-formbody";
	if($("td.ms-formbodysurvey").length>0){
		toFind = "td.ms-formbodysurvey";
	}
	$(toFind).each(function(){
		myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);	
		if(myMatch!=null){
			disp = myMatch[1];
			fin = myMatch[2];
			type = myMatch[3];
			if(type=='SPFieldNote'){
				if($(this).find('script').length>0){
					type=type+"_HTML";
				}else if($(this).find("div[id$='_TextField_inplacerte']").length>0){
					type=type+"_EHTML";
				}				
			}
			if(type=='SPFieldLookup'){
				if($(this).find('input').length>0){
					type=type+"_Input";
				}
			}
			res[fin] = this.parentNode;
			$(res[fin]).attr('FieldDispName',disp);
			$(res[fin]).attr('FieldType',type);
		}		
	});
	return res;
}

</script>

Change the script src to use a local copy of jQuery if you prefer that.

You call the function with an array of the FieldInternalNames you want top apply this solution to, and the number of columns to distribute the choices over like this:

multichoiceVertical(['Checkboxes'],4);

Alexander

50 thoughts on “Wrap choice-field in multiple columns: Updated version”

  1. Alex – thanks for putting this together, but I’ve been staring at this for two days and can’t get anywhere. I have a custom form, and your linked article talks about the V2 code and in light of tabs, not choice columns. Could you shed more light (in dummy terms for me if possible) on what needs to change in this, updated, code? Many thanks in advance!

  2. do i need to change the code with my list field names ? for instance i am trying to apply this on a column “Session name” in my list which is having 38 Choices. I copied and pasted this code to CEWP but it did not work. Please let me know what i shud be doing to make it work. thanks !

      1. Thanks for the quick reply. I’m feeling pretty stupid about where to make the change. Any help of examples would be greatly appreciated.

      2. Like this: multichoiceVertical([‘MyChoiceColumn’,’AnotherChoiceField’],4);

        Alexander

  3. I been trying to make this script work, also i tried to use List inspector. Following exactly every step for some reason does not work for me.

    I did the jquery installation in my testing machine and my prod server and modified the v4.master page with the values specified in the blog.

    Still does not work. I even create a list, name the column “Checkboxes” (Multiple selection allowed). and i modified the new and edit dialog forms…nothing. I am obviously missing something. Any help will be appreciated.

    1. My installation is Sharepoint Foundation 2010 @ server and Sharepoint Foundation 2010 with visual studio in windows 7.

      I downloaded the jquery 1.9.1 however i did change at first the code to my local jquery but since did not work i used the code as is pointing to the googleapis https site.

      I tried to even upload the code to a .js file in a document library and call it in the webpart using the content link.

      Also i test my jquery installation and the background test works with the IE debugging tool (F12).

      1. It was the code that change during copy/paste because I am working on a virtual machine and the Clipboard conversion added additional characters to the code.

        I clean up the code and works.

  4. Hi! This is great stuff….I feel dumb about myself not being able to make this work on my sharepoint 2010 site.
    As I understand, the term “Checkboxes” is the name of the question?
    I have added a question called Checkboxes and pasted this code in the EditForm.aspx of my survey. It still shows no effect. Tearing my hair apart! Please help!!

  5. Yes, my SPD looks something like this in EditForm.aspx page. This is right below the ListFormWebPart.

    Content Editor
    Default
    Allows authors to enter rich text content.
    true
    4
    Normal

    true
    true
    true
    true
    true
    true
    true

    Modeless
    Default

    Cannot import this Web Part.
    /_layouts/images/mscontl.gif

    true
    00000000-0000-0000-0000-000000000000
    g_427a04e5_8b39_4fe9_b143_6c1529825f31

    <![CDATA[

    var fields = init_fields_v3();
    multichoiceVertical([‘Checkboxes’],2);
    …..your code…..
    }
    ]]>

  6. I’m sorry about the above reply. Guess, the code went haywire!
    I placed my CEWP right below the survey listformwebpart and added your entire code from start to finish in the contents of the webpart.
    Also, i referenced a jsfile to the one in my site…..

  7. Hi,
    There was an error in the code, and I have updated his line:

    myMatch = $(this).html().match(/FieldName="(.+)"s+FieldInternalName="(.+)"s+FieldType="(.+)"s+/);

    like this

    myMatch = $(this).html().match(/FieldName="(.+)"\s+FieldInternalName="(.+)"\s+FieldType="(.+)"\s+/);

    Alexander

  8. Hi, I applied this script to a CEWP underneath all form parts and it doesn’t seem to be working, its not splitting the choice out into multiple columns.
    I am using SP2013 could that be why?
    Thanks

  9. I cant get it to work in SP 2013. I tried adding the Javascript to a Document Library and referencing it in webpart. I also made sure to add webpart below form. Maybe I am missing something, Do I need to include column name inside the JS? Please suggest where I need to make changes in above code. Thanks in advance.

    1. Hi,
      2013 loads the form async, you can try wrapping it like this:

      function init_sp2013FormReady(){
      	if($("td.ms-formbody span[id*='"+_spPageContextInfo.pageListId.replace(/\{|\}/g,"")+"']").length>0){
      		setTimeout(function(){
      			init_sp2013FormReady();
      		},10);
      		return;
      	}else{
      		sp2013FormReady();
      		
      	}
      }
      
      function sp2013FormReady(){
      	// The form is ready - add the code here
      }
      
      init_sp2013FormReady();

      Alexander

      1. Thanks for the response. This is the code i’m trying to insert in CEWP but I couldn’t get it to work. Please suggest any changes to be made. Thanks.

        .ms-RadioText label{
        white-space:nowrap;
        }

        function init_sp2013FormReady(){
        if($(“td.ms-formbody span[id*='”+_spPageContextInfo.pageListId.replace(/\{|\}/g,””)+”‘]”).length>0){
        setTimeout(function(){
        init_sp2013FormReady();
        },10);
        return;
        }else{
        sp2013FormReady();

        }
        }

        function sp2013FormReady(){
        // The form is ready – add the code here

        var fields = init_fields_v3();

        setTimeout(function(){
        multichoiceVertical([‘Checkboxes’],4);
        },500;

        function multichoiceVertical(arr,breakAfter){
        var toFind, index, counter, table;
        toFind = “td.ms-formbody”;
        if($(“td.ms-formbodysurvey”).length>0){
        toFind = “td.ms-formbodysurvey”;
        }
        $.each(arr,function(i,fin){
        if(fields[fin]!==undefined){
        index = 0;
        counter = 0;
        table = $(fields[fin]).find(toFind+’ table:first’);
        $(table).prepend(“”);
        $(table).find(‘tr:first’).nextAll().each(function(){
        if(counter%breakAfter===0){
        $(“#vertical_”+fin+”_”+index).after(“”);
        index += 1;
        }
        $(this).find(‘td:first’).appendTo($(“#vertical_”+fin+”_”+index));
        $(this).remove();
        counter += 1;
        });
        }
        });
        }

        function init_fields_v3(){
        var toFind, res, myMatch, disp, fin, type
        res = {};
        toFind = “td.ms-formbody”;
        if($(“td.ms-formbodysurvey”).length>0){
        toFind = “td.ms-formbodysurvey”;
        }
        $(toFind).each(function(){
        myMatch = $(this).html().match(/FieldName=”(.+)”\s+FieldInternalName=”(.+)”\s+FieldType=”(.+)”\s+/);
        if(myMatch!=null){
        disp = myMatch[1];
        fin = myMatch[2];
        type = myMatch[3];
        if(type==’SPFieldNote’){
        if($(this).find(‘script’).length>0){
        type=type+”_HTML”;
        }else if($(this).find(“div[id$=’_TextField_inplacerte’]”).length>0){
        type=type+”_EHTML”;
        }
        }
        if(type==’SPFieldLookup’){
        if($(this).find(‘input’).length>0){
        type=type+”_Input”;
        }
        }
        res[fin] = this.parentNode;
        $(res[fin]).attr(‘FieldDispName’,disp);
        $(res[fin]).attr(‘FieldType’,type);
        }
        });
        return res;
        }

        }

        init_sp2013FormReady();

        This is the code I’m inserting inside CEWP but I couldnt get it work.

      2. Hi,
        The only thing you need to put in the “sp2013FormReady” function is this:

        var fields = init_fields_v3();
        multichoiceVertical(['Checkboxes'],4);

        But I start to think your problem might be the FieldInternalName of your field. The text “Checkboxes” refers to the FieldInternalName and must be changed to match the field you try to address.

        Alexander

  10. Hi,

    I’m running into some trouble implementing this solution in SP 2013. Whenever i put the code in a CEWP and Save, the script contents just disappear and all that’s left is the script tags. I’ve tried using a txt file and linking it and that doesn’t work either. I also tried using a Script Editor and pasting the code there and that didn’t work either. Here’s the code I’m using.

    .ms-RadioText label{
    white-space:nowrap;
    }

    function init_sp2013FormReady(){
    if($(“td.ms-formbody span[id*='”+_spPageContextInfo.pageListId.replace(/\{|\}/g,””)+”‘]”).length>0){
    setTimeout(function(){
    init_sp2013FormReady();
    },10);
    return;
    }else{
    sp2013FormReady();

    }
    }

    function sp2013FormReady(){
    var fields = init_fields_v3();
    multichoiceVertical([‘Test’],4);
    }

    init_sp2013FormReady();

    function multichoiceVertical(arr,breakAfter){
    var toFind, index, counter, table;
    toFind = “td.ms-formbody”;
    if($(“td.ms-formbodysurvey”).length>0){
    toFind = “td.ms-formbodysurvey”;
    }
    $.each(arr,function(i,fin){
    if(fields[fin]!==undefined){
    index = 0;
    counter = 0;
    table = $(fields[fin]).find(toFind+’ table:first’);
    $(table).prepend(“”);
    $(table).find(‘tr:first’).nextAll().each(function(){
    if(counter%breakAfter===0){
    $(“#vertical_”+fin+”_”+index).after(“”);
    index += 1;
    }
    $(this).find(‘td:first’).appendTo($(“#vertical_”+fin+”_”+index));
    $(this).remove();
    counter += 1;
    });
    }
    });
    }

    function init_fields_v3(){
    var toFind, res, myMatch, disp, fin, type
    res = {};
    toFind = “td.ms-formbody”;
    if($(“td.ms-formbodysurvey”).length>0){
    toFind = “td.ms-formbodysurvey”;
    }
    $(toFind).each(function(){
    myMatch = $(this).html().match(/FieldName=”(.+)”\s+FieldInternalName=”(.+)”\s+FieldType=”(.+)”\s+/);
    if(myMatch!=null){
    disp = myMatch[1];
    fin = myMatch[2];
    type = myMatch[3];
    if(type==’SPFieldNote’){
    if($(this).find(‘script’).length>0){
    type=type+”_HTML”;
    }else if($(this).find(“div[id$=’_TextField_inplacerte’]”).length>0){
    type=type+”_EHTML”;
    }
    }
    if(type==’SPFieldLookup’){
    if($(this).find(‘input’).length>0){
    type=type+”_Input”;
    }
    }
    res[fin] = this.parentNode;
    $(res[fin]).attr(‘FieldDispName’,disp);
    $(res[fin]).attr(‘FieldType’,type);
    }
    });
    return res;
    }

    Thanks,
    Sarath

    1. Hi,
      Code directly in a CEWP does not work, but linking it from a text file in a document library should work – as should the script editor.

      Hit F12 and select “Console” to bring up the developer console and look for errors there.

      Alexander

      1. if(fields[fin]!==undefined){ <——– This is fields referred to in the error
        index = 0;
        counter = 0;
        table = $(fields[fin]).find(toFind+' table:first');
        $(table).prepend("”);
        $(table).find(‘tr:first’).nextAll().each(function(){
        if(counter%breakAfter===0){
        $(“#vertical_”+fin+”_”+index).after(“”);
        index += 1;
        }
        $(this).find(‘td:first’).appendTo($(“#vertical_”+fin+”_”+index));
        $(this).remove();
        counter += 1;
        });
        }
        });
        }

      2. I have it under the sp2013FormReady function. Is it not supposed to be there?

        function init_sp2013FormReady(){
        if($(“td.ms-formbody span[id*='”+_spPageContextInfo.pageListId.replace(/\{|\}/g,””)+”‘]“).length>0){
        setTimeout(function(){
        init_sp2013FormReady();
        },10);
        return;
        }else{
        sp2013FormReady();

        }
        }

        function sp2013FormReady(){
        var fields = init_fields_v3();
        multichoiceVertical([‘Test’],4);
        }

  11. I am creating a custom list and have three different multichoiceVertical. I have added your code below the add new form but am wondering if there is a way to make the column width equal between all of the multichoiceVerticals. It seems that SharePoint is automatically stripping any extra spaces I may add to the beginning or end of a choice value – so I am unable to get the column widths to be consistent. The reason I would like to do this is because the columns are so close together – most of the choice values are the same length so it have no space between the choice value of column one and where the next column checkbox starts.

    1. Hi,
      I don’t have a solution ready, but you should be able to find the ID of the tr or the td using the developer toolbar in the browse (hit F12). When you have the ID you can make a CSS style to target them.

      Alexander

  12. Hi Alexander,
    i try to use script for SharePoint 2013 online.
    i get it into script Editor web part or link to txt file in Content Editor. but it doesn’t function.
    this is code, i’m using:

    .ms-RadioText label{
    white-space:nowrap;
    }

    var fields = init_fields_v3();

    function sp2013FormReady(){

    setTimeout(function(){
    multichoiceVertical([‘KnowHow’],2);
    },500;
    }

    function init_sp2013FormReady(){
    if($(“td.ms-formbody span[id*='”+_spPageContextInfo.pageListId.replace(/\{|\}/g,””)+”‘]”).length>0){
    setTimeout(function(){
    init_sp2013FormReady();
    },10);
    return;
    }else{
    sp2013FormReady();

    }
    }

    init_sp2013FormReady();

    function multichoiceVertical(arr,breakAfter){
    var toFind, index, counter, table;
    toFind = “td.ms-formbody”;
    if($(“td.ms-formbodysurvey”).length>0){
    toFind = “td.ms-formbodysurvey”;
    }
    $.each(arr,function(i,fin){
    if(fields[fin]!==undefined){
    index = 0;
    counter = 0;
    table = $(fields[fin]).find(toFind+’ table:first’);
    $(table).prepend(“”);
    $(table).find(‘tr:first’).nextAll().each(function(){
    if(counter%breakAfter===0){
    $(“#vertical_”+fin+”_”+index).after(“”);
    index += 1;
    }
    $(this).find(‘td:first’).appendTo($(“#vertical_”+fin+”_”+index));
    $(this).remove();
    counter += 1;
    });
    }
    });
    }

    function init_fields_v3(){
    var toFind, res, myMatch, disp, fin, type
    res = {};
    toFind = “td.ms-formbody”;
    if($(“td.ms-formbodysurvey”).length>0){
    toFind = “td.ms-formbodysurvey”;
    }
    $(toFind).each(function(){
    myMatch = $(this).html().match(/FieldName=”(.+)”\s+FieldInternalName=”(.+)”\s+FieldType=”(.+)”\s+/);
    if(myMatch!=null){
    disp = myMatch[1];
    fin = myMatch[2];
    type = myMatch[3];
    if(type==’SPFieldNote’){
    if($(this).find(‘script’).length>0){
    type=type+”_HTML”;
    }else if($(this).find(“div[id$=’_TextField_inplacerte’]”).length>0){
    type=type+”_EHTML”;
    }
    }
    if(type==’SPFieldLookup’){
    if($(this).find(‘input’).length>0){
    type=type+”_Input”;
    }
    }
    res[fin] = this.parentNode;
    $(res[fin]).attr(‘FieldDispName’,disp);
    $(res[fin]).attr(‘FieldType’,type);
    }
    });
    return res;
    }

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.