Reputation: 10207
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.
Upvotes: 0
Views: 484
Reputation: 207501
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>
Upvotes: 2
Reputation: 625
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>
Upvotes: 1