skip to Main Content

I have a dynamic table, with variable # of rows. I’m trying to get related information from the backend depending on the specific row that is clicked.

The table’s html (this is from a django template – basically adds one per object in the db that is returned):

<table class="table table-bordered" id="dataTable">
    <thead>
        <tr>
            <th>pk</th>
            <th>ent_1</th>
            <th>ent_2</th>
            <th>ent_3</th>
        </tr>
    </thead>
    <tbody>
    {% for o in object_list %}

            <tr>
                <td><a class="test" href="{% url 'myapp:ajaxview' %}">{{ o.pk }}</a></td>
                <td><a class="test" href="{% url 'myapp:ajaxview' %}">{{ o.ent_1 }}</a></td>
                <td><a class="test" href="{% url 'myapp:ajaxview' %}">{{ o.ent_2 }}</a></td>
                <td><a class="test" href="{% url 'myapp:ajaxview' %}">{{ o.ent_3 }}</a></td>
            </tr>

    {% endfor %}
    </tbody>
</table>

<div id="details">
   <!-- details info from the back is appended to the DOM here. -->
</div>

The jquery code that catches the event & appends html into the div#details:

$(function() {
    $('.test').click(function (event) {
        event.preventDefault();
        console.log("table row clicked")  // sanity check
        update_details();
    });

    function update_details() {
        console.log("update details is called")
        $.ajax({
            // must include the app endpoint at the beginning, others it appends to current url, e.. ajaxlist/get_ajax_details/
            url: "/myapp/get_ajax_details/",
            type: "GET",
            data: {},

            // success
            success: function (rendered_template) {
                $('#details').empty();
                $('#details').prepend(rendered_template)
                console.log(rendered_template);
                console.log("success")
            },

            // error
            error: function (xhr, errmsg, err) {
                $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: " + errmsg +
                    " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
                console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
            }

        });
    };

});

I’ve stepped it into firebug, however I do not understand how can I get the full detail of which row has been clicked. Ultimately, I need the content of the first column of that row that was clicked (the "pk" column) so I can send that to the backed, so that it returns the rendered_template with the relevent information, which I can them append to my div#details.

OTHER DETAILS:

I’m using classes for selectors. I know I could instead generate an integer ID (e.g. number each rows). But that seems wasteful and I’m sure it’s not needed for my purpose. This is a quick prototype, ultimately I’ll look into jquery selectors so that I only need to add a class to the table itself (and then listen for clicks on any table>tbody>tr>a within tables that needs to be listened to).

thanks

2

Answers


  1. Modified your code a bit and attached the click event to the ‘td’ instead of ‘a’ tag to source the index of it easily.

    $(document).ready(function(){
      $('#dataTable td').click(function (event) {
         var col = $(this).index(),
         firstColVal = $(this).parent().children('td:first-child').text(),
         row = $(this).parent().index();
         
         console.log("Row index: " + row + ", Col index: " + col + ",  Col Value: " + firstColVal);
    
         //update_details(); <-- pass required value as parameter
      });
    });
    table {
        border-collapse: collapse;
    }
    th, td { border: 1px solid #000; padding: 10px; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <table class="table table-bordered" id="dataTable">
        <thead>
            <tr>
                <th>pk</th>
                <th>ent_1</th>
                <th>ent_2</th>
                <th>ent_3</th>
            </tr>
        </thead>
        <tbody>
          <tr>
              <td><a class="test" href="#">PK Row 0</a></td>
              <td><a class="test" href="#">Ent_1</a></td>
              <td><a class="test" href="#">Ent_2</a></td>
              <td><a class="test" href="#">Ent_3</a></td>
          </tr>
          <tr>
              <td><a class="test" href="#">PK Row 1</a></td>
              <td><a class="test" href="#">Ent_1</a></td>
              <td><a class="test" href="#">Ent_2</a></td>
              <td><a class="test" href="#">Ent_3</a></td>
          </tr>
          <tr>
              <td><a class="test" href="#">PK Row 2</a></td>
              <td><a class="test" href="#">Ent_1</a></td>
              <td><a class="test" href="#">Ent_2</a></td>
              <td><a class="test" href="#">Ent_3</a></td>
          </tr>
        </tbody>
    </table>
    Login or Signup to reply.
  2. Your $(".text").click handler already knows which <a> was clicked, it provides that as this:

     $('.test').click(function (event) {
         var link = this;
    

    you can then pass this to your update_details function:

         update_details(link);   // or update_details(this);
    
    function update_details(link) {
    };
    

    you can then use DOM navigation to find the row and then the first column. It’s up to you where you do this (in the click handler or the update_details, or split between the two), I would recommend only passing the information once you have extracted:

    $('.test').click(function (event) {
        var link = this;
        var row = $(link).closest("tr");
        var cell = row.children("td").first();
        // or var cell = row.find(">td").eq(0);
    
    

    then you can get the text (excluding the html for the <a>) as

        cell.text();
    

    Put together and shortened gives:

    $('.test').click(function () {
        var pk = $(this).closest("tr").find(">td").text();
        updated_details(pk);
        return false;
    }
    
    function update_details(pk) {
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search