BMN
BMN

Reputation: 8508

jQuery click event triggered twice when clicking on Checkbox

I'm playing around with DataTables and I have a table like this :

<table id='dt'>
    <thead><!-- Some Header --></thead>
    <tbody>
        <tr data-lineid=1>
            <td><input type='checkbox' class='checked_entry' id='checked_1'></td>
            <td>Column 1</td>
            <td>Column 2</td>
        </tr>
        <!-- Rest of the table -->
    </tbody>
</table>

What I am trying to do is to be able to click everywhere in the row, and it will select the checkbox of this row :

$('#dt tbody').on('click', 'tr', function() {
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
});

This is working fine, except that now, when I'm clicking on the checkbox itself, it seems it triggers the checkbox click event plus the event bound on the tr.

I've tried something like :

$('#dt tbody').on('click', 'tr :not(input)', function() { ... });

But this seems not to work.

Could anyone give me a tip on this please ?

Thanks !

Upvotes: 3

Views: 2388

Answers (7)

Innovation
Innovation

Reputation: 1534

As you already have table row click event.It will also be fired when checkbox click and here you are changing the state of checkbox in your click event.So it is better to preventDefault() event of checkbox.A better solution would be:

$('#dt tbody').on('click', 'tr', function(e) {
e.preventDefault();
var id = $(this).data('lineid');
if ($('#checked_'+id).prop('checked')) {
    $('#checked_'+id).prop('checked', false);
    // ... and some other stuff
} else {
    $('#checked_'+id).prop('checked', true);
    // ... and some other stuff
}
});

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337580

Firstly, remove the iterative identifier you don't need it; at least not solely for identifying the row containing a checkbox.

<table id='dt'>
    <thead><!-- Some Header --></thead>
    <tbody>
        <tr>
            <td><input type='checkbox' class='checked_entry' /></td>
            <td>Column 1</td>
            <td>Column 2</td>
        </tr>
    </tbody>
</table>

Then in jQuery you can attach your event to the tr using traversal to find the related checkbox, and also use stopPropagation() on the click of the checkbox to stop the event being caught twice.

$('#dt tbody').on('click', 'tr', function() {
    var $checkbox = $(this).find(':checkbox');
    $checkbox.prop('checked', !$checkbox.prop('checked'));
});
$('#dt input:checkbox').click(function(e) {
    e.stopPropagation();
});

Example fiddle

Upvotes: 2

Amin Jafari
Amin Jafari

Reputation: 7207

$('#dt tbody').on('click', 'tr', function(e) {
    e.preventDefault();
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
});

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388316

It is because the click event on the checkbox itself is propagated. As a solution you can check whether the actual click target was the checkbox in that case don't do anything in the click handler.

$('#dt tbody').on('click', 'tr', function (e) {
    if (!$(e.target).is('input:checkbox')) {
        $(this).find('input:checkbox').prop('checked', function (i, checked) {
            return !checked;
        })
    }
});

Demo: Fiddle

Upvotes: 2

T.S.
T.S.

Reputation: 1242

You could make sure the click event doesn't propagate to the row element when you click the checkbox like this:

$('#dt tbody input').on('click', function(e) { e.stopPropagation(); });

Upvotes: 1

sudhansu63
sudhansu63

Reputation: 6180

You can try this.

$('#dt tbody').on('click', 'tr', function(event) {
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
    } else {
        $('#checked_'+id).prop('checked', true);
    }
      event.preventDefault();
});

Upvotes: 0

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67207

Try to exit the tr click event whenever the user is making a click on checkbox,

$('#dt tbody').on('click', 'tr', function(e) {
    if($(e.target).is('input')) { return; }
    var id = $(this).data('lineid');
    if ($('#checked_'+id).prop('checked')) {
        $('#checked_'+id).prop('checked', false);
        // ... and some other stuff
    } else {
        $('#checked_'+id).prop('checked', true);
        // ... and some other stuff
    }
});

Upvotes: 3

Related Questions