bobbybouwmann
bobbybouwmann

Reputation: 1013

prevent jQuery post request to fires mulitple times

I have a web shop where users can add products to there cart with one button, so they stay on the catalog page (where all products are listed). I do this by using jQuery and ajax. The weird thing is that when I press the button all forms will be submitted. This is not what I want!

$(function() {
    $('form').submit(function (event) {
        event.preventDefault();

        var $form = $(this),
            formdata = $form.serialize(),
            url = $form.attr('action');

        $.post(url, formdata);
    });
});

I understand I can't use a single class for this, since this will submit them all, but ids are not useful since I can have over 50 products on a page and that would be a lot of duplicated work.

So are there any solutions for this?

Thanks in advance

Upvotes: 1

Views: 82

Answers (3)

Alan
Alan

Reputation: 3002

When you build your product list, you could add an attribute to each button. Something like this should work:

<button data-productid='ABC123' onclick='addToCart(this)'>Add</button>

<script>
    function addToCart(btn) {
        var productId = $(btn).data('productid');
        // do ajax call, using productid
    }
</script>

Upvotes: 0

enguerranws
enguerranws

Reputation: 8233

I think you just need another parameter, e.g. the ID of the current product. So you will be able to do something like :

$(function() {
    $('.add-cart-form').submit(function (event) {
        event.preventDefault();

        var $form = $(this),
            productId = $(this).attr('data-product-id'), // Assuming you add the ID in your view
            formdata = $form.serialize() + '&productId=' + productID,
            url = $form.attr('action');

        $.post(url, formdata);
    });
});

Then, you have to retrieve the productId parameter, that will only return the current product.

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93601

The code you show should work in isolation, so either your code is not being hit (due to an error on the page), or it is not connecting to the per-product forms (e.g. if they are also loaded dynamically).

If the forms are loaded dynamically, as I suspect they may be, then you need to use a delegated event handler, attached to a non-changing ancestor of the forms (document is the default)

e.g.:

$(function() {
    $(document).on('submit', 'form', function (event) {
        event.preventDefault();

        var $form = $(this),
            formdata = $form.serialize(),
            url = $form.attr('action');

        $.post(url, formdata);
    });
});

it works by listening for the submit event to bubble up to the ancestor, then applies the jQuery form selector, then applies the function to any matching elements that caused the event, so will work on forms added to the page dynamically.

If this is not the case, please provide the rest of your code and a sample of the page's HTML (from a browser save-as, not source).

Upvotes: 1

Related Questions