Home > other >  How to retain dependent dropdown values using Select2 and Ajax
How to retain dependent dropdown values using Select2 and Ajax

Time:11-28

I have a script that populates the state dropdown based on country id and while everything is working great I can only save the countries dropdown option on page reload but not the state option using html localStorage.

Here is my code:

$(document).ready(function() {
  var country_id = null;
  var state_id = null;

  $('#country').select2();
  $('#state').select2();
  $('#city').select2();

  $('select[name="country"]').on('change', function() {
    var country_id = $(this).val();
    if (country_id) {
      $.ajax({
        url: "/world/getStates.php",
        type: "GET",
        data: {
          'country_id': country_id
        },
        dataType: "json",
        success: function(data) {
          $('select[name="state"]').empty();
          $('select[name="city"]').empty();
          $('select[name="state"]').append('<option value="">Select State</option>');
          $.each(JSON.parse(data), function(key, value) {
            $('select[name="state"]').append('<option value="'   value.id   '">'   value.name   '</option>');
          });
        }
      });
    } else {
      $('select[name="state"]').empty();
    }
  });

  $('select[name="state"]').on('change', function() {
    var country_id = $('#country').val();
    var state_id = $(this).val();
    if (state_id) {
      $.ajax({
        url: "/world/getCities.php",
        type: "GET",
        data: {
          'country_id': country_id,
          'state_id': state_id
        },
        dataType: "json",
        success: function(data) {
          $('select[name="city"]').empty();
          $('select[name="city"]').append('<option value="">Select City</option>');
          $.each(JSON.parse(data), function(key, value) {
            $('select[name="city"]').append('<option value="'   value.id   '">'   value.name   '</option>');
          });
        }
      });
    } else {
      $('select[name="city"]').empty();
    }
  });

  $('#country').val("value from localStorage").trigger('change');
  $('#state').val("value from localStorage").trigger('change');
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>

<label for="country">Country</label>
<select class="csc-select" name="country" id="country">
  <option value="">Select Country</option>
  <option>Australia</option>
  <option>Denmark</option>
  <option>Japan</option>
  <option>Norway</option>
  <option>Switzerland</option>
</select>

<label for="state">State</label>
<select class="csc-select" name="state" id="state">
  <option value="">Select State</option>
</select>

<label for="city">City</label>
<select class="csc-select" name="city" id="city">
  <option value="">Select City</option>
</select>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

So when I call this after the first on change for the country select, it selects the country based on the localStorage value and triggers the change but it does not do the same for the state, any ideas what I am missing here?

CodePudding user response:

Your options inside state dropdown is loaded after the ajax success is executed so your other code doesn't wait for that and .val() fired before only that's the reason the value is not marked as selected inside state dropdown. Now , to fix this you can move that part inside success function of ajax and then call your change event after the options are appended inside state dropdown.

Demo Code :

$(document).ready(function() {

  var country_id = 1 //localStorage.getItem("select2CountryValue");
  var state_id = 3 //localStorage.getItem("select2StateValue");
  var page_load = true; //added this 
  var data = [{
    "id": 1,
    "name": "xyz_State1"
  }, {
    "id": 2,
    "name": "xyz_State2"
  }, {
    "id": 3,
    "name": "xyz_State3"
  }] //this is just the demo datas
  $('#country').select2();
  $('#state').select2();

  $('select[name="country"]').on('change', function() {
    var country_id = $(this).val();
    //localStorage.setItem("select2CountryValue", country_id);
    if (country_id) {
      /*$.ajax({
        url: "/world/getStates.php",
        type: "GET",
        data: {
          'country_id': country_id
        },
        dataType: "json",
        success: function(data) {
          console.log(data);
          $('select[name="city"]').empty();*/
      $('select[name="state"]').empty();
      $('select[name="state"]').append('<option value="">Select State</option>');
      $.each(data, function(key, value) {
        $('select[name="state"]').append('<option value="'   value.id   '">'   value.name   '</option>');
      });
      //check if the change is called on page load
      if (page_load == true) {
        $('#state').val(state_id).trigger('change'); //assign slected value after elemnt option is added in dom
        page_load = false; //add this so that next time this doesn't get execute
      }
      /* }
        });*/
    } else {
      $('select[name="state"]').empty();
    }
  });

  $('#country').val(country_id).trigger('change');

});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" />
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.full.min.js"></script>

<p>
  <span>Country</span>
  <select class="csc-select" name="country" id="country">
    <option value="">Select Country</option>
    <option value="1">
      xyz
    </option>
    <option value="2">
      xyz2
    </option>
  </select>
</p>
<p>
  <span>State</span>
  <select class="csc-select" name="state" id="state">
    <option value="">Select State</option>
  </select>
</p>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

when I call this after the first on change for the country select, it selects the country based on the localStorage value and triggers the change but it does not do the same for the state, any ideas what I am missing here?

When you trigger the change event for your #country list, the list of countries already contains values.

When you trigger the change event for your #state list immediately after that, the list is still empty. There can't be any value selected, so the change event does nothing.

You need to wait until the state list is populated, and then trigger the change event.

// this works immediately, because there are countries in your HTML
$('#country').val("value from localStorage").trigger('change');

// this needs to happen in the `success` callback of country Ajax call
$('#state').val("value from localStorage").trigger('change');
  • Related