Kevin Middleton Kevin Middleton -4 years ago 44
HTML Question

JavaScript - Filter Dropdowns

I'm sure this is very obvious but I cannot figure it out at all.

I have two dropdowns and the content of the second drop down is filtered based on the selection in the first dropdown. The filter at the moment is always based on the first letter of the "option value" in both dropdowns matching. Here is an example:

HTML

<table>
<tr>
<td align="right">Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.7" id="ANSWER.TTQ.MENSYS.7." data-ttqseqn="51" class="forminfree">
<option value=""></option>
<option value="DE">Department DE</option>
<option value="HS">Department HS</option>
<option value="BS">Department BS</option>
</select>
</td>
</tr>

<tr>
<td align="right">Sub-Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.8" id="ANSWER.TTQ.MENSYS.8." data-ttqseqn="52" class="forminfree">
<option value=""></option>
<option value="BSCCC01">Sub-Department 1</option>
<option value="BSCCC02">Sub-Department 2</option>
<option value="BSCCC03">Sub-Department 3</option>
<option value="HSCCC04">Sub-Department 1</option>
<option value="HSCCC05">Sub-Department 2</option>
<option value="HSCCC06">Sub-Department 3</option>
<option value="DECCC07">Sub-Department 1</option>
<option value="DECCC08">Sub-Department 2</option>
<option value="DECCC09">Sub-Department 3</option>
</select>
</td>
</tr>
</table>


JavaScript

var $options = "";

function Init_Page() {

// Ensure the sub-department dropdown is filtered every time the department changes
$('select[data-ttqseqn="51"]').bind('change', function() {
Set_Dpt_List(this.value);
});

// Keep a copy of the full sub-department list from Page Load in $options
var dpt_sel = $('select[data-ttqseqn="52"]').attr('id');
dpt_sel = '#' + escape_selector(dpt_sel);
$options = $(dpt_sel + ' option').clone();

//If a department is already selected then filter the sub-department dropdown accordingly
var fac_sel = $('select[data-ttqseqn="51"]').attr('id');
var facc = get_value(fac_sel);
if (facc) {
Set_Dpt_List(facc)
};
}

function Set_Dpt_List(facc) {

if (facc) {
// If a department is selcted then only show sub-departments whose code begins with the same 1st character
facc = facc.substr(0, 1);
var opts = $options.clone().filter(function() {
return (this.value.substr(0, 1) == facc || this.value == "");
});
$('select[data-ttqseqn="52"]').html(opts);
} else {
$('select[data-ttqseqn="52"]').html($options.clone());
}
}


Please note that the example won't work as it references functions that do not exist in the code.

The client is changing their coding structure so that the first letter of the sub-department code will no longer match the first letter of any of the department codes. The plan is to put the current "option value" codes at the start of the label like this example:

<table>
<tr>
<td align="right">Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.7" id="ANSWER.TTQ.MENSYS.7." data-ttqseqn="51" class="forminfree">
<option value=""></option>
<option value="DE">Department DE</option>
<option value="HS">Department HS</option>
<option value="BS">Department BS</option>
</select>
</td>
</tr>
<tr>
<td align="right">Sub-Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.8" id="ANSWER.TTQ.MENSYS.8." data-ttqseqn="52" class="forminfree">
<option value=""></option>
<option value="CCC01">BS - Sub-Department 1</option>
<option value="CCC02">BS - Sub-Department 2</option>
<option value="CCC03">BS - Sub-Department 3</option>
<option value="CCC04">HS - Sub-Department 1</option>
<option value="CCC05">HS - Sub-Department 2</option>
<option value="CCC06">HS - Sub-Department 3</option>
<option value="CCC07">DE - Sub-Department 1</option>
<option value="CCC08">DE - Sub-Department 2</option>
<option value="CCC09">DE - Sub-Department 3</option>
</select>
</td>
</tr>
</table>


However, I cannot figure out how to pick up the first letter from this to be used in the filter. Can anyone please help?

Please note that the "select" ID, name, etc. are all system driven and cannot be changed. Also, all options in each dropdown are database driven and cannot be altered.

Thanks.

Answer Source

While filtering in Set_Dpt_List() use innerHTML instead of value as the Department code is now present in option's display value.

Your Filter function should be:

var opts = $options.clone().filter(function() {
return (this.innerHTML.substr(0, 1) == facc || this.value == ""); //innerHTML instead of value
});

Full Code (with some modifications to make it working):

var $options = "";

function Init_Page() {

// Ensure the sub-department dropdown is filtered every time the department changes
$('select[data-ttqseqn="51"]').bind('change', function() {
Set_Dpt_List(this.value);
});

// Keep a copy of the full sub-department list from Page Load in $options
var dpt_sel = $('select[data-ttqseqn="52"]').attr('id');
dpt_sel = '#' + dpt_sel;
$options = $(dpt_sel + ' option').clone();

//If a department is already selected then filter the sub-department dropdown accordingly
var fac_sel = $('select[data-ttqseqn="51"]').attr('id');
var facc = $('select[data-ttqseqn="51"]').val();
if (facc) {
Set_Dpt_List(facc)
};
}

function Set_Dpt_List(facc) {

if (facc) {
// If a department is selcted then only show sub-departments whose code begins with the same 1st character
facc = facc.substr(0, 1);
var opts = $options.clone().filter(function() {
return (this.innerHTML.substr(0, 1) == facc || this.value == "");
});
$('select[data-ttqseqn="52"]').html(opts);
} else {
$('select[data-ttqseqn="52"]').html($options.clone());
}
}
Init_Page();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td align="right">Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.7" id="ANSWERTTQMENSYS7" data-ttqseqn="51" class="forminfree">
<option value=""></option>
<option value="DE">Department DE</option>
<option value="HS">Department HS</option>
<option value="BS">Department BS</option>
</select>
</td>
</tr>
<tr>
<td align="right">Sub-Department</td>
<td>
<select name="ANSWER.TTQ.MENSYS.8" id="ANSWERTTQMENSYS8" data-ttqseqn="52" class="forminfree">
<option value=""></option>
<option value="CCC01">BS - Sub-Department 1</option>
<option value="CCC02">BS - Sub-Department 2</option>
<option value="CCC03">BS - Sub-Department 3</option>
<option value="CCC04">HS - Sub-Department 1</option>
<option value="CCC05">HS - Sub-Department 2</option>
<option value="CCC06">HS - Sub-Department 3</option>
<option value="CCC07">DE - Sub-Department 1</option>
<option value="CCC08">DE - Sub-Department 2</option>
<option value="CCC09">DE - Sub-Department 3</option>
</select>
</td>
</tr>
</table>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download