I have the following two select boxes:
<select id="project">
<option data-person_ids="[75,76,77]">None</option>
<option data-person_ids="[77]">Project A</option>
<option data-person_ids="[75,76]">Project B</option>
<option data-person_ids="[75]">Project C</option>
</select>
<select id="person">
<option value="75">Person A</option>
<option value="76">Person B</option>
<option value="77">Person C</option>
</select>
How can I filter the #person
options based on the value selected in #project
?
This is a jQuery code snippet that a colleague came up with but I was unable to get it working because I am still new to jQuery:
$(function() {
var $person = $('#person');
$allPersonOptions = $person.children();
$('#project').on('change', function() {
var selected_project = $('#project').data('person_ids');
filterOptions($allPersonOptions.clone(), +selected_project).appendTo($person.empty());
});
});
function filterOptions($options, id) {
return $options.filter(function() {
return $.inArray(id, $(this).data('project_ids')) > -1
});
}
Thanks for any help in this matter.
Well your colleague gave you bad code.
First
var selected_project = $('#project').data('person_ids');
will return undefined since it is not on the select, it is on the option. It does not magically get the selected option's data attribute
var selected_project = $('#project option:selected').data('person_ids');
Next there is a random + in the code
filterOptions($allPersonOptions.clone(), +selected_project).appendTo($person.empty());
^^^
That is going to do a conversion, bad.
Next the filter code is looking for a data attribute
return $.inArray(id, $(this).data('project_ids')) > -1
There is no data attribute on that select's options. And the arguments are switched.
$(function() { var $person = $('#person'); $allPersonOptions = $person.children(); $('#project').on('change', function() { var selected_project = $('#project option:selected').data('person_ids'); filterOptions($allPersonOptions.clone(), selected_project).appendTo($person.empty()); }); }); function filterOptions($options, id) { return $options.filter(function() { return $.inArray(parseInt(this.value,10), id) > -1 }); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <select id="project"> <option data-person_ids="[75,76,77]">None</option> <option data-person_ids="[77]">Project A</option> <option data-person_ids="[75,76]">Project B</option> <option data-person_ids="[75]">Project C</option> </select> <select id="person"> <option value="75">Person A</option> <option value="76">Person B</option> <option value="77">Person C</option> </select>
I have a version that reuses allPersonOptions (no need to clone) and only copies applicable options.
$(function() { var $person = $('#person'); $allPersonOptions = $person.children(); $('#project').on('change', function() { var ids = $('#project option:selected').data('person_ids'); $person.empty(); $allPersonOptions.each( function() { var id = parseInt($(this).attr('value')); if ($.inArray(id, ids) != -1 ) $person.append(this); }) }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <select id="project"> <option data-person_ids="[75,76,77]">None</option> <option data-person_ids="[77]">Project A</option> <option data-person_ids="[75,76]">Project B</option> <option data-person_ids="[75]">Project C</option> </select> <select id="person"> <option value="75">Person A</option> <option value="76">Person B</option> <option value="77">Person C</option> </select>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.