点击DataTables表头内的select/input元素时如何避免触发列排序
解决方案
问题原因
点击表头内的下拉框时,点击事件会向上冒泡到<th>表头单元格,触发DataTables默认绑定的表头点击排序逻辑,就会出现误触发排序的问题。
修复方案(改动最小,兼容select2渲染后的元素)
只需要额外阻止表头内交互元素的点击事件冒泡即可,有两种实现方式:
方式1:创建select时直接绑定阻止事件
在你原有创建select的代码中,新增click事件监听,阻止事件向上冒泡:
var select = $('<br><select id="' + title + '" class="select2" ></select>') .appendTo($(column.header())) // 新增这一段阻止点击事件冒泡 .on('click', function(e) { e.stopPropagation(); }) // 原有change事件保留 .on('change', function () { // 原有逻辑不变 })
另外因为select2会把原生<select>隐藏,渲染成自定义的.select2-container元素,你还需要给这类渲染后的元素也加事件阻止,可以在initComplete的末尾统一添加:
// 加在initComplete的最后即可 $(this.api().table().header()).on('click', '.select2-container, input', function(e) { e.stopPropagation(); });
方式2:全局统一拦截表头交互元素的冒泡事件
不用改原有select创建逻辑,直接在DataTables初始化时统一加事件委托,适配所有表头内的输入、下拉元素:
// 直接加在DataTables的初始化配置中即可,和initComplete平级 preDrawCallback: function() { $(this.api().table().header()).off('click', 'select, input, .select2-container').on('click', 'select, input, .select2-container', function(e) { e.stopPropagation(); }); }
修改后完整的initComplete代码
initComplete: function () { count = 0; this.api().columns().every(function () { var title = this.header(); //replace spaces with dashes title = $(title).html().replace(/[\W]/g, '-'); var column = this; var select = $('<br><select id="' + title + '" class="select2" ></select>') .appendTo($(column.header())) // 新增阻止冒泡 .on('click', function(e) { e.stopPropagation(); }) .on('change', function () { //Get the "text" property from each selected data //regex escape the value and store in array var data = $.map($(this).select2('data'), function (value, key) { return value.text ? '^' + $.fn.dataTable.util.escapeRegex(value.text) + '$' : null; }); //if no data selected use "" if (data.length === 0) { data = [""]; } //join array into string with regex or (|) var val = data.join('|'); //search for the option(s) selected column .search(val ? val : '', true, false) .draw(); }); //unique, tipo group by //sorte deixa em ordem abcd column.data().unique().sort().each(function (d, j) { select.append('<option value="' + d + '">' + d + '</option>'); }); //use column title as selector and placeholder $('#' + title).select2({ multiple: true, closeOnSelect: false, placeholder: "Select a " + title }); //initially clear select otherwise first option is selected $('.select2').val(null).trigger('change'); }); // 新增阻止select2渲染元素的冒泡 $(this.api().table().header()).on('click', '.select2-container, input', function(e) { e.stopPropagation(); }); }
内容的提问来源于stack exchange,提问作者Bijan
相关产品推荐
相关产品推荐

