3

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 !

7 Answers 7

3

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
    }
});
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

2

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

3 Comments

I need the identifier for other purposes that I didn't paste here. Thanks for the answer though.
Fair point. It can easily be added back in, but you don't require it for checking/unchecking the boxes of a related tr
Sure, no excuses on that :) I'll use your solution to check/uncheck ! Thank you.
1

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

Comments

0

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

Comments

0
$('#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);
    }
});

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.