0

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 e.g. 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","--",""]]}

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, your solution works (or at least the page you linked to got me to the solution): $('#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] ); });
0

@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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.