如何在Select2多选字段中设置无法移除的固定选项
Select2 多选模式配置不可移除固定选项实现方案
以下方案适配主流的Select2 4.x版本,无需修改框架源码,兼容性稳定。
核心实现思路
通过自定义属性标记固定选项,拦截Select2暴露的移除事件阻止固定项被删除,同时配合样式优化给用户明确的不可操作提示,分两种常见场景适配:
场景1:JS动态加载选项数据的初始化方式
- 给需要固定的选项添加自定义
locked: true标记,同时配置选中项渲染模板,给固定项加专属标识用于样式控制
$('#demo-select').select2({ multiple: true, placeholder: '请选择选项', data: [ { id: 'fixed_01', text: '系统默认必选项', locked: true }, // 固定项加锁定标记 { id: 'normal_01', text: '普通选项A' }, { id: 'normal_02', text: '普通选项B' }, { id: 'normal_03', text: '普通选项C' } ], templateSelection: function(data, container) { if (data.locked) { container.attr('data-locked', 'true'); } return data.text; } });
- 绑定移除拦截事件,检测到锁定项时直接阻止默认移除行为
$('#demo-select').on('select2:unselecting', function (e) { const currentItem = e.params.args.data; if (currentItem.locked) { e.preventDefault(); } });
- 添加样式隐藏固定项的移除按钮,做视觉区分
/* 隐藏固定项的删除叉号 */ .select2-selection__choice[data-locked="true"] .select2-selection__choice__remove { display: none !important; } /* 可选:给固定项加差异化背景,提示用户不可操作 */ .select2-selection__choice[data-locked="true"] { background-color: #f1f5f9 !important; cursor: default; padding-right: 6px !important; }
场景2:原生select标签预渲染选项的初始化方式
如果选项是直接写在HTML的select标签内,直接给固定的option加data-locked="true"属性即可:
<select id="demo-select" multiple style="width: 300px"> <!-- 固定项加data-locked属性,默认选中 --> <option value="fixed_01" selected data-locked="true">系统默认必选项</option> <option value="normal_01">普通选项A</option> <option value="normal_02">普通选项B</option> <option value="normal_03">普通选项C</option> </select>
对应的拦截事件逻辑稍作调整,读取原生option的属性判断即可:
$('#demo-select').select2(); $('#demo-select').on('select2:unselecting', function (e) { const targetValue = e.params.args.data.id; const isLocked = $(this).find(`option[value="${targetValue}"]`).data('locked'); if (isLocked) { e.preventDefault(); } });
样式部分和场景1完全通用。
注意事项
- 如果业务里有批量清空、批量赋值的逻辑,记得手动保留固定项的值,避免批量操作把固定项冲掉。比如清空选择时不能直接置空,要保留锁定项的value:
// 错误写法:会把固定项一起清掉 // $('#demo-select').val(null).trigger('change'); // 正确写法:仅清空非锁定项 const lockedValues = $('#demo-select') .find('option[data-locked="true"]') .map(function() { return this.value }) .get(); $('#demo-select').val(lockedValues).trigger('change');
不要直接修改Select2源码实现该需求,用官方暴露的事件钩子做适配,后续框架升级时不会出现兼容问题。
内容的提问来源于stack exchange,提问作者Stelios - Ervis Priftis
相关产品推荐
相关产品推荐

