tags:

views:

53

answers:

3

Could somebody tell me why this code:

$('#places-view > tbody').find('td').click(function(evt) {
    var td = $(this),
        input = td.find('input');
        console.log('click');
        console.log(input.attr('disabled'), 'disabled');
        if (! input.attr('disabled')) {
            input.trigger('click');
            console.log('inner click');
        }
})

throwing too much recursion error...

Regards

+1  A: 
Pointy
I am using firebug console, so in my case all works as expected.
Marek
+2  A: 

To prevent event bubbling, place event.stopPropagation() in the handler for your input element's click event.

$('#places-view input').click(function(event) {

      // This will prevent the click event from bubbling up and firing
      //    the click event on your <td>
    event.stopPropagation();

      // run the rest of your click code
});

http://api.jquery.com/event.stopPropagation/


EDIT: As @Pointy noted, it may be your intention to have the same handler handle both events, or at least have the td handler still fire when you click the input.

If that's the case, you'll just need to check to see if the td handler was fired by a click on the input, and if so, prevent the input.trigger("click") from running:

$('#places-view > tbody').find('td').click(function(evt) {
    var td = $(this),
        input = td.find('input');
        console.log('click');
        console.log(input.attr('disabled'), 'disabled');
        if (! input.attr('disabled')) {
                // If the target of the click was not the input,
                //   then trigger the click on the input
            if( input.not( evt.target ).length ) {
                input.trigger('click');
                console.log('inner click');
            }
        }
});

Another way to do the test would be:

if(input[0] != evt.target) {...

Both of these approaches assume that there's just one input. If that's not the case, then you'll need to give the input an identifier to allow the test to be more specific.

patrick dw
This is true, but I have to wonder whether that'd be a good idea. If he indeed wants to handle "click" at the `<td>` level, it may be bad to cancel bubbling at the `<input>` because that'll shunt off the clicks to the `<td>`. Of course it depends on what else is in the table cell.
Pointy
@Pointy - You're right. My assumption is that the click for the `td` is occurring elsewhere in the `td`, and as such, the handler would be separate. If that's not the case, then OP will probably need to test the `evt.target` in the `td` handler to see if the click was on the `input`, and if so, bypass triggering the `click()` on the `input`.
patrick dw
Good answer, +1
Mark
Thanks a lot folks. Everything is working now.
Marek
A: 

Now I am facing next issue.

I want to change (switch) td background color on click and change select status of checkbox inside. Everything is working fine when I click on a td, but when I click directly on input background color switch doesn't work.

My code:

var occupiedColor = '#f90',
    freeColor = '#333',
    property = 'background-color';
$('#places-view > tbody').find('td').click(function(evt) {
    var td = $(this),
        input = td.find('input');
    if (input.length > 0) {
        input.trigger('click');
        if (input.attr('type') == 'radio') {
            $('#places-view > tbody').find('td').each(function() {
                var currTd = $(this);
                if (currTd.data('selected') == true) {
                    currTd.css(property, freeColor);
                    currTd.data('selected', false);
                }
            })
        }
        td.data('selected', ! td.data('selected'));
        if (td.data('selected') == false) {
            td.css(property, freeColor);
        } else {
            td.css(property, occupiedColor);
        }
    }
}).data('selected', false);

$('#places-view input').click(function(event) {
    event.stopPropagation();
});

Could somebody explain me how to merge those two events?

Marek