Skip to content

Instantly share code, notes, and snippets.

Last active November 23, 2022 07:27
What would you like to do?
Making Select2 (4.x) list boxes cascading / dependent. Options of a select2 list box will be loaded/refreshed by ajax based on selection of another select2 list box.
* A Javascript module to loadeding/refreshing options of a select2 list box using ajax based on selection of another select2 list box.
* @url :
* @auther : Anis Uddin Ahmad <>
* Live demo -
* w: | t: @ajaxray
var Select2Cascade = ( function(window, $) {
function Select2Cascade(parent, child, url, select2Options) {
var afterActions = [];
var options = select2Options || {};
// Register functions to be called after cascading data loading done
this.then = function(callback) {
return this;
parent.select2(select2Options).on("change", function (e) {
child.prop("disabled", true);
var _this = this;
$.getJSON(url.replace(':parentId:', $(this).val()), function(items) {
var newOptions = '<option value="">-- Select --</option>';
for(var id in items) {
newOptions += '<option value="'+ id +'">'+ items[id] +'</option>';
child.select2('destroy').html(newOptions).prop("disabled", false)
afterActions.forEach(function (callback) {
callback(parent, child, items);
return Select2Cascade;
})( window, $);

Select2 Cascade (for v4.x)

Loadeding/refreshing options of a select2 list box (using ajax) based on selection of another select2 list box.

Check the live demo.

How to use

Create a new instance of Select2Cascade by passing the following 4 things -

  • Parent select2 listbox
  • Child select2 listbox
  • URL to load child items from
  • (OPTIONAL) select2 options

To set the parent selected value in ajax request, keep :parentId: as a placeholder in url. The selected value of parent select2 listbox will replace the :parentId: string in url. For example -
Query string: /path/to/api?type=childType&parent_id=:parentId:
RESTful url: /path/to/api/items/:parentId:/sub-items

The response json should be a flat object of value:label pairs. e,g,

  "20150415" : "Chittagong Zila",
  "20190901" : "Comilla Zila",
  "20221601" : "Cox's Bazar Zila",
  "20301401" : "Feni Zila"

Otherwisw you have to adjust the way of populating child options (at line 29).


When #parentList is changed, call to path/to/geocode/district/SELECTED-PARENT/zilla and set the options of #childList from the ajax response.

var options = { width: 'resolve' };
new Select2Cascade($('#district'), $('#zilla'), 'path/to/geocode/district/:parentId:/zilla', options);
new Select2Cascade($('#zilla'), $('#thana'), 'path/to/geocode/zilla/:parentId:/thana', options);

If you want to do something with the response data or selectboxes, you can set (any number of) callbacks to be executed after the child listbox refreshed -

var cascadLoading = new Select2Cascade($('#parent'), $('#child'), 'path/to/api/categories?parent_id=:parentId:');
cascadLoading.then( function(parent, child, items) {
    // Open the child listbox immediately
    // Dump response data
Copy link

Is failing in the pen.

screen shot 2018-09-16 at 15 54 08

Copy link

ajaxray commented Apr 16, 2019

Hello @seanfcarroll,
Thanks for notifying! I've fixed it.
Actually, I was using content as sample API response, which has been expired.
So, now I have made a gist with 2 sample json file and using their raw version as API response.

Copy link

Thanks @ajaxray !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment