[英]How to detect button click event inside DataTable child row?
I have the standard DataTable code which populates the datatable and shows child rows on row clicks.我有标准的 DataTable 代码,它填充数据表并在行点击时显示子行。 Inside the child row (using the format function) i have added a button and i want to do something when it's clicked but each time i click the button(data table contains child row inside a new tr->td) the event of td click which is used to open/close child rows is fired and i get "Uncaught TypeError: Cannot read property '0' of undefined"
for the d[]
array in format function.在子行内(使用格式功能),我添加了一个按钮,我想在单击它时执行某些操作,但是每次单击该按钮(数据表包含新 tr->td 内的子行)时,td 单击事件用于打开/关闭子行的函数被触发,并且我在格式函数中为d[]
数组收到"Uncaught TypeError: Cannot read property '0' of undefined"
。
This is the code for the child rows open/close:这是子行打开/关闭的代码:
$('tbody').on('click', 'td', function() {
var tr = $(this).closest('tr');
id = $(this).closest('table').attr('id');
table = $('#' + id).DataTable();
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data(), id)).show();
tr.addClass('shown');
}
});
function format(d, id) {
// `d` is the original data object for the row
if(sessionStorage['name']!=undefined)
return '<img src="images/photo.jpg" id="photo" />' + '<p>Session created by:' + d[0] + '</p>' + '<p>Start Date:' + d.start_date + '</p>' + '<p>Extra info:' + d[3] + '</p>' + "<button class='btn btn-default' id='joinbutton' role='button'>Join Session</button>";
else
return '<div>' + '<img src="images/photo.jpg" id="photo" />' + '<p>Session created by:' + d[0] + '</p>' + '<p>Start Date:' + d.start_date + '</p>' + '<p>Extra info:' + d[3] + '</p>' + '</div>';
}
Is there a way to either prevent the td click
event from being fired for child rows or to detect the button click somehow?有没有办法防止为子行触发 td click
事件或以某种方式检测按钮单击? Thanks谢谢
I propose the snippet following my remark (see the comments, not those in the format function, they are required for me to make the snippet running):我在我的评论之后提出了代码段(请参阅注释,而不是格式函数中的注释,它们是我运行代码段所必需的):
function format(d, id) { // `d` is the original data object for the row //if(sessionStorage['name']!=undefined) return '<img src="http://icons.iconarchive.com/icons/treetog/junior/256/image-format-jpg-icon.png" id="photo" />' + '<p>Session created by:' + d[0] + '</p>' + '<p>Start Date:' + d.start_date + '</p>' + '<p>Extra info:' + d[3] + '</p>' + "<button class='btn btn-default' id='joinbutton' role='button'>Join Session</button>"; //else //return '<div>' + '<img src="images/photo.jpg" id="photo" />' + '<p>Session created by:' + d[0] + '</p>' + '<p>Start Date:' + d.start_date + '</p>' + '<p>Extra info:' + d[3] + '</p>' + '</div>'; } // to handle the joinbutton created dynamically you need: // avoid to use the same ID for more than one element $(document).on('click', 'button[role="button"]', function(e) { alert('This is the button'); }); $(function () { $('tbody').on('click', 'td', function(e) { // to avoid to receive the button click inside the td you need: if ($(e.target).is(':not(td)')) { alert('This is inside td'); return; } var tr = $(this).closest('tr'); id = $(this).closest('table').attr('id'); table = $('#' + id).DataTable(); var row = table.row(tr); if (row.child.isShown()) { // This row is already open - close it row.child.hide(); tr.removeClass('shown'); } else { // Open this row row.child(format(row.data(), id)).show(); tr.addClass('shown'); } }); });
table, th, td { border: 1px solid black; border-collapse: collapse; } th, td { padding: 10px; }
<link href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet"/> <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script> <link href="//cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css" rel="stylesheet"> <script src="//cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script> <table id="tblId"> <thead> <tr> <th>Month</th> <th>Savings</th> </tr> </thead> <tfoot> <tr> <td>Sum</td> <td>$180</td> </tr> </tfoot> <tbody> <tr> <td>January</td> <td>$100</td> </tr> <tr> <td>February</td> <td>$80</td> </tr> </tbody> </table>
SOLUTION解决方案
Add click handler to the button and return false
from the handler to prevent default action and stop the event from propagating to parent element.将单击处理程序添加到按钮并从处理程序返回false
以防止默认操作并阻止事件传播到父元素。 Alternatively you may call stopPropagation()
and preventDefault()
.或者,您可以调用stopPropagation()
和preventDefault()
。
$('#example tbody').on('click', 'button', function (e) {
// ... skipped ...
return false;
});
It would be better to remove id='joinbutton'
and use class name instead, for example btn-join
.最好删除id='joinbutton'
并改用类名,例如btn-join
。 Then you would be able to target specific button with the code below.然后您就可以使用以下代码定位特定按钮。
$('#example tbody').on('click', '.btn-join', function (e) {
// ... skipped ...
return false;
});
DEMO演示
See this jsFiddle for code and demonstration.有关代码和演示,请参阅此 jsFiddle 。
I resolve my problem with @gaemaf solution:我用@gaemaf 解决方案解决了我的问题:
// Handle click on checkbox
$("#example tbody").on("click", 'input[type="checkbox"]', function(e){
var $row = $(this).closest("tr");
if(this.checked){
$row.addClass("active");
} else {
$row.removeClass("active");
}
// Prevent click event from propagating to parent
e.stopPropagation();
});
// Handle click on table cells
$("#example tbody").on("click", "td", function(e){
// Begin Solution
if ($(e.target).is(':not(td)')) {
return;
}
// End solution
$(this).parent().find('input[type="checkbox"]').trigger("click");
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.