Reputation: 732
So I am making two dropdowns. One is dependent on the other one, as in when you choose an option in the first dropdown, the values in the other should change. I am rendering my form with Symfony3.4, so I do not have much control over it. (I do not think I can add dynamic class names/value names to it). If it is relevant, I am using Bulma css framework.
Here is what my selectboxes look like:
states:
<select name="state" id="stateSelect">
<option value="1">Lagos</option>
<option value="2">Abuja</option>
<option value="3">Rivers</option>
<option value="4">Ogun</option>
<option value="5">Oyo</option>
<option value="6">Anambra</option>
<option value="7">Enugu</option>
<option value="8">Akwa Ibom</option>
<option value="9">Adamawa</option>
...
<option value="37">Zamfara</option>
</select>
LGA (local government areas):
<select id="lgaSelect" name="areas_registration[lga]">
<optgroup label="Lagos">
<option value="1">Abule Egba</option>
<option value="2">Agege</option>
<option value="3">Ajah</option>
<option value="4">Alimosho</option>
<option value="5">Amuwo Odofin</option>
...
</optgroup>
<optgroup label="Abuja">
<option value="38">Apo</option>
<option value="39">Asokoro</option>
<option value="40">Central Area</option>
<option value="41">Chika</option>
<option value="42">Dakibiyu</option>
...
</optgroup>
....35 more optgroups
</select>
My goal is when a user chooses an option from States dropdown, the LGA dropdown should only have options relevant to the selected state. I am using optgroup label for this. What I tried in my javascript is that when the page loads, I clone the LGA dropdown, hide it, call it lgaSelectSeed and use it for seeding the original LGA dropdown: (#hiddenLgas is just an empty div)
$(function () {
var stateSelect = $("#stateSelect") || null;
var lgaSelect = $("#lgaSelect") || null;
var hiddenLga = $("#hiddenLgas") || null;
$(hiddenLga).html(lgaSelect.clone().prop('id', 'lgaSelectSeed'));
stateSelect.change(function () {
var select_class = $(this).find('option:selected').text();
var options = $(lgaSelectSeed).find('optgroup[label="' + select_class + '"]');
$(lgaSelect).html(options.children());
}
This works but there is a bug in it. If you select random options in the state dropdown, and then go up and select Lagos or Abuja, the LGA dropdown becomes blank. I have been trying to figure out for a few days why this is happening, but still cant. Is there any jquery plugin to handle this instead?
DEMO: https://jsfiddle.net/gafyvbL9/
How to replicate the bug: In the states dropdown (left), choose Lagos. Then choose Anambra. Then choose Lagos again, then choose Anambra. You can see that the LGA dropdown (right) becomes empty. Why is this happening? Thanks in advance
Upvotes: 0
Views: 61
Reputation: 1073
Playing with your fiddle, I think the issue is when you perform $(lgaSelect).html()
, you're deleting all of the information stored there. Try storing that outside of your handler.
let $options = $('#lgaSelect').clone();
$("#stateSelect").on('change',function() {
let state = $(this).find('option:selected').text();
$("#lgaSelect").html($options.find(`optgroup[label="${state}"]`).html());
});
EDIT:
Notice the double quote in optgroup[label="${state}"]
. This prevents issue with states that contain a space, like Akwa Ibom
.
Upvotes: 1
Reputation: 171679
Make a clone of the stored options so you don't remove the originals from $(hiddenLga)
Change:
$(lgaSelect).html(options.children());
To
$(lgaSelect).html(options.children().clone());
Upvotes: 1