kate_hudson kate_hudson - 4 months ago 11
Javascript Question

Displaying inputs based on previous selection

I have a page with several select inputs which take the following form

<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="col-sm-7">
<select class="selectpicker" name="productType" id="productType">
<option value=""></option>
<option value="Cereal">Cereal</option>
</select>
</div>
</div>
</div>
</div>


What I am trying to do is display select inputs only when the previous select has been selected. To do this I am essentially doing

$( "#productType" ).change(function() {
if($(this).val() != '') {
$('#yearRow').css('display', 'block');
} else {
$('#yearRow').css('display', 'none');
}
});


I have set up a working JSFiddle

Although what I have works, I have a feeling it is going to get ugly. Reason I say this is because if you select the first input, and then the second, and then unselect the first, the third input will remain. I could handle the display of every input within every select change function, but this is where I think it will get messy. Basically, I want to avoid this

$( "#productType" ).change(function() {
if($(this).val() != '') {
$('#yearRow').css('display', 'block');
} else {
$('#yearRow').css('display', 'none');
$('#monthRow').css('display', 'none');
$('#idRow').css('display', 'none');
//Any other rows
}
});


Is there a better way of doing what I am attempting to do?

Thanks

Answer

You can try this:

  • Add some class to all the selects and their row parents.

Then you can use the select's class selector like this:

$( ".selectpicker" ).change(function() {
    var $this = $(this);

    //Display Next Select
    if ($this.val().toString().length) {
        $this.closest('div.select-parent').next('div.select-parent').removeClass('hiddenRow');
        return;
    }

    //Hide Next All Selects
    $this.closest('div.select-parent').nextAll('div.select-parent').addClass('hiddenRow')
       .find('select').val("").selectpicker('refresh'); //Refresh Select
});

Here is the FIDDLE.