使用复选框控制 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 属性附加到&lt;input&gt; 节点: 在发生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 列的可见性的主要内容,如果未能解决你的问题,请参考以下文章

在 jquery datatables.net 中呈现布尔数据列的最佳方法

ExtJs 确定表单加载的可见性

datatablesearch无效

jQuery DataTables 检查标题单击时的复选框

当前页面的 JQuery DataTables 列复选框

在复选框和文本框上使用相同的功能切换可见性[重复]