Marten Sytema
Marten Sytema

Reputation: 1926

Triggering a click in jquery plugin does not work

I've written a plugin for jQuery, and I used the boilerplate pattern of http://jqueryboilerplate.com/

Inside, i have the following snippet of code:

ShoppingcartPlugin.prototype = {
    bindButtons : function(){
         var self = this;
             $('.addtocart').on('click.shoppingCart', function(event){
                event.preventDefault();
                $('.product-size-wrong').addClass('hidden');
                $('.product-added').addClass('hidden');

                if(!self.validateForm())
                    return;

                self.updateProductDataInDOM(event);

                var b = self.addProduct(event);
                if(b){
                    self.addExtraProducts(event); //aanvullingen

                    self.updatePrices();
                    self.calculateWeight();
                    self.calculateDeposit();
                    $('.product-added').removeClass('hidden');
                }
                self.persist();

     });
         $("body").on("click.shoppingCart","a.removefromcart", function(event){
            self.logger("a.removefromcart clicked");
            event.preventDefault();
            self.removeProduct(event);
            self.updateCartTotalPrice();
            self.updatePrices();
            self.calculateWeight();
            self.calculateDeposit();
            event.stopPropagation();
        });
    }
}

Now, I've written a Jasmine testcase, that should simulate a click on a 'a.removefromcart' element. After that, I can spy on some Ajax call and see if the results are correct.

So I've done this:

describe('Removing products testsuite', function(){
    it('Should yield an empty cart, when the X is clicked in a cart with a single product', function(){
        $('#shoppingcart').shoppingCart();
        allProducts = {};

        $('.addtocart').click(); //simulate click, and adding a product

        expect($.ajax.calls[1].args[0].data.shoppingCart[0].quantity).toBe(1);
        expect($.ajax.calls[1].args[0].data.shoppingCart.length).toBe(1);       

        $('body').trigger('click.shoppingCart','a.removefromcart');

        console.log($.ajax.calls);
        expect($.ajax.calls[2].args[0].data.shoppingCart.length).toBe(0);
    });
});

the first simulation of a click works (for adding a product), but the removal doesn't get triggered, ie, the callback of the 'on' is never being called.

The implementation works, but I 'd love to have a few testcases around this part of the plugin.

Am I taking the right approach? Any suggestions how I could debug this, such that the .on callback gets fired?

Edit: i should note that I used the $('a.removefromcart').on('click.shoppingCart', function(){...}); , but that has some other side-effects that I don't like, so I'd prefer to keep the click binding the same as it is now. I just want to trigger it programmatically.

Upvotes: 0

Views: 98

Answers (1)

Arun P Johny
Arun P Johny

Reputation: 388416

$('body').trigger('click.shoppingCart','a.removefromcart'); will not work because you are triggering the event for the body element where as the handlers are registered for a.removefromcart elements.

What you need is

$('a.removefromcart').trigger('click',);

Why

click.shoppingCart is same as a normal click event, the shoppingCart part is a namespace which is normally used to remove a specific event handler from an element. so when the event is fired the .shoppingCart part should not be there.

Also $("body").on("click.shoppingCart","a.removefromcart", ...); means you are registering an delegated event handler for elements of type a.removefromcart, so if you want the handler to be called you need to fire it on a a.removefromcart element as shown above, not in the body element as you have done

Upvotes: 1

Related Questions