Bootstrap 使用 ajax 调用捕获事件在数据表插件中切换

Bootstrap switch inside datatables plugin with ajax call catch event

我正在使用 datatables plugin and I have a problem with bootstrap switch。 这是我的 javascript 代码,我在其中使用从 ajax 调用检索到的值创建了一个开关:

$(document).ready(function() {
    if ( ! $.fn.DataTable.isDataTable( '#usersTable' ) ) {
        userTable = $('#usersTable').DataTable({
            responsive: true,
            //fix problem with responsive table
            "autoWidth": false,
            "ajax": "table",
            "columns": [
                        { "data": "username" },
                        { data: "enabled", render: function ( data, type, row ) {
                            if (data) {
                                return '<input data="username" type="checkbox" name="my-checkbox" checked>';
                            }
                            else {
                                return '<input data="username" type="checkbox" name="my-checkbox">';
                            }
                        }   
                        },
                        { "data": "role.role"},
                        { "data": "clientVersion.name" },
                        {
                            data: null,
                            className: "center",
                            defaultContent: '<button type="button" class="btn btn-danger" id="deleteLicense" data-toggle="modal" th:attr="data-href=${license.idClientLicense}" data-target="#deleteLicenseModal">Delete</button>'
                        }
                        ],
                        "fnDrawCallback": function() {
                            //Initialize checkbos for enable/disable user
                            $("[name='my-checkbox']").bootstrapSwitch({size: "small", onColor:"success", offColor:"danger"});
                        }
        });
    }
    else {
        userTable.ajax.url("table").load();
    }

    $('input[name="my-checkbox"]').on('switchChange.bootstrapSwitch', function(event, state) {
        //CSRF attribute for spring security
        var token = $("meta[name='_csrf']").attr("content");
        var header = $("meta[name='_csrf_header']").attr("content");
        $.ajax({
            type : "POST",
            url : "status"+(this).attr("data"),
            data : form.serialize(),
            beforeSend:function(xhr) {
                xhr.setRequestHeader(header, token);
            },  
//          all right with rest call
            success : function(data) {  
//              No exception occurred
                if (data.status==true){ 
//                  Also the field are right(for e.g. form value)
                    if(data.success==true){
//                      il risultato sta in data.result
//                      window.location.reload(true);
                        //reset select 2 choise because it can set with old user who no longer exist 
//                      reload only the tag with id carsTable, so only the table

                    }
                    else{
//                      code if there are some error into form for example
                    }
                } else {
//                  code exception
                    notifyMessage(data.result, 'error');
                }
            },
//          error during rest call
            error : function(data) {
                window.location.href = "/ATS/500";
            }
        });
    }); 
});

这是 HTML 代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
    xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Administration users</title>
<!-- Tell the browser to be responsive to screen width -->
<meta
    content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    name="viewport">
<!-- Spring csrf  -->
<meta name="_csrf" th:content="${_csrf.token}" />
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}" />
<!-- Bootstrap Core CSS -->
<link th:href="@{/static/assets/bootstrap/css/bootstrap.css}"
    rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet"
    th:href="@{/static/assets/component/font-awesome-4.4.0/css/font-awesome.min.css}">
<!-- Ionicons -->
<link rel="stylesheet"
    href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet"
    th:href="@{/static/assets/plugins/datatables/dataTables.bootstrap.css}">
<link rel="stylesheet"
    th:href="@{/static/assets/plugins/datatables/extensions/Responsive/css/responsive.bootstrap.min.css}">
<!-- Theme style -->
<link rel="stylesheet"
    th:href="@{/static/assets/dist/css/AdminLTE.min.css}">
<!-- AdminLTE Skins. Choose a skin from the css/skins
         folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet"
    th:href="@{/static/assets/dist/css/skins/_all-skins.min.css}">
<!-- Select2 -->
<link rel="stylesheet"
    th:href="@{/static/assets/plugins/select2/select2.min.css}">
<!-- Bootstrap switch -->
<link rel="stylesheet"
    th:href="@{/static/assets/plugins/bootstrap-switch/css/bootstrap-switch.min.css}">
<!-- jQuery 2.1.4 -->
<script th:src="@{/static/assets/plugins/jQuery/jQuery-2.1.4.min.js}"
    type="text/javascript"></script>
<!-- Bootstrap 3.3.5 -->
<script th:src="@{/static/assets/bootstrap/js/bootstrap.min.js}"
    type="text/javascript"></script>
