A Select2 can be chained in the same way that a standard <select>
can be chained. So that means that when the value of the first select is chained, the second select is reset (generally to a placeholder) and the options generally change as well.
You have two options for how this can be done with Select2:
Pre-load the options for the second <select>
when the value changes, and let Select2 handle searching locally. This would be similar to how you are currently trying to do it, but may suffer from issues when there are a large number of options that can be selected in the second <select>
.
In your case, there shouldn't be thousands of "states" (for whatever degree of state) within a country, so local searching shouldn't be too much of an issue.
Use Select2's AJAX functionality and pass in a different parameter as the url
to use based on the value of the first <select>
. This requires that you have a dynamic endpoint that can handle retrieving the items for the second select as well as filtering them when searching, so it's not always feasible.
If you already have an endpoint like this that supports filtering, this is a more responsive option as the user doesn't have to necessarily wait for all options to be retrieved before they can select an option from the second <select>
.
What option you choose largely depends on what you already have set up, the size of the data set that you are working with (Select2 does not handle well with thousands of options), and the user experience you want to provide.
The code for the first option would be similar to
$("#first").select2({
placeholder: 'Select a number range'
});
$("#second").select2({
placeholder: 'Select a number'
});
$("#first").on("change", function () {
$("#second option[value]").remove();
var newOptions = []; // the result of your JSON request
$("#second").append(newOptions).val("").trigger("change");
});
And can be tested at the following jsbin, using ranges of numbers instead of countries and states: http://jsbin.com/wigalivapi/1/edit?html,output
Note that while this is similar to the code you were using, there are a few small difference that would have caught you.
You are setting dataType: "html"
when you are really expecting dataType: "json"
. You are returning JSON in your response, not HTML.
You are not clearing your <select>
before you call .select2({data:[]})
a second time. Select2 doesn't automatically remove the <option>
tags it generates with data
, so you need to do that on your own.
When you change the value of the <select>
, you never tell Select2 about it. You need to re-trigger the change
event on the second <select>
after you change it.
The JSON that you provide in your question does not appear to be valid. Now I'm not sure if that is just because you are giving it as an example, but I would check your JSON response with JSONLint just to ensure that it is valid.
The code for the second option would be similar to
$("#first").select2({
placeholder: 'Select a number range'
});
$("#second").select2({
placeholder: 'Select a number',
ajax: {
url: http://localhost/CodeIgniter/countries/get_state/',
type: 'POST',
data: function (params) {
return {
id: $("#first").val(),
search: params.term
}
}
}
});
And this can be tested at the following jsbin, which mocks the response using a range of numbers (similar to the other example): http://jsbin.com/gihusohepe/1/edit?html,output
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…