1

I have a job that requires several hundred select elements on a page. I want to show each select dynamically as the previous is changed. I have a working version in which I put all the select elements in the markup, and then used a simple function to hide them all and show only the first. Then on change of each select the next is added.

This works just fine, but is obviously not ideal. I don't want to put 500 select items in the markup and hide them all for no reason, and my JS function would be 1500 lines long. Plus that would make me feel silly.

How can I automate this process with JS?

I do not need each select to have a unique id, but I do need each select to have a unique and incremented name. Is this possible? I have a working fiddle.

HTML:

<select name="select-one" class="hidden" id="one">
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>

<select name="select-two" class="hidden" id="two">
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>

<select name="select-three" class="hidden" id="three">
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>

<select name="select-four" class="hidden" id="four">
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>

JS:

$(document).ready(function() {

  $('.hidden').hide();
  $('#one').show();

  $('#one').change(function(){
     $('#two').show();
  });
  $('#two').change(function(){
     $('#three').show();
  });
  $('#three').change(function(){
     $('#four').show();
  });
  // and so forth...

});
Claire
  • 3,146
  • 6
  • 22
  • 37

2 Answers2

2

HTML:

<select class="hidden" id="one" name='name_0'>
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>

jQuery

$('select').on('change', function() {
$('body').append($(this).clone(true))
})

Result:

enter image description here

Note we are using the overload of the clone() method. This means event handlers and data will be copied along with the elements. So whatever event handler you attached to the original select gets cloned.

If you want to increment the name just use a counter and add the attribute after the clone:

cnt=0;
$('select').on('change', function() {
cnt++
$('body').append($(this).clone(true).attr('name', 'name_' + cnt))
})

enter image description here

Cybernetic
  • 12,628
  • 16
  • 93
  • 132
0

My solution:

CSS

.hidden {
  display: none;
}

JS

const createSelect = index => `
<select name="select-${index}" class="hidden select" data-index=${index}>
   <option value="">not this one</option>
   <option value="">pick this one</option>
</select>
`;

$(document).ready(function() {
  // Generate 100 selects
  for (let i = 0; i < 100; i++) {
    $("body").append(createSelect(i));
  }

  // Show first select
  $(`.select[data-index='0']`).show();

  $('.select').on('change', function() {
    // Store index of a select currently changed
    const index = parseInt($(this).attr('data-index'), 10);

    // Show next select
    $(`.select[data-index='${index + 1}']`).show();
  });
});
user3210641
  • 1,565
  • 1
  • 10
  • 14