Reputation: 1205
Select2 (v3.5.1) have a Drag&Drop function but only für "input" fields. I need a value/text combination, so only a selectbox is for me the right choice.
I found a (part) solution for my problem here: http://joevanderjagt.com/better-multiple-select-with-sorting/
But, its have a bug. Its working fine with sorting tags, but not, if user only add tags without sorting. I have created a jsfiddle: http://jsfiddle.net/s8v3su36/
<select id="test" size="1" multiple="multiple" style="width:400px">
<option value="a">AAA</option>
<option value="b">BBB</option>
<option value="c">CCC</option>
</select>
(function($){
$.fn.extend({
select2_sortable: function(){
var select = $(this);
$(select).select2();
var ul = $(select).prev('.select2-container').first('ul');
ul.sortable({
placeholder : 'ui-state-highlight',
forcePlaceholderSize: true,
items : 'li:not(.select2-search-field)',
tolerance : 'pointer',
stop: function() {
$($(ul).find('.select2-search-choice').get().reverse()).each(function() {
var id = $(this).data('select2Data').id;
var option = select.find('option[value="' + id + '"]')[0];
$(select).prepend(option);
});
}
});
}
});
$('#test').select2_sortable();
}(jQuery));
Add first "CCC" and now "BBB" and press debug button. You will see order "AAA, BBB, CCC" but must be "CCC,BBB,AAA"
Now use drag&drop the move "BBB" as first entry. click again debug button and see correct order "BBB,CCC,AAA".
Can anybody help here? I wish that add a entry is sorting the option in select too. :)
POSSIBLE SOLUTION: http://jsfiddle.net/s8v3su36/4/
Upvotes: 1
Views: 9726
Reputation: 178
I have simplified it; you can try using this code. I hope it works:
var selectable = $('#id').select2();
selectable.next().children().children().children().sortable({
containment: 'parent', stop: function (event, ui) {
ui.item.parent().children('[title]').each(function () {
var title = $(this).attr('title');
var original = $( 'option:contains(' + title + ')', selectable ).first();
original.detach();
selectable.append(original)
});
selectable.change();
}
});
Upvotes: 0
Reputation: 389
I rewrote the code from (@ambroiseRabier). My code is more clean, don't use $(ul).find to find selected options. Instead it uses the passed ui element, to find selected options and original select element that needs to be updated. This version works properly if you have more Select2 instances in the web page.
(function ($) {
$.fn.select2Sortable = function () {
this.next().children().children().children().sortable({
containment: 'parent', stop: function (event, ui) {
var originalSelectElement = ui.item.parent().parent().parent().parent().prev();
ui.item.parent().children('[title]').each(function () {
var title = $(this).attr('title');
var originalOptionElem = $(originalSelectElement).children('[value="' + title + '"]');
originalOptionElem.detach();
$(originalSelectElement).append(originalOptionElem)
});
$(originalSelectElement).change();
}
});
};
})(jQuery);
Upvotes: 0
Reputation: 7832
With vue.js - please consider using this component (compact on the page, comfortable to use even with long list of options):
https://www.npmjs.com/package/vue-libs-multi-select-with-order
Upvotes: 1
Reputation: 1205
Added:
$(select).on("change", function(e)
{
if (e.added)
{
var select = $(this);
var ul = $(select).prev('.select2-container').first('ul');
$($(ul).find('.select2-search-choice').get().reverse()).each(function() {
var id = $(this).data('select2Data').id;
var option = select.find('option[value="' + id + '"]')[0];
$(select).prepend(option);
});
}
});
Upvotes: 0
Reputation: 2736
Your magic debug button just outputs the <select>
children, which remain the same when the page first loads or you add options to the select2 div
.
Only after you stop the drag, the stop
function gets executed and rearranges the <option>
tags.
Try to reorder your <select>
on the add
event too.
Upvotes: 0