Ceriana
Ceriana

Reputation: 67

jQuery: Hide/Show table rows based on clicked button

I got two tables side by side on a page. The left table contains buttons with company names, and the right table should contain employees connected to specific companies.

When you load the page there shouldn't be any employees. If the user clicks on one of the buttons, the table rows with the employees connected to this company should show up. If I click on the same button again or another button, the employee rows should hide (with the new ones popping up).

The buttons have a class with the company id (1, 2, 3..), and the rows have a class with an id like trclass1, trclass2, .. .

I tried using this function:

    $(document).ready(function()
    {
        $(".clickbtn").click(function(event)
        {
            $('[id=trclass'+event.target.id+']').toggle();
        });
    });

clickbtn is the name of the button, trclass the class of the table rows.

<button id='1' class='clickbtn' />
<button id='2' class='clickbtn' />
.
.

<tr id='trclass1' hidden> ...
<tr id='trclass2' hidden> ...
.
.

It works sometimes. There seems no pattern if it works or doesnt work.

My problems are, except not knowing anything about jQuery, how to pass the argument properly to the function and making it work everytime. The jQuery code above was from another question which had quite the same problem, but was somehow different from mine. Last but not least, there isn't a constant number of how many companies or employees are there to show, the data is fetched from a database.

Upvotes: 0

Views: 3384

Answers (2)

Tyler Roper
Tyler Roper

Reputation: 21672

The importance here is understanding the difference between jQuery's $(this) and plain old javascript event.target.

Consider this example.

The big blue box is our button, and it includes all the red boxes inside it. Notice, as you hover your mouse over them: $(this) always refers to the element in which the event is tied to. Because our event is tied to the button click, $(this) always refers to the button.

event.target on the other hand is almost too-specific in many cases. As you hover over the red boxes, you'll notice that event.target refers to the exact element being hovered. By doing event.target.id, you'll be getting the divs' ID's instead of the button's.


For this reason, I really think your solution is quite simple: Use jQuery's $(this) instead of event.target.

$('.clickbtn').click(function() { 
    var btnID = $(this).attr("id");
    $("#trclass"+btnID).toggle();
});

If you want only the clicked button's row to be shown, then you can hide all of the others using .hide(). If you give your table an ID, you can select all the rows by doing $("#my-table-id tr"), however in your case you'll need to use a "starts with" selector [id^=trclass]. If this is the only table on the page, consider just using $("tr"), which selects every table row on the page.

$('.clickbtn').click(function() { 
    var btnID = $(this).attr("id");
    $("[id^=trclass]").not(this).hide();
    $("#trclass"+btnID).toggle();
});

Upvotes: 1

Obsidian Age
Obsidian Age

Reputation: 42304

The problem sounds to be due to the elements being dynamically created. In order to get around this, you need to attach the click handler to an element that is always present on the page, which in turn delegates the click event:

$(document).ready(function() {
  $(document).on("click", ".clickbtn", function(event) {
    $('[id=trclass'+event.target.id+']').toggle();
  });
});

In the above sample, the click handler is attached to document, which fires whenever .clickbtn is clicked. This should cause the clicks to work every time.

Hope this helps! :)

Upvotes: 0

Related Questions