You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel服务端DataTables实现事件动态列方案问询

实现Laravel DataTables动态列(基于事件表单模板)

场景说明

每个事件对应独立的表单模板,用户提交内容以JSON格式存储在submissions表的content字段中,需在对应事件页面用Laravel DataTables展示匹配模板的动态列,同一事件列结构保持一致。


服务端实现(Laravel)

先获取当前事件的表单字段列表,再为每个字段动态添加DataTables列,解析content中的JSON值:

public function datatable(Request $request, $id)
{
    if($request->ajax()){
        // 获取当前事件关联的表单模板字段
        $event = Event::whereHas('forms', function($q) use($id){
            $q->where('code', $id);
        })->firstOrFail();
        $formFields = $event->forms; // 表单字段集合,需包含code(对应JSON的name)和title

        $models = Submission::whereHas('event.forms', function($q) use($id){
            $q->where('code', $id);
        });

        $dataTable = DataTables::of($models)
            ->addColumn('action', function($model){
                return 'button action'; // 保留原有操作按钮逻辑
            })
            ->addIndexColumn()
            ->escapeColumns([]);

        // 循环添加动态表单列
        foreach($formFields as $field){
            $fieldCode = $field->code;
            $dataTable->addColumn($fieldCode, function($model) use($fieldCode){
                // 解析JSON格式的content,匹配对应字段值
                $content = json_decode($model->content, true);
                $fieldValue = collect($content)->where('name', $fieldCode)->first()['value'] ?? '-';
                return $fieldValue;
            });
        }

        return $dataTable->rawColumns(['action'])
            ->make(true);
    }
}

前端实现(jQuery DataTables)

动态生成columns配置,匹配服务端返回的字段,同时和页面表头对应:

1. 页面传递表单字段到JS

在Blade模板中把表单字段的code集合传给JS:

<script>
    const formFields = @json($template->forms->pluck('code'));
    const datatableUrl = "{{ route('your-datatable-route', ['id' => $id]) }}"; // 替换为实际路由
</script>

2. 动态构建DataTables列配置

修改原JS代码,插入动态表单列:

var datas_datatable = $('#datas_datatable').DataTable({
    "lengthMenu": [
        [10, 25, 50, 100, 200, -1],
        [10, 25, 50, 100, 200, "All"]
    ],
    dom: 'Bfrtip',
    buttons: [{
            extend: 'colvis',
            text: 'Column',
        },
        'pageLength',
        {
            extend: 'excel',
            text: 'Excel',
            exportOptions: {
                columns: ':visible th:not(:last-child)'
            }
        },
        "{{ auth()->user()->isAbleTo('events-create') }}" == 1 ? {
            text: 'Tambah',
            action: function ( e, dt, node, config ) {
                add("{{ route('getform_events') }}");
            }
        } : {}
    ],
    responsive: true,
    processing: true,
    serverSide: true,
    autoWidth: false,
    ajax: datatableUrl,
    columns: (function(){
        // 基础列:序号 + 动态表单列 + 操作列
        let cols = [
            {
                data: 'DT_RowIndex',
                orderable: false,
                searchable: false
            }
        ];

        // 插入动态表单列
        formFields.forEach(fieldCode => {
            cols.push({
                data: fieldCode,
                name: fieldCode,
                orderable: true,
                searchable: true
            });
        });

        // 添加操作列
        cols.push({
            data: 'action',
            name: 'action',
            orderable: false,
            searchable: false,
            className: "action-center"
        });

        return cols;
    })(),
    columnDefs: [
        {   
            "targets": [],
            "visible": false,
            "searchable": true
        }
    ],
    order: [
        [0, "asc"]
    ],
});

HTML表头配合

原有Blade表头代码已正确循环生成表单字段表头,保持不变:

<div class="card-body">
    <div class="table-responsive">
        <table id="datas_datatable" class="table table-bordered table-striped">
            <thead>
                <tr>
                    <th>No</th>
                    @foreach ($template->forms as $item)
                        <th>{{ $item->title }}</th>
                    @endforeach
                    <th>Aksi</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
    <!-- /.table-responsive -->
</div>

关键注意点

  • 确保表单模板的code字段与submissions.content中JSON对象的name值完全匹配,才能正确解析对应值。
  • 若需优化动态列的排序/搜索性能,可在服务端使用Laravel的JSON查询能力(如whereJsonContains),或预先解析content字段。

内容的提问来源于stack exchange,提问作者faradie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:01:11