【问题标题】:Control DataTables columns visibility with checkboxes使用复选框控制 DataTables 列的可见性
【发布时间】:2019-11-09 21:42:23
【问题描述】:

我正在使用 在我的刀片模板上动态呈现表格。我有一系列复选框,用户可以检查以显示/隐藏表格列。所有这些都很好。

这是我的模板的样子:

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。你试过吗?
  • 我还没有机会更新我的代码,但我绝对会尝试一下。它似乎比我所拥有的要少得多。非常感谢!

标签: datatables javascript php jquery laravel datatables


【解决方案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;
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-16
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-02
        • 2011-01-22
        相关资源
        最近更新 更多