问题
I use Chosen jQuery plugin on a multiple select element.
I want to retrieve and to display the options value in the order they were selected (clicked).
For example, if I click on "Three", "Two" then "One", I should get the values in this order: [3, 2, 1]
I use the 'change' event of Chosen but it gives me the values ordered as they are declared in the DOM. i.e.: [1, 2, 3]
Here is my code snippet:
<select class="chosen" data-order="true" name="multiselect[]" id="multiselect" multiple="true">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>
</select>
<div id="result"></div>
<script type="text/javascript" src="jquery-1.11.0.js"></script>
<script type="text/javascript" src="chosen.jquery.min.js"></script>
<script type="text/javascript">
$(".chosen").chosen({enable_search_threshold: 10}).change(function(event) {
if(event.target == this) {
var value = $(this).val();
$("#result").text(value);
}
});
</script>
jsFiddle demo: http://jsfiddle.net/FjET4
回答1:
You are facing a common issue with Chosen. Chosen multiple select UI does not actually handle selection order.
By the way, the following part is not specific to the event:
if(event.target == this)
{
var value = $(this).val();
$("#result").text(value);
}
In fact, it does exactly the same thing everytime you select an item. With $(this).val()
you are basically just asking Chosen to retrieve an array of the values of the selected elements.
And because Chosen does not handle selection order, it just sends you ["1", "2", "3"]
.
A method to retrieve the selection order as it appears is to iterate though some children of the Chosen UI. Look:
<!-- Chosen UI container -->
<div class="chosen-container chosen-container-multi ..." id="multiselect_chosen">
<ul class="chosen-choices">
<li class="search-choice">
<span>Three</span>
<a class="search-choice-close" data-option-array-index="2"></a>
</li>
<li class="search-choice">
<span>Five</span>
<a class="search-choice-close" data-option-array-index="4"></a>
</li>
....
</ul>
...
</div>
As you can see, there is some interesting stuff in <ul class="chosen-choices"></ul>
. The data-option-array-index
attribute contains the index of the selected item, relative to the actual <select>
DOM element options.
I wrote a small plugin for Chosen that allows you to retrieve the selection order, exactly as it appears, and to force it via an array of ordered values (e.g.: ["3", "2", "1"]
).
It is open-source and works for both Chosen jQuery plugin and Prototype plugin.
- Demonstration: http://labo.tristan-jahier.fr/chosen_order
- Github repository: https://github.com/tristanjahier/chosen-order
回答2:
The Chosen plugin has a "change" event that you can use to keep and update a list with selected items, in the order in which they were selected.
$("#mnu_chosen").on('change', function(e, params) {
var selected = params.selected;
var deselected = params.deselected;
var selected_keys = $(this).data('selected_keys');
if (!selected_keys) {
$(this).data('selected_keys', []);
selected_keys = $(this).data('selected_keys');
}
if (deselected) {
for (var i = 0; i < selected_keys.length; i++) {
if (selected_keys[i] == deselected) {
selected_keys.splice(i, 1);
break;
}
}
}
if (selected) {
selected_keys.push(selected);
}
//See array "selected_keys"
//Do something on change...
});
回答3:
Here's a stand alone function that does the job. I'm using Chosen 1.2.0
var orderBy = ChosenValInSelectedOrder('OrderReportBy');
function ChosenValInSelectedOrder(id) {
var $chosenOptions = $('#' + id + '_chosen .search-choice-close');
if ($chosenOptions.length == 0)
return null;
var results = [];
var $options = $('#' + id + ' option');
$chosenOptions.each(function () {
var idx = parseInt($(this).attr('data-option-array-index'));
results.push($options[idx].value); // value from original select
});
return results;
}
来源:https://stackoverflow.com/questions/21659224/chosen-jquery-plugin-get-multiple-select-values-in-the-order-they-were-clicked