简体   繁体   中英

Creating a dynamic link in a DataTables table using jQuery

I'm trying to create a JSON-delivered table using DataTables, and have that table do "things" when certain links in the table are clicked on. The links aren't always there, so they need to be dynamically generated. I'm just getting started with jQuery, and I'm having trouble figuring out what I'd term a callback which is "attached" to the correct element.

Here's an example HTML page, with a dynamically generated "up" link (rather naively in plain old JS). The idea is that the clicking of that link will eg produce an alert which shows which row you clicked on, and the row above. The end goal is to be able to move the rows up or down using the links/buttons.

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
                <title>Show a re-orderable list</title>
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css" />
                <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
        </head>
    <script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-1.11.3.min.js"> </script>
    <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"> </script>
    <script type="text/javascript" class="init">
        $(document).ready(function() {
            var table = $('#example').DataTable( {
                "ajax": "foo_data.txt",
                       "columnDefs": [
                        {
                            "render": function ( data, type, row ) {
                                var extra_text = "";
                                if( data === "Queued" ) {
                                    extra_text = ' <a href="#" class="up_queue">Up</a> Down ';
                                }
                                return data +' ('+ row[3]+')' + extra_text;
                            },
                            "targets": 1
                        },
                        { "visible": false,  "targets": [ 3 ] }
                        ]
            } );
            $(".up_queue").on('click', function() {
                var mydata = table.row( this ).data();
                var uprow  = table.row( this ).index() - 1;
                var updata = table.row( uprow) .data();
                alert( 'You clicked on '+mydata[0]+ ' ' +updata[0] +' row' );
                });
        } );
    </script>
<body>

<div>
<table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Job ID</th>
                <th>Status</th>
                <th>Name</th>
                <th>Elapsed Time</th>
                <th>Options</th>
            </tr>
        </thead>
    </table>
</div>

</body>
</html>

Essentially the problem is that the "Up" link does nothing... I'd like to know which row was clicked, and the index of the row immediately above the clickee. Any ideas?

Here's the associated data foo_data.txt which could be served via AJAX:

{
"data":
[["101","Finished","Static","3 days",""],
 ["102","Queued","Moveable1","--",""],
 ["103","Queued","Moveable2","--",""],
 ["104","Queued","Moveable3","--",""],
 ["105","Queued","Moveable4","--",""],
 ["106","Queued","Moveable5","--",""],
 ["107","Queued","Moveable6","--",""]]}

The reason is that link doesn't work is because it doesn't exist at the time you attach event handler. You need to use delegated event handler instead.

$('#example').on('click', ".up_queue", function() {
   var mydata = table.row( this ).data();
   var uprow  = table.row( this ).index() - 1;
   var updata = table.row( uprow) .data();
   alert( 'You clicked on '+mydata[0]+ ' ' +updata[0] +' row' );
});

See jQuery DataTables – Why click event handler does not work for more information.

On the other hand, consider using RowReorder extension that offers much better functionality with row reordering.

@Gyrocode.com posted a link which helped - here's the working code:

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
                <title>Show a re-orderable list</title>
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css" />
                <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
        </head>
    <script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-1.11.3.min.js"> </script>
    <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"> </script>
    <script type="text/javascript" class="init">
        $(document).ready(function() {
            var table = $('#example').DataTable( {
                "ajax": "foo_data.txt",
         'columnDefs': [
         {
            'targets': 4,
            'searchable': false,
            'orderable': false,
            "render": function ( data, type, row ) {
                var extra_text = "";
                if( row[1] === "Queued" ) {
                    extra_text = ' <button type="button" class="button up-button">Up</button>'
                }
                return extra_text;
            },
         } ]
            } );
            $('#example').on('click', ".up-button", function() {
                var tr        = $(this.closest('tr'));
                var table     = $(this.closest('table'));
                var tr_above   = table.DataTable().row(tr).index() - 1;
                var data       = table.DataTable().row(tr).data();
                var data_above = table.DataTable().row(tr_above).data();

                alert( 'You clicked on ' + data[0] + ' swap with ' + data_above[0] );
                });
        } );

    </script>
<body>

<div>
<table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Job ID</th>
                <th>Status</th>
                <th>Name</th>
                <th>Elapsed Time</th>
                <th>Options</th>
            </tr>
        </thead>
    </table>
</div>

</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM