views:

27

answers:

4

Hey guys, I have a little button functionality that is not erring, but also not working. The addItem gets called fine, and switches the class from "add-button" to "in-cart-button", but the $("a.in-cart-button").click(... doesn't seem to be firing. When I click the "in-cart-button", instead it triggers the addItem function again... Any ideas?

function addItem(t_id) {
    $("#" + t_id).addClass("in-cart-button").removeClass("add-button");
}

function removeItem(t_id) {
    $("#" + t_id).addClass("add-button").removeClass("in-cart-button");
    alert("Remove item with id: " + t_id);
}

$("a.add-button").click(function(event) {
    event.preventDefault();
    addItem(event.target.id);
});

$("a.in-cart-button").click(function(event) {
    event.preventDefault();
    removeItem(event.target.id);
});

Thanks!

+5  A: 

Instead of .click() which binds the elements when they're found initially (by which classes they had initially), you would need .live() here, like this:

$("a.add-button").live('click', function(event) {
//and
$("a.in-cart-button").live('click', function(event) {

With .click() when the element's class changes it doesn't have an effect on the handlers, all that matters is which elements had the class when you called $("a.add-button") and $("a.in-cart-button"), it found the elements and bound to those...what happens to the element afterwards doesn't matter, the handlers bound to the element, not the class. With .live() it checks the class when you click :)

Nick Craver
Had no idea, thank you for the clarification, this works perfectly! Appreciated.
TwstdElf
@TwstdElf - Welcome :)
Nick Craver
+1  A: 

That is because when the page loads, in-cart-button isn't on the page yet, so the handler isn't attached.

Just use one function with toggleClass().

function toggleItem(event) {
    $("#" + t_id).toggleClass("add-button in-cart-button");
}

$("a.add-button").click(function(event) {
    event.preventDefault();
    toggleItem(event.target.id);
});

Other options are to use .toggle() instead of .click() which accepts 2 (or more) functions.

Also, you could just pass reference to the function as the .click() handler, and still have access to the event object.

function toggleItem( event ) {
    event.preventDefault();
    var $target = $("#" + event.target.id);
    $target.toggleClass("add-button in-cart-button");
    if( $target.hasClass('in-cart-button') )
        alert("Remove item with id: " + t_id);
}

$("a.add-button").click(toggleItem);
patrick dw
I think the OP's doing additional work in these two methods, e.g. the `alert()`...but you could pass `this` to the method in either case :)
Nick Craver
@Nick - Could be. OP could do a `.hasClass()` on the next line to get the state in the function. I have a feeling that the ID is that of the `<a>` element, which of course would simplify things more.
patrick dw
A: 

Try attaching a live event to the <a/> element.

see this

Pablo Fernandez
A: 

Event delegation is basically what you are looking for...

http://www.jqueryrefuge.com/2010/06/event-handling-the-delegate-way/

John Strickler