使用复选框控制DataTables列的可见性

使用复选框控制DataTables列的可见性,datatables,javascript,php,jquery,laravel,Datatables,Javascript,Php,Jquery,Laravel,我正在使用动态渲染刀片模板上的表。我有一系列复选框,用户可以选中这些复选框来显示/隐藏表列。所有这些都很有效 这是我的模板的外观: template.blade.php <table id="dataTables-report" class="table table-striped table-bordered table-hover"> </table> “订单日期”是用户可以选择在表上显示的复选框。如果选中,则显示该列。否则它就不会。 可以先选择不同的列,并且可以是

我正在使用动态渲染刀片模板上的表。我有一系列复选框,用户可以选中这些复选框来显示/隐藏表列。所有这些都很有效

这是我的模板的外观:

template.blade.php

<table id="dataTables-report" class="table table-striped table-bordered table-hover">
</table>
“订单日期”是用户可以选择在表上显示的复选框。如果选中,则显示该列。否则它就不会。 可以先选择不同的列,并且可以是
目标:1
。现在,如果用户选中另一个框,
目标
需要动态设置为下一个数字。在本例中:
目标:2

每个复选框都作为自己的列存储在数据库中,因此我认为我不能执行任何类型的循环(因此会有一堆if语句)。否则的话,我想会有用的


是否有一种方法可以在我的刀片模板中动态生成
目标
编号?

感谢您的建议,以下是我提出的“快速”解决方案,同时我将进一步研究您的建议

在我的blade模板中,我创建了一个全局变量,可以在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
@节(“脚本”)
$(函数(){
...
让columnTarget=0;
...
$(“#数据表报告”)。数据表({
...
columnDefs:[
{
目标:目标,,
标题:“姓名”,
可搜索:正确,
数据:函数(行、类型、值、元){
//返回row.data;
}
},
@如果($report->order\u date)
{
目标:++columnTarget,
标题:“订单日期”,
可搜索:false,
数据:函数(行、类型、值、元){
//返回row.data;
}
},
@恩迪夫
@如果($报告->订单号)
{
目标:++columnTarget,
标题:“订单号”,
可搜索:false,
数据:函数(行、类型、值、元){
//返回row.data;
}
},
@恩迪夫
...
@端部

这似乎很有效;正确地(动态地)分配
目标值。

如果您正在寻求由复选框控制的真正动态列可见性(我理解您的最终目标),则完全可以通过几行jQuery在用户端完成

为了做到这一点,你可以

  • 将每列的源对象属性作为
    属性附加到
    节点:
  • 在发生
    change
    事件时,找到由与单击的复选框值对应的对象属性来源的列(使用方法),并调整该列的可见性(相应地使用方法:
完成该概念的现场演示,您可以在下面找到:

//示例源数据
常数dataSrc=[
{id:1,项目:'苹果',猫:'水果'},
{id:2,项目:'胡萝卜',猫:'素食'},
{id:3,项目:'香蕉',猫:'水果'}
];
//从数据源数组中提取所有唯一的对象键
常量复选框=[…新集合(dataSrc
.map(项=>Object.keys(项))
.flat())];
//将这些节点转换为HTML
const checkboxesHtml=checkboxes.reduce((inputs,prop)=>inputs+=`${prop}`,'');
$('#checkboxWrapper').append(checkboxesHtml);
//初始化数据表
const dataTable=$(“#示例”).dataTable({
数据:dataSrc,
dom:‘t’,
列:checkbox.map(prop=>({title:prop,data:prop}))
});
//使用复选框控制列的可见性
$('#checkboxWrapper')。在('change','[type=“checkbox”]”上,事件=>{
//抓取与复选框值对应的列().index()
设colindex=null;
dataTable.columns().every(函数()){
如果(this.dataSrc()=$(event.target.val())colindex=this.index();
});
//切换选定列的可见性
dataTable.column(colindex).visible($(event.target).prop('checked')).draw();
});

->addColumn('action',function($floor){
$action=
@可以(“地板编辑”){
"};
返回$action;
})

您想随时更新表吗?我觉得如果您使用DataTables的ajax部分,这将更易于管理(并删除那些if语句)。然后您可以将当前列计数作为JS变量保留,以便在添加/删除列时进行修改。问得好-如果我选择/检查“订单日期”我必须单击“保存”"按钮。该按钮执行完整的
POST
,因此页面会刷新。除了使用JS和Ajax,您还必须将目标与其他请求数据一起发布到控制器。可能是一个隐藏字段,在选中/取消选中复选框时会更新该字段,该字段存储了json字符串,该字符串的顺序与选中/取消选中的内容相同。看起来Damon:我已经提出了我的解决方案。你试过了吗?我还没有机会更新我的代码,但我绝对要尝试一下。它看起来比我现在的版本“黑客性”要小得多。非常感谢!
@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
$('#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();
});
->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;
})