使用复选框控制 DataTables 列的可见性
Posted
技术标签:
【中文标题】使用复选框控制 DataTables 列的可见性【英文标题】:Control DataTables columns visibility with checkboxes 【发布时间】:2019-11-09 21:42:23 【问题描述】:我正在使用datatables 在我的刀片模板上动态呈现表格。我有一系列复选框,用户可以检查以显示/隐藏表格列。所有这些都很好。
这是我的模板的样子:
template.blade.php
<table id="dataTables-report" class="table table-striped table-bordered table-hover">
</table>
这是我用来渲染表格的内容:
scripts.js
$('#dataTables-report').DataTable(
...
columnDefs: [
targets: 0,
title: 'Name',
searchable: true,
data: function (row, type, val, meta)
// return row.data;
,
@if($report->order_date)
targets: 1,
title: 'Order Date',
searchable: false,
data: function (row, type, val, meta)
// return row.data;
,
@endif
@if($report->order_number)
targets: 2, // could be 1 if order date is not selected
title: 'Order Number',
searchable: false,
data: function (row, type, val, meta)
// return row.data;
,
@endif
...
);
“订单日期”是用户可以选择在表格上显示的复选框。如果选中,则显示该列。否则它不会。
有可能首先选择不同的列,它可能是targets: 1
。现在,如果用户选中另一个框,targets
需要动态设置为下一个数字。在这种情况下:targets: 2
。
每个复选框都作为它自己的列存储在数据库中,所以我认为我不能执行任何类型的循环(因此有一堆 if 语句)。否则,我认为something like this 会起作用。
有没有办法在我的刀片模板中动态生成targets
号码?
【问题讨论】:
要更新表格时是否随时刷新页面?如果您使用 DataTables 的 ajax 部分,我觉得这会更容易管理(并且会删除那些 if 语句)。然后,您可以将当前列数保留为 JS 变量,以便在添加/删除列时进行修改。 好问题 - 如果我选择/检查“订购日期”,我必须单击“保存”按钮。该按钮执行完整的POST
,因此页面刷新。
除了使用 JS 和 Ajax 之外,您还必须将目标与其他请求数据一起发布到控制器。也许一个隐藏字段会在选中/取消选中一个复选框时更新,该字段存储一个 json 字符串,其中包含检查/取消选中的顺序。不过,这对我来说似乎有点不对劲。我会尝试使用 datatable 的内置 ajax 来节省麻烦。
@Damon :我提出了我的解决方案below。你试过吗?
我还没有机会更新我的代码,但我绝对会尝试一下。它似乎比我所拥有的要少得多。非常感谢!
【参考方案1】:
如果您正在寻求由复选框控制的真正动态的列可见性(据我了解您的最终目标),则可以完全通过几行 jQuery 在用户端完成。
为了做到这一点,你可以简单地
将每列的源对象属性作为value
属性附加到<input>
节点:
在发生change
事件时,通过与单击的复选框值对应的对象属性找到来源(使用column().dataSrc()
方法)的列,并调整该列的可见性(相应地使用.column().visible()
方法:
$('#checkboxWrapper').on('change', '[type="checkbox"]', event =>
let colindex = null;
dataTable.columns().every(function()
if(this.dataSrc() == $(event.target).val()) colindex = this.index();
);
dataTable.column(colindex).visible($(event.target).prop('checked')).draw();
);
您可以在下面找到该概念的完整现场演示:
//sample source data
const dataSrc = [
id: 1, item: 'apple', cat: 'fruit',
id: 2, item: 'carrot', cat: 'vegie',
id: 3, item: 'banana', cat: 'fruit'
];
//extract all unique object keys from data source array
const checkboxes = [...new Set(dataSrc
.map(item => Object.keys(item))
.flat())];
//translate those into <input> nodes html
const checkboxesHtml = checkboxes.reduce((inputs, prop) => inputs += `<input type="checkbox" value="$prop" checked>$prop</input>`,'');
$('#checkboxWrapper').append(checkboxesHtml);
//initialize datatables
const dataTable = $('#example').DataTable(
data: dataSrc,
dom: 't',
columns: checkboxes.map(prop => (title: prop, data: prop))
);
//control columns visibility with checkboxes
$('#checkboxWrapper').on('change', '[type="checkbox"]', event =>
//grab column().index() that corresponds to checkbox value
let colindex = null;
dataTable.columns().every(function()
if(this.dataSrc() == $(event.target).val()) colindex = this.index();
);
//toggle selected column visibility
dataTable.column(colindex).visible($(event.target).prop('checked')).draw();
);
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<div id="checkboxWrapper"></div>
<table id="example"></table>
</body>
</html>
【讨论】:
【参考方案2】:感谢您的建议,这是我在进一步研究您的建议时提出的“快速”解决方案。
在我的刀片模板中,我创建了一个可以在我的 php 中访问的全局变量。
@section('scripts')
<script>
$(function ()
...
let columnTarget = 0;
...
$('#dataTables-report').DataTable(
...
columnDefs: [
targets: columnTarget,
title: 'Name',
searchable: true,
data: function (row, type, val, meta)
// return row.data;
,
@if($report->order_date)
targets: ++columnTarget,
title: 'Order Date',
searchable: false,
data: function (row, type, val, meta)
// return row.data;
,
@endif
@if($report->order_number)
targets: ++columnTarget,
title: 'Order Number',
searchable: false,
data: function (row, type, val, meta)
// return row.data;
,
@endif
...
</script>
@endsection
这似乎运作良好;正确(动态)分配 targets
值。
【讨论】:
【参考方案3】:->addColumn('action', function ($floor)
$action=
@Can("floor-edit")"
<a class='btn btn-info btn-sm'
href=".route("floor.edit",Crypt::encrypt($floor->id))."><i class='fa fa-edit'></i>
</a>
<button type='button' name='delete' id=".Crypt::encrypt($floor->id)." class='delete btn btn-danger btn-sm'><i class='fa fa-trash'></i></button>
";
return $action;
)
【讨论】:
以上是关于使用复选框控制 DataTables 列的可见性的主要内容,如果未能解决你的问题,请参考以下文章