cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Not applicable

Dynamic multi choice field in Repeating Sections

Hello All,

Hoping someone can point me in the right direction for this.   I have a form with a multi-text field that holds all possible values (separated by semicolons)  to be selected in a multi choice field in a repeating section.  Let's say it holds all the States.    What I want is for all the State values to be selected in the repeating sections.   So the first repeating section multi choice field would show all 50 states.   Let's say the user picks 10 states and then adds a new repeating section row.   That new row would have only the remaining 40 states in it's multi choice field.  This would continue until all states are selected across "X" number of repeating rows.    My thought was to have two  fields one with original 50 states and one with the selected states.   I would use an "Row Adding" or "Row Deleting" event to keep the running list of selected states and compare the two fields and come up with the remaining list which would be used in the new row's multi choice field.  (Maybe this is a third field)     So in theory this sounds awesome and totally do-able.   My issue is I'm not sure how to pull it off.    I have the events wired up to my repeating section and working to give alerts when new rows are added or deleted.   I just don't have enough experience to know how to get the values from the multi-choice field in the repeating rows to do the running list and do the comparison.     I would appreciate any advice or some similar examples of the JavaScript to help me figure it out.   

**Extra bonus points for validating all 50 states are selected

Thank you in advance,

Brad

Ps- I've seen some great posts that helped me with the events, thanks Caroline Jung​ for pointing it out to me,  and Emily Billing​ for creating it.

Labels: (3)
0 Kudos
Reply
7 Replies
Highlighted
Automation Master
Automation Master

Re: Dynamic multi choice field in Repeating Sections

Hello Brad,

Regarding validation, I would add an hidden multi lines text field in the form containing remaining states to select (the content of this field would be populated using javascript). And you could add a validation rule which condition would be if this hidden multi text field is not empty then all states haven't been selected.

Regarding the implementation I would add an hidden multi lines text field in the repeating section to store the selected states in each row (the content of this field would be populated using javascript). In the repeating section, I would also add a panel. With this panel, you will be able to dynamically add a dropdown list inside it using JavaScript (by adding a CSS class to this panel). When you will generate the dropdown list (using the Row added event), you can add an onchange event so that each time a new state is selected or deselected, you can execute a script which will update the content of all the hidden multi lines text fields (the global one and those in repeating section rows). This script will also have to update possible values to select in each dropdown list: for example if state A is selected in the third row, then it has to be removed from all other existing dropdown lists (in the first and second rows).

Tell me if it's not clear or if you need more information.

To help you with the javascript, here's a link which explains how to dynamically generate a dropdown list using Javascript :

http://stackoverflow.com/questions/9895082/javascript-populate-drop-down-list-with-array

Tell me if you need more help to build the scripts.

Reply
Highlighted
Not applicable

Re: Dynamic multi choice field in Repeating Sections

I'm working on implementing this and one thing I've run across is that my change event for the "States" Select field works but only in the first repeating section.  If I add a section it doesn't fire when the new states are selected.    Any help would be appreciated.  also Is there a good resource for how to reference items in repeating sections? 

Reply
Highlighted
Not applicable

Re: Dynamic multi choice field in Repeating Sections

I figured out the on change event and how to iterate all the rows and get a list of all the selected States,  Now I'm having issues with how to change the options in the States checkbox in the new repeating row.   I can't figure out how to copy code into this forum so I've included an image of my code.   It runs through just doesn't do anything.   When the new repeating row is added it still has all the possible states.  the allState array does have the correct values that I want to populate into my state checkboxes.  (Even though I named the variable statedropdown they are checkboxes)

Capture.PNG

Thanks in advance for any help.

Brad

Reply
Highlighted
Automation Master
Automation Master

Re: Dynamic multi choice field in Repeating Sections

I think that the checkboxes control in the row added is not correctly selected.

Can you try with the following code (as the row added is the last one) :

     var statedropdown = repeaterControl.find(".cssStates").last();

If it doesn't work, can you try to use the "RegisterRepeaterRowAdded" function instead of the "RegisterRepeaterRowAdding"?

Hope this helps

Reply
Highlighted
Not applicable

Re: Dynamic multi choice field in Repeating Sections

Ok, I've got this all working,  it may not be the best way to do it but it works.   Please feel free to leave comments if you see anything that can be improved.    The problem was to create a dynamic reducing choice field in a repeating row so that items could not be chosen more than once.   It would also make it easier for end user to know which options had already been selected.  And finally some validation to make sure all options were selected.   I'm using States as an example.    In my form I have a repeating section with a CSS Class of  StateSelectionRepeater.   In the repeating section I have a choice [checkbox] field with a CSS Control Class of cssctlStates.   I also have a calculated value CSS Class of cssRowNum with the currentRowNumber() function for value.     Outside the repeating section I have two fields with their Client ID JavaScript Names set to AllStates and RemainingStates.   AllStates by default has States separated by semi-colons.   The AllStates field is the default for the cssctlStates field.   I created a change event for the checkbox field and events handlers for repeating row added, deleted and deleting.   All of that code with comments is included below.    I hope all my efforts help someone else because I had a heck of a time getting this to work.   Lots of trial and error.   I wanted to remove the checked options but I couldn't get that to work for some reason so I just disabled them.   If someone can show me how to change disable to remove I'd appreciate it.

Custom JavaScript Click on the Forms Settings icon in the Ribbon and copy and paste the following JavaScript code in the Custom JavaScript field and click Save.

NWF.FormFiller.Events.RegisterAfterReady(function() {

NWF$(".cssStates").change(State_Checkbox_Change_function);

});

NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {

//find the Checkboxes that have been checked and disable them in the new row

var repeaterRow = NWF$(arguments[0][0]);

if (NWF$(repeaterRow.parents('.nf-repeater')[0]).hasClass('StateSelectionRepeater')) {

var allRemainingStates = new Array();

//get contents of RemainingStates and AllStates fields and find the difference which are the checked options

allRemainingStates = NWF$('#' + RemainingStates).val().split(",");

var allStates = new Array();

allStates = NWF$('#' + AllStates).val().split(";");

var stateChoice= NWF$(repeaterRow).find(".cssctlStates");

NWF$.each(subtractarrays(allStates, allRemainingStates), function(i, p) {

disableCheckbox(p, stateChoice); }); } });

NWF.FormFiller.Events.RegisterRepeaterRowDeleting(function () {

//find the checked options being deleted and enable them in the remaining rows

var repeaterRow = NWF$(arguments[0][0]);

if (NWF$(repeaterRow.parents('.nf-repeater')[0]).hasClass('StateSelectionRepeater')) {

var rowChecked = new Array();  //checked values

//get just the checkbox from this row

NWF$(repeaterRow).find(".cssStates input:checked").each(function() {

rowChecked.push(NWF$(this).val()); });

//loop all remaining rows and enable the checkboxes from this row we're deleting

NWF$(".StateSelectionRepeater .nf-repeater-row").each(function() {

var statedropdown= NWF$(this).find(".cssctlStates");

NWF$.each( rowChecked, function(i, p) {

enableCheckbox(p, statedropdown); }); }); } });

NWF.FormFiller.Events.RegisterRepeaterRowDeleted(function () {

var repeaterControl = NWF$(arguments[0][0]);

//Now that row is deleted we need to update our Remaining Options field.

if(repeaterControl.hasClass('StateSelectionRepeater')) {

//loop all remaining rows to get the checked values

var checkedStatesVals = new Array();  //checked values

var allState = new Array();

NWF$(".StateSelectionRepeater .nf-repeater-row").each(function() {

NWF$(this).find(".cssStates input:checked").each(function() {

checkedStatesVals.push(NWF$(this).val()); });  });

//updated the remaining states field with the available options

var remainingStates= NWF$('#' + RemainingStates);

allState = NWF$('#' + AllStates).val().split(";");

remainingStates.val(subtractarrays(allState, checkedStatesVals)); } });

function State_Checkbox_Change_function() {

//everytime a box is checked or unchecked update the options in all repeating rows

var $row = NWF$(this).parents(".nf-repeater-row").first();

var rownum = $row.find(".cssRowNum input").val();

var checkedStatesVals = new Array();  //checked values

var allState = new Array();

NWF$(".taskAssignmentRepeater .nf-repeater-row").each(function() {

NWF$(this).find(".cssStates input:checked").each(function() {

checkedStatesVals.push(NWF$(this).val()); });  });

var remainingStates= NWF$('#' + RemainingStates);

allState = NWF$('#' + AllStates).val().split(";");

remainingStates.val(subtractarrays(allState, checkedStatesVals));

//loop through all repeating rows and disable checked values

NWF$(".taskAssignmentRepeater .nf-repeater-row").each(function() {

var thisrownum = NWF$(this).find(".cssRowNum input").val();

//we don't want to disable the actual checked box in case they want to uncheck it later

//so compare rownumbers to skip just changed value

if ( thisrownum != rownum    ){

var stateChoice= NWF$(this).find(".cssctlStates");

NWF$.each(checkedStatesVals, function(i, p) {

disableCheckbox(p, stateChoice); }); };});

//loop through all repeating rows and enable values that are no longer checked

NWF$(".taskAssignmentRepeater .nf-repeater-row").each(function() {

var stateChoice= NWF$(this).find(".cssctlStates");

NWF$.each( remainingStates.val().split(","),function(i, p) {

enableCheckbox(p, stateChoice); }); }); }

function subtractarrays(array1, array2){

//find the difference between two arrays

var difference = []; for( var i = 0; i < array1.length; i++ ) {

if( $.inArray( array1, array2 ) == -1 ) {

difference.push(array1); } }

return difference; }

function disableCheckbox(name, container) {

container.find( 'input[type=checkbox]').each(function () {

//check to see if it's checked because we don't want to disable in case they want to change it

var sThisVal = (this.checked ? "1" : "0");

if (this.value == name && sThisVal == "0"){

this.disabled = true; }; }); }

function enableCheckbox(name, container) {

container.find( 'input[type=checkbox]').each(function () {

var sThisVal = (this.disabled ? "1" : "0");

if (this.value == name && sThisVal == "1"){

this.disabled = false; }; }); }

stateschoice.PNG

Reply
Highlighted
Not applicable

Re: Dynamic multi choice field in Repeating Sections

Hi Caroline,

I posted my solution to the reducing choices in repeating sections,  Can you take a look at my post and suggest how I can remove instead of disable the options.

Thanks,

Brad

Reply
Highlighted
Automation Master
Automation Master

Re: Dynamic multi choice field in Repeating Sections

You can remove options already selected but remaining options won't be correctly displayed in columns and rows.

As the options are put in an html table, if you delete the cell (<td></td>) where the option is, there will be a blank space and the next option won't automatically take the place of the removed one. You can try to use Javascript to reorganise the html table, but I think that it won't be so easy.

To remove the option, you can try to use the following function (I haven't tried it):

function removeCheckbox(name, container) {

container.find( 'input[type=checkbox]').each(function () {

//check to see if it's checked because we don't want to remove it in case they want to change it

var sThisVal = (this.checked ? "1" : "0");

if (this.value == name && sThisVal == "0"){

NWF$(this).parents("td").remove(); }; }); }

Also be careful to store the removed td tag in a Javascript variable in case that you need to add it again (via enableCheckbox function).

Hope this helps

Reply