DataTables与Laravel集成问题:JSON列悬停显示异常
问题与需求
我正在使用DataTables 1.13.5和Laravel 10.0,创建了包含ID、Brand、First Name等列的数据表。MySQL表中有一个JSON类型的all列,存储着zip、phone等键值对数据,我已经对该列数据做了解析。我的需求是:表格初始只显示一条记录,鼠标悬停时显示all列,但目前的实现没达到预期效果。
表结构
| 字段名 | 类型 | 是否为空 | 键类型 | 默认值 | 额外属性 |
|---|---|---|---|---|---|
| id | bigint(20) unsigned | 否 | PRI | NULL | auto_increment |
| brand | varchar(255) | 否 | NULL | ||
| first_name | varchar(255) | 否 | NULL | ||
| all | json | 是 | NULL | ||
| created_at | timestamp | 是 | NULL |
表数据
| id | brand | first_name | all | created_at |
|---|---|---|---|---|
| 1 | Test | test | [{"zip": "xyz", "phone": "123"}] | 2023-07-20 10:05:58 |
| 2 | Test | test | [{"zip": "abc", "phone": "456"}] | 2023-07-20 10:09:10 |
当前脚本代码
var columnDefs = [ { title: "ID", targets: 0, render: function (data) { return (data['id']); } }, { title: "Brand", targets: 1, render: function (data) { return (data['brand']); } }, { title: "Form", targets: 2, render: function (data) { return (data['form_name'];); // 语法错误:多余的分号 } }, { title: "First Name", targets: 3, render: function (data) { return (data['first_name']); } }, { title: "All", targets: 4, className: 'all', render: function (data) { var details = JSON.parse(data['data']); // 错误:应该取data['all'],且Laravel返回的可能已解析为数组 var result = ""; $.each(details, function (index, value) { $.each(value, function (v, k) { let underscore = v.replace('_', ' '); underscore = underscore.toLowerCase().replace(/\b[a-z]/g, function (letter) { return letter.toUpperCase(); }); result = result + underscore + ": " + k + '<br>'; }); }); return result; } // 语法错误:缺少闭合的}, { title: "Created", targets: 5, render: function (data) { return (data['created_at']); } }, ];
解决方案
1. 修复脚本语法错误
- 移除
Form列render函数中多余的分号:return data['form_name']; - 为
All列的配置对象添加闭合的}, - 修正JSON解析逻辑:Laravel返回的
all列数据如果是已解析的数组,无需再用JSON.parse,直接取data['all']即可,修改后:
render: function (data) { var details = data['all']; // 直接使用后端传递的数组 var result = ""; $.each(details, function (index, value) { $.each(value, function (v, k) { let underscore = v.replace('_', ' '); underscore = underscore.toLowerCase().replace(/\b[a-z]/g, function (letter) { return letter.toUpperCase(); }); result += `${underscore}: ${k}<br>`; }); }); return result; }
2. 实现初始仅显示一条记录
在DataTables初始化配置中添加pageLength: 1,指定每页显示1条记录。
3. 实现鼠标悬停显示all列
- 初始状态隐藏
all列,在初始化配置的columns数组中设置对应列的visible: false - 监听表格行的
mouseenter和mouseleave事件,动态显示/隐藏all列
完整初始化代码示例
$(document).ready(function() { var table = $('#your-table-id').DataTable({ pageLength: 1, // 初始仅显示1条记录 ajax: { url: '/your-laravel-api-endpoint', // 替换为你的Laravel接口地址 dataSrc: '' }, columnDefs: [ { title: "ID", targets: 0, render: function (data) { return data['id']; } }, { title: "Brand", targets: 1, render: function (data) { return data['brand']; } }, { title: "Form", targets: 2, render: function (data) { return data['form_name']; // 修复语法错误 } }, { title: "First Name", targets: 3, render: function (data) { return data['first_name']; } }, { title: "All", targets: 4, className: 'all', visible: false, // 初始隐藏该列 render: function (data) { var details = data['all']; var result = ""; $.each(details, function (index, value) { $.each(value, function (v, k) { let underscore = v.replace('_', ' '); underscore = underscore.toLowerCase().replace(/\b[a-z]/g, function (letter) { return letter.toUpperCase(); }); result += `${underscore}: ${k}<br>`; }); }); return result; } }, { title: "Created", targets: 5, render: function (data) { return data['created_at']; } } ] }); // 绑定鼠标悬停事件 $('#your-table-id tbody').on('mouseenter', 'tr', function() { table.column(4).visible(true); // 显示all列 }); $('#your-table-id tbody').on('mouseleave', 'tr', function() { table.column(4).visible(false); // 隐藏all列 }); });
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

