2

I have two drop down list; one with states and the other with cities. I want the second list with cities to show only the cities in the selected state. Why is this not working?

$(document).ready(function($) {
  $("#state").change(function() {
    var selected_state = $("#state").val(); //get the selected state
    $("#city").children().hide(); //hide all the options
    $("#selected_state").children().show(); //only show cities in selected state
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
  State: <select name="state" id="state">
            <option value="state1">State1</option>
            <option value="state2">State2</option>
        </select> City:
  <select name="city" id="city">
            <div id="state1">
               <option value="0">City1a</option>
               <option value="1">City1b</option>
               <option value="2">City1c</option>
            </div>
            <div id="state2">
               <option value="3">City2a</option>
               <option value="4">City2b</option>
               <option value="5">City2c</option>
            </div>
        </select>
  <input name="submit" type="submit" value="Submit" />
</form>
Pedram
  • 15,766
  • 10
  • 44
  • 73
user9049171
  • 23
  • 1
  • 3
  • Look like there is no any link between state and city , And do not wrap options with `div` – Pedram Dec 04 '17 at 06:33
  • No id 'selected_state' in your code...it is a variable, you use it like a string...And, beside that, not sure that this will work... – sinisake Dec 04 '17 at 06:34

7 Answers7

2

You should make a link between states and cities for example with data-state:

<option value="0" data-state="state1">City1a</option>

$("#state").change(function() {
  var selected_state = $(this).val();
$('#city').removeAttr('disabled').children('option').hide();
  $('#city option[data-state="' + selected_state + '"]').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">

  <label>State:</label>
  <select name="state" id="state">
 <option>-- choose state--</option>
<option value="state1">State1</option>
<option value="state2">State2</option>
</select>

  <label>City:</label>
  <select name="city" id="city" disabled>
 <option>-- choose city --</option>
<option value="0" data-state="state1">City1a</option>
<option value="1" data-state="state1">City1b</option>
<option value="2" data-state="state1">City1c</option>
<option value="3" data-state="state2">City2a</option>
<option value="4" data-state="state2">City2b</option>
<option value="5" data-state="state2">City2c</option>
</select>

  <input name="submit" type="submit" value="Submit" />
</form>

And DO NOT wrap options with div or anything else, it's invalid.

Pedram
  • 15,766
  • 10
  • 44
  • 73
  • Thanks for your help. Another user suggested using a class for each option entered to be able to filter the cities shown. Would there be any advantage to either using classes or data-state or is it just a matter of personal preference. (Keeping in mind that the number of states and cities will be much greater than what I have shown here) – user9049171 Dec 05 '17 at 04:18
0

Problems in your code

  • selected_state is a variable
  • cant place div inside select options

$(document).ready(function($) {
  $("#state").change(function() {
    var selected_state = $("#state").val(); // get the selected state
    $("#city").children().hide(); // hide all the options
    $("." + selected_state).show(); // only show cities in selected state
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
  State: 
  <select name="state" id="state">
      <option value="state1">State1</option>
      <option value="state2">State2</option>
  </select> City:
   
   <select name="city" id="city">
    <option class="state0" value="-1">-select city-</option>
         <option class="state1" value="0">City1a</option>
         <option class="state1" value="1">City1b</option>
         <option class="state1" value="2">City1c</option>

         <option class="state2" value="3">City2a</option>
         <option class="state2" value="4">City2b</option>
         <option class="state2" value="5">City2c</option>
  </select>
  
  <input name="submit" type="submit" value="Submit" />
</form>
Sudarpo Chong
  • 608
  • 4
  • 12
0
  • Don't use the div inside select.
  • The way you used the selected_state is not how to use it.
  • You should be able to make out a relation with both the drop down.

Something like this is what you have to do.

<form method="post">
State: <select name="state" id="state">
    <option value="">Select</option>
    <option value="state1">State1</option>
    <option value="state2">State2</option>
</select>
City: 
<select name="city" id="city">

</select>     
<input name="submit" type="submit" value="Submit" />

    $(document).ready(function($) {     
    $("#state").change(function() {
        var selected_state =$("#state option:selected").val(); //get the selected state
        GetAllCityByState(selected_state);
    });

        function GetAllCityByState(stateid) {
        $("#city").html('');
        $("#city").empty();
        if(stateid == "state1")
        {
          $("#city").append($("<option></option>").val(0).html("City1a"));
          $("#city").append($("<option></option>").val(1).html("City1b"));
          $("#city").append($("<option></option>").val(2).html("City1c"));
        }
        else if(stateid == "state2")
        {
          $("#city").append($("<option></option>").val(3).html("City2a"));
          $("#city").append($("<option></option>").val(4).html("City2b"));
          $("#city").append($("<option></option>").val(5).html("City2c"));
        }
        $("#city").select().val();
    }
});

Please find the fiddle here

Hrishikesh
  • 632
  • 3
  • 13
0

Don't use div inside select . You can try this way.

$(document).ready(function($) {
  var c1 = '<option value="0">City1a</option><optionvalue="1">City1b</option><option value="2">City1c</option>'
  var c2 = ' <option value="3">City2a</option> <option value="4">City2b</option><option value="5">City2c</option>'
  $("#city").html(c1);
  $("#state").change(function() {
$("#city").html('');

var selected_state = $("#state").val(); //get the selected state
if (selected_state == 'state1')
  $("#city").html(c1);
else
  $("#city").html(c2);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
  State: <select name="state" id="state">
            <option value="state1">State1</option>
            <option value="state2">State2</option>
        </select> City:
  <select name="city" id="city">
            
  </select>
  <input name="submit" type="submit" value="Submit" />
</form>
4b0
  • 21,981
  • 30
  • 95
  • 142
0
<form method="post">
State: <select name="state" id="state">
    <option value="state1">State1</option>
    <option value="state2">State2</option>
</select>
City: 
    <div id="state1">
    <select name="city" id="city">
       <option value="0">City1a</option>
       <option value="1">City1b</option>
       <option value="2">City1c</option>
       </select>
    </div>
    <div id="state2">
    <select name="city" id="city">
       <option value="3">City2a</option>
       <option value="4">City2b</option>
       <option value="5">City2c</option>
    </select>  
    </div>

<input name="submit" type="submit" value="Submit" />

<script type="text/javascript">
    $(document).ready(function() { 
    $("#state1").hide();
    $("#state2").hide();
    $("#state").change(function() {
    var selected_state =document.getElementById("state").value;
    // $("#city").children("state1").hide(); //hide all the options
    if(selected_state === "state1"){
        alert(selected_state);
        $("#state1").show();
        $("#state2").hide();
    }else{
        $("#state1").hide();
        $("#state2").show();
    }
    //$("#selected_state").children().show(); //only show cities in selected state
    });
}); 
</script>
Girish
  • 366
  • 3
  • 15
0

You can use optgroup tag, instead divs, to wrap your options, so your HTML will look like this:

<form method="post">
    State: <select name="state" id="state">
        <option value="state1">State1</option>
        <option value="state2">State2</option>
    </select>
    City: 
    <select name="city" id="city">
        <optgroup label="state1" id='state1'>
           <option value="0">City1a</option>
           <option value="1">City1b</option>
           <option value="2">City1c</option>
        </optgroup>
        <optgroup label="state2" id='state2'>
           <option value="3">City2a</option>
           <option value="4">City2b</option>
           <option value="5">City2c</option>
        </optgroup>
    </select>     
    <input name="submit" type="submit" value="Submit" />
</form>

And then, few small changes in your code:

$("#state").change(function() {
    var selected_state =$("#state").val(); //get the selected state


    $("#city optgroup").not('#'+selected_state).hide();
    $("#"+selected_state).show(); //only show cities in selected state
    $('#city').val($("#"+selected_state).children().first().val());

});

Demo:

 $("#state").change(function() {
        var selected_state =$("#state").val(); //get the selected state
        
        
        $("#city optgroup").not('#'+selected_state).hide();
        $("#"+selected_state).show(); //only show cities in selected state
        $('#city').val($("#"+selected_state).children().first().val());
      
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
    State: <select name="state" id="state">
        <option value="state1">State1</option>
        <option value="state2">State2</option>
    </select>
    City: 
    <select name="city" id="city">
        <optgroup label="state1" id='state1'>
           <option value="0">City1a</option>
           <option value="1">City1b</option>
           <option value="2">City1c</option>
        </optgroup>
        <optgroup label="state2" id='state2'>
           <option value="3">City2a</option>
           <option value="4">City2b</option>
           <option value="5">City2c</option>
        </optgroup>
    </select>     
    <input name="submit" type="submit" value="Submit" />
</form>

As you can see, now code pointing to variable (id is variable), and your html is valid (no divs iniside select).

sinisake
  • 11,240
  • 2
  • 19
  • 27
  • `optgroup` is best way instead of `div` but there is no need to use `optgroup ` because` you hide all `options` then just show selected. – Pedram Dec 04 '17 at 07:06
  • 1
    @pedram, many possibilities here... i just wanted to keep HTML structure as close as possible to OP's HTML...Of course, few good solutions here (with additional data attributes, like you suggested, or with creating/appending html for another select)... :) – sinisake Dec 04 '17 at 07:17
0

you can't handle options with style How to remove/hide select options from select-list

$(document).ready(function($) {

  var states = {
            "state1":["City1a","City1b", "City1c"]
            ,
            "state2":["City2a" , "City2b", "City2c"]
            };
  var state_option = (state) => states[state].map( (s,n)=> '<option value="'+n+'">'+s+'</option>' ).join();  
  $("#city").html( state_option("state1") );
  $("#state").change(function() {
    var selected_state = $("#state").val(); //get the selected state
    $("#city").html( state_option(selected_state) );
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
  State: <select name="state" id="state">
            <option value="state1">State1</option>
            <option value="state2">State2</option>
        </select> City:
        <select name="city" id="city">
        </select>
  <input name="submit" type="submit" value="Submit" />
</form>
nullqube
  • 2,959
  • 19
  • 18