最近項目上需要使用多選控件,於是查閱了下資料並對比demo的效果,最終選擇了select2控件。
下載及使用方法請參考:https://select2.github.io/
問題1:已選擇的選項始終在下拉菜單中,只是狀態為選中樣式,再次點擊取消選擇
v3.5.x版本中:已選擇的選項不會再出現在下拉菜單中,只有取消選擇后才會再次出現在菜單中。
v4.x.x版本中:已選擇的效果已經被修改,已選擇的選項始終在下拉菜單中,只是狀態為選中樣式,再次點擊取消選擇
然而項目需求更傾向於v3.5.x版本的效果,查找了下解決方法如下:通過設置css樣式來使已選擇的選項不顯示
.select2-results__option[aria-selected=true]{
display:none;
}
問題2:已選中項的展示順序與它在下拉菜單中的順序一致
v3.5.x版本中:已選擇的選項展示的順序與用戶點擊選擇的先后順序一致,換句話說就是新選中的項目會出現在展示列表的最后
v4.x.x版本中:已選擇的選項展示順序與它在下拉菜單中的順序一致。
可以通過下面的代碼來解決新選擇的項目順序問題(但是這個方法不能解決默認選中項的順序問題,解決方法在問題4)
$("#sel_menu2").on("select2:select",function(evt){
varelement=evt.params.data.element;
var$element=$(element);
$element.detach();
$(this).append($element);
$(this).trigger("change");
});
參考:http://stackoverflow.com/questions/31431197/select2-how-to-prevent-tags-sorting
問題3:設置默認選中項
對於用戶已選中並保存的選項,下次再次進入頁面時,需要展示默認選中項。
方法如下:(這個方法存在顯示順序問題,如例子中設置的是["1707","1706"],但顯示的是"1706","1707",因為是按照選項在列表中的順序展示)
$("#sel_menu2").val(["1707","1706"]).trigger('change');//trigger('change')
問題4:默認選中項以及新選擇項的排序問題
在問題2和問題3中都提到了選中項的展示順序問題,一開始我查了很久的資料,只找到問題2中對新選擇項的排序解決方法。
方法1:於是對於默認選中項的展示順序,我想了一個變通的方法。既然展示的順序是跟選項列表的順序一致,那么我就把選項列表中的已選擇項通過一定的方法按照默認的順序移動到列表的最前面,這樣的話,默認選中項的順序就跟我們想要的順序一致。但是有個不好的地方就是會破壞選項列表原有的排序。
方法2:后來我翻牆在網上提了問題,然后網友給我提供了一個不錯的解決方法。
解決方法如下:(通過一個重新渲染選項序列的方法,對選中項按照我們想要的順序重新排列,這樣的話問題2中的問題也被這個方法解決了,問題3中的設置默認值時需要多設置默認選中項的順序)
/**
* select2_renderselections
* @param {jQuery Select2 object}
* @return {null}
*/
function select2_renderSelections($select2){
const order = $select2.data('preserved-order') || [];
const $container = $select2.next('.select2-container');
const $tags = $container.find('li.select2-selection__choice');
const $input = $tags.last().next();
// apply tag order
order.forEach(val=>{
let $el = $tags.filter(function(i,tag){
return $(tag).data('data').id === val;
});
$input.before( $el );
});
console.log('$select2.val():', $select2.val());
console.log(
"$select2.data('preserved-order'):",
$select2.data('preserved-order')
);
}
/**
* selectionHandler
* @param {Select2 Event Object}
* @return {null}
*/
function selectionHandler(e){
const $select2 = $(this);
const val = e.params.data.id;
const order = $select2.data('preserved-order') || [];
switch (e.type){
case 'select2:select':
order[ order.length ] = val;
break;
case 'select2:unselect':
let found_index = order.indexOf(val);
if (found_index >= 0 )
order.splice(found_index,1);
break;
}
$select2.data('preserved-order', order); // store it for later
select2_renderSelections($select2);
}
$select2.on('select2:select select2:unselect', selectionHandler);
// Demo for default
runDemo($select2);
function runDemo($select2){
var selected = ['c','a','d'];
$select2
.val( selected )
.data('preserved-order',selected) // must manually preserve the order
.trigger('change');
// Render in preserved order
select2_renderSelections($select2);
console.log('$select2.val():', $select2.val());
console.log(
"$select2.data('preserved-order'):",
$select2.data('preserved-order')
);
}
參考:https://github.com/select2/select2/issues/3106