<!-- DataTables -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/datatables/jquery.dataTables.min.js}"></script>
<script type="text/javascript"
    th:src="@{/static/assets/plugins/datatables/dataTables.bootstrap.min.js}"></script>
<script type="text/javascript"
    th:src="@{/static/assets/plugins/datatables/extensions/Responsive/js/dataTables.responsive.min.js}"></script>
<script type="text/javascript"
    th:src="@{/static/assets/plugins/datatables/extensions/Responsive/js/responsive.bootstrap.min.js}"></script>
<!-- page script -->
<!-- Slimscroll -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/slimScroll/jquery.slimscroll.min.js}"></script>
<!-- FastClick -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/fastclick/fastclick.min.js}"></script>
<!-- Bootstrap-growl -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/notify/jquery.bootstrap-growl.js}"></script>
<!-- AdminLTE App -->
<script type="text/javascript"
    th:src="@{/static/assets/dist/js/app.min.js}"></script>
<!-- AdminLTE for demo purposes -->
<script type="text/javascript"
    th:src="@{/static/assets/dist/js/demo.js}"></script>
<!-- Select2 -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/select2/select2.full.min.js}"></script>
<!-- Bootstrap switch -->
<script type="text/javascript"
    th:src="@{/static/assets/plugins/bootstrap-switch/js/bootstrap-switch.min.js}"></script>
<script type="text/javascript" th:src="@{/static/assets/js/user.js}"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
        <!-- Header nd menu fragment -->
        <div th:replace="../fragments/dashboard-header :: dashboard-header"></div>
        <!-- Content Wrapper. Contains page content -->
        <div class="content-wrapper">
            <!-- Content Header (Page header) -->
            <section class="content-header">
                <h1>Administration</h1>
                <ol class="breadcrumb">
                    <li><a th:href="@{/}"><i class="fa fa-dashboard"></i> Home
                    </a></li>
                    <li class="active">User</li>
                </ol>
            </section>
            <!-- Main content -->
            <section class="content">
                <div class="row">
                    <div class="col-xs-12">
                        <div class="box">
                            <div class="box-header">
                                <h3 class="box-title">Users</h3>
                            </div>
                            <!-- /.box-header -->
                            <div class="box-body">
                                <!-- -Users table -->
                                <table id="usersTable"
                                    class="table table-bordered table-striped">
                                    <thead>
                                        <tr>
                                            <th>Username</th>
                                            <th>Enable</th>
                                            <th>Role</th>
                                            <th>Version</th>
                                            <th>Delete</th>
                                        </tr>
                                    </thead>
                                </table>
                                <!-- Create two equals button because when I am on desktop I show the text add fleet otherwise the + and the tooltip. 
                                This is need because otherwise the text goes out the button -->
                                <button id="addUserButton" type="button"
                                    class="btn btn-primary visible-lg col-lg-1 col-lg-offset-11"
                                    data-toggle="modal" data-target="#addUserModal">Add
                                    user</button>
                                <button id="addlicenseButton" type="button"
                                    class="btn btn-primary hidden-lg col-xs-1 col-xs-offset-11"
                                    data-toggle="modal" data-target="#addUserModal">
                                    <span class="glyphicon glyphicon-plus" data-toggle="tooltip"
                                        title="Add user"></span>
                                </button>
                            </div>
                        </div>
                    </div>
                    <!-- /.col -->
                </div>
                <!-- /.row -->
            </section>
            <!-- /.content -->
        </div>
    </div>
</body>
</html>

我阅读了几个问题和答案,但我认为我的问题与 "fnDrawCallback": function() 有关,因为我尝试了所有解决方案并且 None 有效。可能是开关设置不正确? 这是 table

原因

在初始化时 DOM 中不存在第一个以外的页面,这就是为什么您的处理程序永远不会被调用的原因。

解决方案

您需要通过在 on() 调用中提供选择器作为第二个参数来使用事件委托,请参见下面的示例:

$('#usersTable').on('switchChange.bootstrapSwitch', 'input[name="my-checkbox"]', function(event, state) {
   // ... skipped ...
});

来自jQueryon()方法文档:

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.

请参阅 jQuery on() 方法文档和 jQuery 数据表中的“直接和委托事件”——为什么点击事件处理程序不起作用获取更多信息。

注意事项

自定义控件和响应式扩展需要特殊处理。如果包含自定义控件的列变为隐藏或可见,则应重新初始化。有关详细信息,请参阅 jQuery DataTables – Responsive extension and custom controls