svcputl3y7 svcputl3y7 - 9 days ago 6
HTML Question

jQuery selector add a string ,but selected get undefined value

As the code below, they actually have 5 school drop-down and 5 departments drop-down list. So, it'll have five id, which is

school_1
,
school_2
,
school_3
...so on. The options are all same in these five school drop-down, same value, same text.

The department drop-down(
id="dept_x"
) would show different departments list which belongs to the school that I selected in school drop-down list.

The
school_1
connect with
dept_1
,and
school_2
connect with
dept_2
and ...so on.

Now, I have a problem with getting value in selected. The code
var school_code = $("#school_" + num).val();
in the jQuery. I always get value
undefined
.

if I use selector
"#school_1
or
"#school_2
or other else, instead of
"#school_" + num
,then it would work perfectly. It all do the same thing, so I choose to use for loop.

How do I fix this? or other better way?

Thank you so much!

The example HTML:

<select id="school_1" name="school_1" class="form-control">
<option value="1001">school-A</option>
<option value="1002">school-B</option>
<option value="1003">school-C</option>
<option value="1004">school-D</option>
</select>

<select id="dept_1" name="dept_1" class="form-control"></select>


The jQuery:

var school_num = '5'; //the value 5 is comes from a php variable and it's a string.
for(var num = 1; num <= parseInt(school_num); num++){

num = String(num);
//console.log("#school_" + num);

$("#school_" + num).change(function(){
$("#dept_" + num + " > option").remove();

var school_code = $("#school_" + num).val();
console.log(school_code);

//then doing ajax to get department data in the database.

});
}

Answer

You need to use a closure to ensure the num value within the change event handler is what you expect it to be, and not the last value in the array - as the for loop will have finished long before any change event has fired.

var school_num = '5';
for(var num = 1; num <= parseInt(school_num, 10); num++){
    (function(num) {
        $("#school_" + num).change(function(){
            $("#dept_" + num + " > option").remove();
            var school_code = $("#school_" + num).val();

            //then doing ajax to get department data in the database.
       });  
    })(num)
}

That being said you can massively improve the logic by using common classes and a single event handler. You can then use DOM traversal from the first select to find the related select. This will completely remove the need for the loop. Try this:

$('.school').change(function() {
  var $dept = $(this).next('.dept').empty()
  var school_code = $(this).val();
  console.log(school_code)

  //then doing ajax to get department data in the database.
  $dept.append('<option>Foo</option>'); // just an example
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="school" name="school_1" class="form-control">
  <option value="1001">school-A</option>
  <option value="1002">school-B</option>
  <option value="1003">school-C</option>
  <option value="1004">school-D</option>
</select>

<select class="dept" name="dept_1" class="form-control"></select>

<select class="school" name="school_2" class="form-control">
  <option value="1001">school-A</option>
  <option value="1002">school-B</option>
  <option value="1003">school-C</option>
  <option value="1004">school-D</option>
</select>

<select class="dept" name="dept_2" class="form-control"></select>