jdphenix
jdphenix

Reputation: 15425

How to attach an event handler with eventData and a named function?

I have a page with elements that have the ID "rec-0", "rec-1", to "rec-n", and I'm trying to figure out how to attach an event to them. They are input elements that are children of td elements.

<td><input type="checkbox" id="rec-0" /></td>

I tried to attach an event handler to all of the elements with this:

$("td > input").change({ elem:this }, recipe_checkbox_clicked); 

but within the recipe_checkbox_clicked() function I get Uncaught TypeError: Object #<Object> has no method 'prop'. This is the recipe_checkbox_clicked function:

function recipe_checkbox_clicked(elem) { 
    if (elem.prop('checked')) $("#modify-recipe").show(); 
    else $("#modify-recipe").hide(); 
}

If I copy the function's code into an anonymous function, with a slight modification it works as expected. Here's the modified code:

$("td > input").change( function() { 
    if ($(this).prop('checked')) $("#modify-recipe").show(); 
    else $("#modify-recipe").hide(); 
}); 

I can leave as is, but I prefer to not use anonymous functions. Is there a way to accomplish what I'm trying without using them?


With Adil and Felix's help and suggestions, I've gotten the behavior I wanted with the following code!

function recipe_checkbox_clicked() { 
    if ($(this).prop('checked')) $("#modify-recipe").show(); 

    var any_checked = false; 
    $("td > input").each(function() { 
        if($(this).prop('checked')) {
            any_checked = true; 
            return false; 
        }
    }); 
    if (!any_checked) $("#modify-recipe").hide(); 
}

And the selector that attaches this function:

$("td > input").change(recipe_checkbox_clicked);

Thank you so much! I have burned hours trying to figure out how to do this.

Upvotes: 0

Views: 101

Answers (2)

Adil
Adil

Reputation: 148120

You can pass name of function in change instead of passing anonymous function, You can access the source of event from $(this) for jquery and this for javascript in the function.

change

$("td > input").change( function() { 
    if (elem.prop('checked')) $("#modify-recipe").show(); 
    else $("#modify-recipe").hide(); 
}); 

To

$("td > input").change(yourFunction); 

function yourFunction() { 
    elem = $(this);
    if (elem.prop('checked')) $("#modify-recipe").show(); 
    else $("#modify-recipe").hide(); 
}

To bind with ids like rec-0, rec-1, rec-2 you can use wild cards

 $("[id^=rec-").change(yourFunction);

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816442

Just use the same code in the named function:

function recipe_checkbox_clicked() { 
    if ($(this).prop('checked')) $("#modify-recipe").show(); 
    //  ^^^^^^^
    // or better: if (this.checked) ...
    else $("#modify-recipe").hide(); 
}

Two things that I believe are wrong with your code:

$("td > input").change({ elem:this }, recipe_checkbox_clicked);

Even if you would access elem correctly, I assume that this here does not actually refer to any element selected by $("td > input"), but to something else and thus $(elem).prop(...) would probably not work as expected.

function recipe_checkbox_clicked(elem) {

The first argument passed to an event handler is always the event object. If you want to access the event data, you have to do this via the event object:

function recipe_checkbox_clicked(event) {
  var elem = event.data.elem;
}

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

Upvotes: 3

Related Questions