Reputation: 3434
I have an multiselect with 10 or more options. I select the options in a random order.
The problem is that when I submit the form, the elements are sent in the order of the options, not in the order that I selected them.
So let's say I have:
<option value="1">AAA</option>
<option value="2">BBB</option>
<option value="3">CCC</option>
<option value="4">DDD</option>
<option value="5">EEE</option>
<option value="6">FFF</option>
<option value="7">GGG</option>
<option value="8">HHH</option>
If I select the elements in the following order: 1, 4, 2, 8 , when I submit the form, the order of the elements is: 1,2,4,8. And this is wrong, because I want the order to respect the selection done by me.
I tied to manually set the order using:
$object.val(JSON.parse("[" + newVal.split(',') + "]"));
where newVal is a string with the id's 1,4,2,8 (in the order that I selected them), but it doesn't work.
If I try:
$object.val(JSON.parse("[" + newVal.split(',')[0] + "]"));
It will set the value of 1 (first element), which is good, but if I send an array it doesn't work.
Any idea how can I fix this problem will help. Anticipated thanks!
Upvotes: 1
Views: 477
Reputation: 3434
I have a complex application and there are multiple trigger('click') / trigger('blur') events. In my case I had to set a timeout and to reorder the options.
I've seen that the submitted order is the options order. So my idea was to move the selected options to the top of the select. So if there's no selected option, I will move the option to be first. If there are selected options, I will add the selected option after the latest selected option.
I know it's not the best solution, but it's working good.
My code looks like:
this.orderElementInitData = function (id) {
var newSelectOption = select.find('option[value="' + id + '"]');
select.find('option[value="' + id + '"]').remove();
var firstSelected = select.find('option:eq(0)').attr('selected');
if(typeof firstSelected !== typeof undefined && firstSelected !== false) {
select.find('option[selected="selected"]:last').after(newSelectOption);
} else {
select.find('option:eq(0)').before(newSelectOption);
}
};
Upvotes: 1
Reputation: 523
Following is the one of the way to achieve that:
first of all you need to edit your "option tags" by adding data-attribute "data-order=''"
<option value="100" data-order="">foo</option>
<option value="101" data-order="">bar</option>
<option value="102" data-order="">bat</option>
<option value="104" data-order="">baz</option>
<option value="105" data-order="">baz</option>
<option value="106" data-order="">baz</option>
<option value="107" data-order="">baz</option>
<option value="108" data-order="">baz</option>
then apply the following jquery
$(document).keydown(function(event){
if(event.which=="17")
cntrlIsPressed = true;
});
$(document).keyup(function(){
cntrlIsPressed = false;
});
var cntrlIsPressed = false;
var order = 1;
$("#data").on("click", "option", function() {
var clickedOption = $(this);
if (cntrlIsPressed)
{
if (clickedOption.data("order") == "")
{
clickedOption.data("order", order);
order++;
}
else {
clickedOption.data("order", "");
order--;
}
}
else
{
$("#data option").data("order", "");
order = 1
clickedOption.data("order", order);
order++;
}
});
function showOrder()
{
var myArr = [$("#data option").length];
$("#data option").each(function () {
var index = parseInt($(this).data("order"));
myArr[index-1] = $(this).val();
});
console.log(myArr);
}
Upvotes: 2