logicOnAbstractions
logicOnAbstractions

Reputation: 2580

Get details of which row clicked in a jquery.click() event

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

Upvotes: 1

Views: 683

Answers (2)

fdomn-m
fdomn-m

Reputation: 28611

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) {
};

Upvotes: 1

Zam Abdul Vahid
Zam Abdul Vahid

Reputation: 2721

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>

Upvotes: 1

Related Questions