4

I am trying to make the rows in my DataTable clickable. On click I want to navigate the user to another page.

When I execute the script and click on the rows the script always navigates me to ./test/data.php?id=1 which is the page I want to use for the first row. The same script is active in all the rows.

Does someone know why my script is pasting the link for the first row in all the rows and how I can fix this?

Here is my script:

    <script type="text/javascript">
     $( document ).ready(function() {
      $('#grid1').DataTable({
       "bprocessing": true,
       "serverSide": true,
            "ajax": {
                "url": "response2.php",
                "type": "POST",
                "error": function(){
                    $("#grid_processing").css("display","none");
                }
            },
            "columnDefs": [ 
                { "targets": 1, "render": function ( data, type, full, meta ) { return  '<b>'+data+'</b>'} },
                { "targets": 3, "render": function ( data, type, full, meta ) { return  '<i>'+data+'</i>'} },
                { "targets": 6, "render": function ( data, type, full, meta ) { return  '<a href="./test/data.php?id='+data+'"></a>'; } }               
            ]                       
      });   
     });
    </script>
    <script type="text/javascript">
    $(document).ready(function() {

        $('#grid1').click(function() {
            var href = $(this).find("a").attr("href");
            if(href) {
                window.location = href;
            }
        });

    });
    </script>

Edit 1:

response2.php:

<?php
    include_once("connection.php");

    $params = $columns = $totalRecords = $data = array();
    $params = $_REQUEST;
    $columns = array( 
        0 => 'name',
        1 => 'address',
        2 => 'number',
        3 => 'city',
        4 => 'country',
        5 => 'id'
    );

    $where = $sqlTot = $sqlRec = "";

    if( !empty($params['search']['value']) ) {   
        $where .=" WHERE ";
        $where .=" ( id LIKE '".$params['search']['value']."%' ";
        $where .=" OR name LIKE '".$params['search']['value']."%')";
    }

    if (!empty($where) ) {

   $where .= "AND user_id='1' ";
    } else {
     $where .= "WHERE user_id='1' ";
    }

    $sql = "SELECT name, address, number, city, country, id FROM customers ";
    $sqlTot .= $sql;
    $sqlRec .= $sql;
    if(isset($where) && $where != '') {

        $sqlTot .= $where;
        $sqlRec .= $where;
    }

    $sqlRec .=  " ORDER BY id DESC LIMIT ".$params['start']." ,".$params['length']." ";

    $queryTot = mysqli_query($conn, $sqlTot) or die("database error:". mysqli_error($conn));


    $totalRecords = mysqli_num_rows($queryTot);

    $queryRecords = mysqli_query($conn, $sqlRec) or die("error to fetch employees data");

    while( $row = mysqli_fetch_row($queryRecords) ) { 
        $data[] = $row;
    }   

    $json_data = array(
            "draw"            => intval( $params['draw'] ),   
            "recordsTotal"    => intval( $totalRecords ),  
            "recordsFiltered" => intval($totalRecords),
            "data"            => $data
            );

    echo json_encode($json_data);
?>
4
  • 1
    your $(this).find("a") will always find the first anchor tag it comes across which is the first row. Hence it is redirecting to ./test/data.php?id=1 every time. Commented Feb 10, 2019 at 17:41
  • Hmm, Do you know how I can fix this? Commented Feb 10, 2019 at 20:55
  • Please check the example shown here. Commented Feb 11, 2019 at 6:59
  • I know the example. When I replace my javascript with the javascript in the example I get the same result. I get always You clicked on 1's row. I tried to use <thead> an <tr> in my script but the result is the same. I still get You clicked on 1's row. Commented Feb 11, 2019 at 22:27

2 Answers 2

1
+50

You need to initialize the click listener to each individual row.

You can specify the column index where the URL or URL parameter is set, in this example the index is 6 as in your original example.

Edited:

Replace your click listener with this. This script will detect which row you clicked and use the correct row for the link:

<script type="text/javascript">
  $(document).ready(function() {

    var table = $('#grid1').DataTable();    
    $('#grid1').on( "click", "td", function (e) {
      var rowIdx = table.row( this ).index();
      var sData = table.cells({ row: rowIdx, column: 6 }).data()[0];
      if (sData && sData.length) {
        location.href = './test/data.php?id=' + sData;
      }
    });

  });
</script>

A good idea is to add some CSS styles to the row as in @ygorbunkov's answer, so that the row will appear as a link.

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

4 Comments

True, the listener does not need to be reinitialized after the ajax call, edited accordingly. As for the other points: I think having the listener on a td element instead of a tr is good practice, threfore the row has to be investigated with the cell co-ordinates. Your comment about the data model doesn't apply here, since the asked specified ajax, if i understood your comment correctly.
My approach does work weather the link is rendered or not. It uses the original value rather than the rendered value.
I see, and understand your point. I however don't think it's relevant regarding the original question since the asker specified the data model to have only visible cells.
I guess .data()[6]. But that wouldn't work with your data model, as data() wouldn't return an array :)
0

Your jquery function takes all <a> doms on table. Because your $(this) returns <table> not a row of the your <a>.So you need to reduce your click event's perspective to row level or to <a> level as which I will share an example with you.

Give a class to <a> for example class="redirector" when you are creating it on that line.

{ "targets": 6, "render": function ( data, type, full, meta ) { return  '<a class="redirector" href="./test/data.php?id='+data+'"></a>'; } }   

And change your js like;

$('.redirector').click(function() {
    var href = $(this).attr("href");
    if(href) {
        window.location = href;
    }
});

Or try just this;

  $('#grid1>a').click(function() {
      var href = $(this).attr("href");
      if(href) {
          window.location = href;
      }
  });

2 Comments

Wouldn't this make only the link clickable, not the whole row? Both $('.redirector') and $('#grid1>a') only point to the link itself, not the whole row?
In the original question: I am trying to make the rows in my DataTable clickable

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.