"Dynamic form fields - Add new field on focus or change"
Bootstrap 3.1.0 Snippet by renswijnmalen

<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <div class="container"> <h3>Fields</h3> <div class="row"> <div class="form-group form-group-options col-xs-11 col-sm-8 col-md-4"> <div class="input-group input-group-option col-xs-12"> <input type="text" name="option[]" class="form-control" placeholder="Focus me"> <span class="input-group-addon input-group-addon-remove"> <span class="glyphicon glyphicon-remove"></span> </span> </div> </div> </div> </div> <div class="container"> <h3>Selects</h3> <div class="row"> <div class="form-group form-group-multiple-selects col-xs-11 col-sm-8 col-md-4"> <div class="input-group input-group-multiple-select col-xs-12"> <select class="form-control" name="values[]"> <option value="">Select one</option> <option value="1">Option 1</option> <option value="2">Option 2</option> <option value="3">Option 3</option> <option value="4">Option 4</option> </select> <span class="input-group-addon input-group-addon-remove"> <span class="glyphicon glyphicon-remove"></span> </span> </div> </div> </div> </div>
/* Text fields */ div.input-group-option:last-child span.input-group-addon-remove{ display: none; } div.input-group-option:last-child input.form-control{ border-bottom-right-radius: 3px; border-top-right-radius: 3px; } div.input-group-option span.input-group-addon-remove{ cursor: pointer; } div.input-group-option{ margin-bottom: 3px; } /* Selects */ div.input-group-multiple-select:last-child span.input-group-addon-remove{ display: none; } div.input-group-multiple-select:last-child input.form-control{ border-bottom-right-radius: 3px; border-top-right-radius: 3px; } div.input-group-multiple-select span.input-group-addon-remove{ cursor: pointer; background: none; border: none; } div.input-group-multiple-select{ margin-bottom: 5px; }
/* Text fields */ $(function(){ $(document).on('focus', 'div.form-group-options div.input-group-option:last-child input', function(){ var sInputGroupHtml = $(this).parent().html(); var sInputGroupClasses = $(this).parent().attr('class'); $(this).parent().parent().append('<div class="'+sInputGroupClasses+'">'+sInputGroupHtml+'</div>'); }); $(document).on('click', 'div.form-group-options .input-group-addon-remove', function(){ $(this).parent().remove(); }); }); /* Selects */ $(function(){ var values = new Array(); $(document).on('change', '.form-group-multiple-selects .input-group-multiple-select:last-child select', function(){ var selectsLength = $(this).parent().parent().find('.input-group-multiple-select select').length; var optionsLength = ($(this).find('option').length)-1; if(selectsLength < optionsLength){ var sInputGroupHtml = $(this).parent().html(); var sInputGroupClasses = $(this).parent().attr('class'); $(this).parent().parent().append('<div class="'+sInputGroupClasses+'">'+sInputGroupHtml+'</div>'); } updateValues($(this).parent().parent()); }); $(document).on('change', '.form-group-multiple-selects .input-group-multiple-select:not(:last-child) select', function(){ updateValues($(this).parent().parent()); }); $(document).on('click', '.input-group-addon-remove', function(){ var oSelectContainer = $(this).parent().parent() $(this).parent().remove(); updateValues(oSelectContainer); }); function updateValues(oSelectContainer){ values = new Array(); $(oSelectContainer).find('.input-group-multiple-select select').each(function(){ var value = $(this).val(); if(value != 0 && value != ""){ values.push(value); } }); $(oSelectContainer).find('.input-group-multiple-select select').find('option').each(function(){ var optionValue = $(this).val(); var selectValue = $(this).parent().val(); if(in_array(optionValue,values)!= -1 && selectValue != optionValue) { $(this).attr('disabled', 'disabled'); } else { $(this).removeAttr('disabled'); } }); } function in_array(needle, haystack){ var found = 0; for (var i=0, length=haystack.length;i<length;i++) { if (haystack[i] == needle) return i; found++; } return -1; } // Update all options for first use $('.form-group-multiple-selects').each(function(i, e){ updateValues(e); }); });

Related: See More


Questions / Comments:

how can I add autocomplete to this form? please, help me.

Royan Hudayana () - 7 years ago - Reply 0


Definitely cool, nice functionality

DK () - 7 years ago - Reply 0


I like this snippet

Robin () - 8 years ago - Reply 0


Can anyone explain how to limit these fields, please? Thank you.

Ä°lker OÄžUZ () - 8 years ago - Reply 0


Thanks for the snippet. Really helped. Although it broke when i used options with data-content. Did some dirty-fix and its working...

curiouscod3r () - 8 years ago - Reply 0


There is any way to sign a limit to the inputs? I need this function but for 3 data.

Diego Maruri () - 9 years ago - Reply 0


How would I use the input fields with preloaded data like if there is a value show the remove button?

Fejér Ferenc () - 9 years ago - Reply 0


How Can I make this with 2 input?

Bülent Sakarya () - 9 years ago - Reply 0


KenSchroeder () - 9 years ago - Reply 0


Ok I have one more question...I have this amazing snippet working on my page. The only issue I have now is when the new field is added it takes on the same name as the field before it. I need it to increment the name for each line. For example: SelectName1 is the first field name attribute, I need the new line to be SelectName2, and then SelectName3 and so on. How can I accomplish that? Any suggestions? Thank you in advance for your assistance.

k3nSchr0eder () - 9 years ago - Reply 0


Nice one :)

I customized the text input a bit and added the following CSS to support addons before and after the input field. Also I like the keyup event more for this. ;)

div.input-group-option:last-child input.form-control,
div.input-group-option:last-child input.form-control:not(:first-child):not(:last-child) {
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
}

Marc Nolte () - 9 years ago - Reply 0


So please do not burn me as I am new to this. First of all this site has taught me a TON! So thank you all for that. Second, I am running into an issue with this snippet as I cannot figure out how to incorporate the JS into my site files. I have created a JS file called dynamic-text.js with its contents being the provided JavaScript. I have added it the scriptbundle on my Site.Master. I have added the provided CSS to my main Bootstrap.css file and entered the HTML as shown. I still will not work. I really think it has something to do with me not knowing how to incorporate the JavaScript. Any help or suggestions would be greatly appreciated. Thank you.

k3nSchr0eder () - 9 years ago - Reply 0


I figured it out. Thank you. AWESOME snippet by the way!!

k3nSchr0eder () - 9 years ago - Reply 0


Does anyone know of an example where the selects are pre populated on load. Say for instance you choose a few selects, save the choices and then want to populate on page load.

John Mood () - 9 years ago - Reply 0


You would have to save the selects into the session (on the back end) and the prepopulate them from the session. This is not an easy task unfortunately as far as I know...

maxsurguy () - 9 years ago - Reply 0