-2

I have markup something like this.

<div id="sequenced" class="pane overflow-auto">
    <table id="sequenced-railcars" class="table table">
        <tbody>
            <tr>
                <td class="railcar-sequence">1</td>
                <td class="railcar-number">ABCD123456</td>
                <td class="remove-sequence">
                    <img src="~/images/delete.png" title="Unsequence" role="button" />
                </td>
            </tr>
        </tbody>
    </table>
</div>

And I have the following handlers.

// Handle table row clicks
$('#sequenced-railcars').on('click', 'tr', function () {
    var $rows = $('#sequenced-railcars tr');
    $rows.removeClass('target-row');
    $(this).addClass('target-row');
});

// Handle image clicks
$('#sequenced').on('click', '.remove-sequence img', function () {
    var $row = $(this).closest('tr');
    var railcar = { id: $row.data('id'), number: $row.find('.railcar-number').text() };
    if (railcar.id != undefined) {
        unsequenceRailcar(railcar);
        $row.remove();
        resetTarget();
    }
});

This works okay. However, in the case where the image click handler is called, the row click handler is called first.

Is there any way to say that when my image is clicked, that the handler for the row click is not triggered? In the case where the image is clicked, the logic for handling row clicks does not apply.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 1
    The row handler gets called first because the element you have bound it to (#sequenced-railcars) is a child of the element that the image click handler is bound to (#sequenced) - so in the bubbling phase the events for #sequenced-railcars are handled first. I suspect you could reverse those two selectors for desired results, with appropriate use of stopPropagation. – James Mar 28 '23 at 18:01

3 Answers3

1

Take a look at the concept of "Event Bubbling" - What is event bubbling and capturing?

Here is a handy method that should help you stop the bubbling - https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

0

How would the user click #sequenced without clicking #sequenced-railcars?

The latter gets the event and it bubbles up, which is why you see it called first.

  • Clicking `#sequenced` is not an issue. It's the row that handler is responding to. And I don't want it to bubble up in this case. – Jonathan Wood Mar 28 '23 at 17:49
  • The first handler is on `#sequenced-railcars` and the second handler is on `#sequenced` which is lower in the hierarchy so the first handler gets the event first. Bubbling up is not an issue, you're trying to prevent "bubbling down" which is not possible. Change the selectors so that the second handler is attached to a child element of the first handler. – Guy Incognito Mar 28 '23 at 17:59
0

You can simply skip calling the row click event on last td using td:not(:last-child)

$(document).ready(function() {
  // Handle table row clicks
  $('#sequenced-railcars').on('click', 'td:not(:last-child)', function() {
    console.log("row test");
    var $rows = $('#sequenced-railcars tr');
    $rows.removeClass('target-row');
    $(this).parents("tr").addClass('target-row');

  });

  // Handle image clicks
  $('#sequenced').on('click', '.remove-sequence img', function() {

    console.log("image test");
    var $row = $(this).closest('tr');
    var railcar = {
      id: $row.data('id'),
      number: $row.find('.railcar-number').text()
    };
    if (railcar.id != undefined) {
      //unsequenceRailcar(railcar);
      $row.remove();
      resetTarget();
    }
  });
});
img{
  width:25px;
}

td{
  border: 1px solid tomato;
}

.target-row{
  background-color:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div id="sequenced" class="pane overflow-auto">
    <table id="sequenced-railcars" class="table table">
        <tbody>
            <tr id="1">
                <td class="railcar-sequence">1</td>
                <td class="railcar-number">ABCD123456</td>
                <td class="remove-sequence">
                    <img src="https://cdn-icons-png.flaticon.com/512/3405/3405244.png" title="Unsequence" role="button" />
                </td>
            </tr>
            <tr id="2">
                <td class="railcar-sequence">2</td>
                <td class="railcar-number">test</td>
                <td class="remove-sequence">
                    <img src="https://cdn-icons-png.flaticon.com/512/3405/3405244.png" title="Unsequence" role="button" />
                </td>
            </tr>
        </tbody>
    </table>
</div>

Related: How to select not first tr and not last td

Nitin Sawant
  • 7,278
  • 9
  • 52
  • 98