背景
本人前端是一塌糊涂,这几年没怎么搞过前端,因为有需要,所以用了bootrstrap。
现在有个需求,我有一个table,需要在每一行的最后一个单元格内增加两个按扭,并绑定点击事件,点击这个按扭的事件,获得这一行的数据,然后进行相关业务处理,如下:
在最后1列增加扣费和充值2个按钮。
这个列表用的是DataTable。
在网上搜了几篇解决方案,千篇一律,我也就没试可行不,不符合我的期望。
翻了官方文档和源码,被我发现了2个属性,想到了2个方案解决了。
我的html代码:
<table id="vip-user-list" class="table table-bordered table-hover ">
</table>
服务器数据:
{
"data": [
{
"name": "Tiger Nixon",
"id": "12345678",
"tel": "187xxxxxxxx",
"money": "$320,800",
"updateTime": "2019/04/25"
},
{
"name": "Hello World",
"id": "87654321",
"tel": "187xxxxxxxx",
"money": "$58,800",
"updateTime": "2019/10/25"
}
]
}
方案一
使用ajax.dataSrc属性,处理原始数据,以字符串拼接的方式,拼接上这两个按钮标签,并绑定点击事件。
关于这个属性描述如下,文档地址:http://datatables.club/reference/option/ajax.dataSrc.html
ajaxOption
ajax不定时一讲
选项基本继承了 jQuery.ajax 所有的选项,但是Datatables额外提供了dataSrc
属性来改变从服务器返回的数据给Datatables,或者是操作数据从一种形式转换成另一种形式(比如xml、json、yaml等)。 这么做是因为ajaxOption
ajax不定时一讲
的success
选项不能被改变-Datatables内部自己加载数据完成时使用。
代码如下:
<script>
$(function () {
$('#vip-user-list').DataTable({
'paging': true,
'lengthChange': false,
'searching': true,
'ordering': false,
'info': true,
'autoWidth': false,
"ajax": {
"url": './data/vip_user_list.json',
"dataSrc": function (json) {
for (var i = 0, ien = json.data.length; i < ien; i++) {
var data = json.data[i];
var rechargeBtn = "recharge" + data.id;
var deductionBtn = "deduction" + data.id;
data.op = "<button type=\"button\" class=\"btn btn-sm btn-primary\"" + " id=" + rechargeBtn + " >扣费</button> <button type=\"button\" class=\"btn btn-sm btn-yellow\"" + " id=" + deductionBtn + " >充值</button>";
var recharge = function(){
console.log(this);
}
$('#vip-user-list').on('click', 'tbody #'+rechargeBtn, recharge.bind(data))
var deduction = function() {
console.log(this);
}
$('#vip-user-list').on('click', 'tbody #'+deductionBtn, deduction.bind(data))
}
return json.data;
}
},
"columns": [
{
"title": "姓名",
"data": "name"
},
{
"title": "卡号",
"data": "id"
},
{
"title": "手机号",
"data": "tel"
},
{
"title": "余额",
"data": "money"
},
{
"title": "更新日期",
"data": "updateTime"
},
{
"title": "操作",
"data": "op"
}
]
})
})
</script>
方案二
使用columns的render属性,这个是我在翻源码的时候看到的:
/**
* This property is the rendering partner to `data` and it is suggested that
* when you want to manipulate data for display (including filtering,
* sorting etc) without altering the underlying data for the table, use this
* property. `render` can be considered to be the the read only companion to
* `data` which is read / write (then as such more complex). Like `data`
* this option can be given in a number of different ways to effect its
* behaviour:
*
* * `integer` - treated as an array index for the data source. This is the
* default that DataTables uses (incrementally increased for each column).
* * `string` - read an object property from the data source. There are
* three 'special' options that can be used in the string to alter how
* DataTables reads the data from the source object:
* * `.` - Dotted Javascript notation. Just as you use a `.` in
* Javascript to read from nested objects, so to can the options
* specified in `data`. For example: `browser.version` or
* `browser.name`. If your object parameter name contains a period, use
* `\\` to escape it - i.e. `first\\.name`.
* * `[]` - Array notation. DataTables can automatically combine data
* from and array source, joining the data with the characters provided
* between the two brackets. For example: `name[, ]` would provide a
* comma-space separated list from the source array. If no characters
* are provided between the brackets, the original array source is
* returned.
* * `()` - Function notation. Adding `()` to the end of a parameter will
* execute a function of the name given. For example: `browser()` for a
* simple function on the data source, `browser.version()` for a
* function in a nested property or even `browser().version` to get an
* object property if the function called returns an object.
* * `object` - use different data for the different data types requested by
* DataTables ('filter', 'display', 'type' or 'sort'). The property names
* of the object is the data type the property refers to and the value can
* defined using an integer, string or function using the same rules as
* `render` normally does. Note that an `_` option _must_ be specified.
* This is the default value to use if you haven't specified a value for
* the data type requested by DataTables.
* * `function` - the function given will be executed whenever DataTables
* needs to set or get the data for a cell in the column. The function
* takes three parameters:
* * Parameters:
* * {array|object} The data source for the row (based on `data`)
* * {string} The type call data requested - this will be 'filter',
* 'display', 'type' or 'sort'.
* * {array|object} The full data source for the row (not based on
* `data`)
* * Return:
* * The return value from the function is what will be used for the
* data requested.
*
* @type string|int|function|object|null
* @default null Use the data source value.
*
* @name DataTable.defaults.column.render
* @dtopt Columns
*
* @example
* // Create a comma separated list from an array of objects
* $(document).ready( function() {
* $('#example').dataTable( {
* "ajaxSource": "sources/deep.txt",
* "columns": [
* { "data": "engine" },
* { "data": "browser" },
* {
* "data": "platform",
* "render": "[, ].name"
* }
* ]
* } );
* } );
*
* @example
* // Execute a function to obtain data
* $(document).ready( function() {
* $('#example').dataTable( {
* "columnDefs": [ {
* "targets": [ 0 ],
* "data": null, // Use the full data source object for the renderer's source
* "render": "browserName()"
* } ]
* } );
* } );
*
* @example
* // As an object, extracting different data for the different types
* // This would be used with a data source such as:
* // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
* // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
* // (which has both forms) is used for filtering for if a user inputs either format, while
* // the formatted phone number is the one that is shown in the table.
* $(document).ready( function() {
* $('#example').dataTable( {
* "columnDefs": [ {
* "targets": [ 0 ],
* "data": null, // Use the full data source object for the renderer's source
* "render": {
* "_": "phone",
* "filter": "phone_filter",
* "display": "phone_display"
* }
* } ]
* } );
* } );
*
* @example
* // Use as a function to create a link from the data source
* $(document).ready( function() {
* $('#example').dataTable( {
* "columnDefs": [ {
* "targets": [ 0 ],
* "data": "download_link",
* "render": function ( data, type, full ) {
* return '<a href="'+data+'">Download</a>';
* }
* } ]
* } );
* } );
*/
"mRender": null,
我的代码如下,也是字符串拼接标签,但是要注意这个方法会被调用多次,需要先取消绑定的事件,避免重复绑定:
<script>
$(function () {
$('#vip-user-list').DataTable({
'paging': true,
'lengthChange': false,
'searching': true,
'ordering': false,
'info': true,
'autoWidth': false,
"ajax": {
"url": './data/vip_user_list.json'
},
"columns": [
{
"title": "姓名",
"data": "name"
},
{
"title": "卡号",
"data": "id"
},
{
"title": "手机号",
"data": "tel"
},
{
"title": "余额",
"data": "money"
},
{
"title": "更新日期",
"data": "updateTime"
},
{
"title": "操作",
"data": "op",
"render": function (data, type, full) {
var rechargeBtn = "recharge" + full.id;
var deductionBtn = "deduction" + full.id;
$('#vip-user-list ').undelegate('tbody #'+rechargeBtn, 'click');
$('#vip-user-list').on('click', 'tbody #'+rechargeBtn, function () {
console.log(full);
})
$('#vip-user-list ').undelegate('tbody #'+deductionBtn, 'click');
$('#vip-user-list').on('click', 'tbody #'+deductionBtn, function () {
console.log(full);
})
return "<button type=\"button\" class=\"btn btn-sm btn-primary\"" + " id=" + rechargeBtn + " >扣费</button> <button type=\"button\" class=\"btn btn-sm btn-yellow\"" + " id=" + deductionBtn + " >充值</button>";
}
}
]
})
})
</script>
点击这几个按钮,执行结果如下,输出这一行的值: