最近项目上需要使用多选控件,于是查阅了下资料并对比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");
});
参考:
问题3:设置默认选中项
对于用户已选中并保存的选项,下次再次进入页面时,需要展示默认选中项。
方法如下:(这个方法存在显示顺序问题,如例子中设置的是["1707","1706"],但显示的是"1706","1707",因为是按照选项在列表中的顺序展示)
$("#sel_menu2").val(["1707","1706"]).trigger('change');//trigger('change')
问题4:默认选中项以及新选择项的排序问题
在问题2和问题3中都提到了选中项的展示顺序问题,一开始我查了很久的资料,只找到问题2中对新选择项的排序解决方法。
方法1:于是对于默认选中项的展示顺序,我想了一个变通的方法。既然展示的顺序是跟选项列表的顺序一致,那么我就把选项列表中的已选择项通过一定的方法按照默认的顺序移动到列表的最前面,这样的话,默认选中项的顺序就跟我们想要的顺序一致。但是有个不好的地方就是会破坏选项列表原有的排序。
方法2:后来我FQ在网上提了问题,然后网友给我提供了一个不错的解决方法。
解决方法如下:(通过一个重新渲染选项序列的方法,对选中项按照我们想要的顺序重新排列,这样的话问题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')
);
}
参考: