1

I am developing a site on Magento 1.8.1.0 and using following plugin for add to cart with ajax.

http://www.magentocommerce.com/magento-connect/ajax-add-to-cart-1.html

It is working fine on both category listing page and product view page but i need quantity field on category listing page and for that i am copying the form tag with quantity field from product view page

C:\wamp\www\mage\app\design\frontend\bluefin\default\template\catalog\product\view.phtml to C:\wamp\www\mage\app\design\frontend\bluefin\default\template\catalog\product\list.phtml

On the product view page ajax is working on form id and form code looks like this

<form action="http://localhost/mage/index.php/checkout/cart/add/uenc/aHR0cDovL2xvY2FsaG9zdC9tYWdlL2luZGV4LnBocC9mdXJuaXR1cmUvbGl2aW5nLXJvb20vb3R0b21hbi5odG1sP19fX1NJRD1V/product/51/form_key/6sRQPimEU620349z/" method="post" id="product_addtocart_form">

<input name="form_key" type="hidden" value="6sRQPimEU620349z">
<div class="no-display">
    <input type="hidden" name="product" value="51">
    <input type="hidden" name="related_product" id="related-products-field" value="">
</div>

<div class="product-shop">

    <div class="add-to-box">
        <div class="add-to-cart">
            <label for="qty">Qty:</label>
            <input type="text" name="qty" id="qty" maxlength="12" value="1" title="Qty" class="input-text qty">
            <button type="button" title="Add to Cart" class="button btn-cart" onclick="productAddToCartForm.submit(this)"><span><span>Add to Cart</span></span></button>
        </div>
    </div>

</div>

Its javascript code looks like this

<script type="text/javascript">
//<![CDATA[
    var productAddToCartForm = new VarienForm('product_addtocart_form');
    productAddToCartForm.submit = function(button, url) {
        if (this.validator.validate()) {
            var form = this.form;
            var oldUrl = form.action;

            if (url) {
               form.action = url;
            }
            var e = null;
            try {
                this.form.submit();
            } catch (e) {
            }
            this.form.action = oldUrl;
            if (e) {
                throw e;
            }

            if (button && button != 'undefined') {
                button.disabled = true;
            }
        }
    }.bind(productAddToCartForm);

    productAddToCartForm.submitLight = function(button, url){
        if(this.validator) {
            var nv = Validation.methods;
            delete Validation.methods['required-entry'];
            delete Validation.methods['validate-one-required'];
            delete Validation.methods['validate-one-required-by-name'];
            // Remove custom datetime validators
            for (var methodName in Validation.methods) {
                if (methodName.match(/^validate-datetime-.*/i)) {
                    delete Validation.methods[methodName];
                }
            }

            if (this.validator.validate()) {
                if (url) {
                    this.form.action = url;
                }
                this.form.submit();
            }
            Object.extend(Validation.methods, nv);
        }
    }.bind(productAddToCartForm);
//]]>
</script>

As we can't have multiple element of same id in an html page that's why i am generating form id through php loop and not using inline property onclick of button. My form ids are product_addtocart_form_0, product_addtocart_form_1, product_addtocart_form_2 and so on. And my script is

<script type="text/javascript">
//<![CDATA[
    // console.log(<?php //echo $counter; ?>);
    window.onload = function () {
        var productAddToCartForm = new Array();

        for (var i = 0; i < <?php echo $counter; ?>; i++) {
            productAddToCartForm[i] = new VarienForm('product_addtocart_form_'+i);
            productAddToCartForm[i].submit = function(button, url) {
                if (this.validator.validate()) {
                    var form = this.form;
                    var oldUrl = form.action;

                    if (url) {
                       form.action = url;
                    }
                    var e = null;
                    try {
                        this.form.submit();
                    } catch (e) {
                    }
                    this.form.action = oldUrl;
                    if (e) {
                        throw e;
                    }

                    if (button && button != 'undefined') {
                        button.disabled = true;
                    }
                }
            }.bind(productAddToCartForm[i]);

            productAddToCartForm[i].submitLight = function(button, url){
                if(this.validator) {
                    var nv = Validation.methods;
                    delete Validation.methods['required-entry'];
                    delete Validation.methods['validate-one-required'];
                    delete Validation.methods['validate-one-required-by-name'];
                    // Remove custom datetime validators
                    for (var methodName in Validation.methods) {
                        if (methodName.match(/^validate-datetime-.*/i)) {
                            delete Validation.methods[methodName];
                        }
                    }

                    if (this.validator.validate()) {
                        if (url) {
                            this.form.action = url;
                        }
                        this.form.submit();
                    }
                    Object.extend(Validation.methods, nv);
                }
            }.bind(productAddToCartForm[i]);
        };

        var j = 0;
        $$('.btn-cart').each( function(item) {
            console.log(productAddToCartForm);
          item.observe('click', function(event) {
            productAddToCartForm[j].submit($(item));
          });
          j++;
        });
    }
//]]>
</script>

But when i click add to cart an error appears Uncaught TypeError: Cannot read property 'submit' of undefined

If anyone can help me then it would be great.

4

I tried some thing and it is working fine for me, i am sharing code hope this might be useful for someone else or one can suggest me the better approach.

In mage\app\design\frontend\your-design-package\default\template\catalog\product\list.phtml

Replace the following code

<?php if($_product->isSaleable()): ?>
      <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
<?php else: ?>

with

<?php if($_product->isSaleable()): ?>

<form class="product_addtocart_form" action="<?php echo $this->getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form_<?php echo $counter; ?>"<?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
    <?php echo $this->getBlockHtml('formkey') ?>
    <div class="no-display">
        <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
        <input type="hidden" name="related_product" id="related-products-field" value="" />
    </div>

    <?php $buttonTitle = $this->__('Add to Cart'); ?>
    <div class="add-to-cart">
        <?php if(!$_product->isGrouped() && !$_product->isconfigurable()): ?>
        <label for="qty"><?php echo $this->__('Qty:') ?></label>
        <input type="text" name="qty" id="qty_<?php echo $counter; ?>" maxlength="12" value="<?php echo '1'; //echo $this->getProductDefaultQty() * 1 ?>" title="<?php echo $this->__('Qty') ?>" class="input-text qty" />
        <?php endif; ?>
        <button type="button" title="<?php echo $buttonTitle ?>" class="button btn-cart" data-count="<?php echo $counter; ?>" data-ptype="<?php echo $_product->getTypeID(); ?>"><span><span><?php echo $buttonTitle ?></span></span></button>
        <?php echo $this->getChildHtml('', true, true) ?>
    </div>
</form>

<?php else: ?>

Remember i am generating form id and quantity field id with loop and as there are two display modes in magento category listing page List Mode and Grid Mode so you have to replace the above code in both areas.

id="product_addtocart_form_<?php echo $counter; ?>"

Also for button i have used two HTML5 data attributes data-count and data-ptype. In data-count i am just storing the value of $counter variable and in the data-ptype i am storing product type (i.e simple, grouped etc)

data-count="<?php echo $counter; ?>" data-ptype="<?php echo $_product->getTypeID(); ?>"

finally the javascript code

<script type="text/javascript">
//<![CDATA[
    // console.log(<?php //echo $counter; ?>);
    document.observe("dom:loaded", function() {
        var productAddToCartForm = new Array();
        for (var i = 0; i < <?php echo $counter; ?>; i++) {
            productAddToCartForm[i] = new VarienForm('product_addtocart_form_'+i);
            productAddToCartForm[i].submit = ajx_form_submit.bind(productAddToCartForm[i]);
            productAddToCartForm[i].submitLight = ajx_form_submitLight.bind(productAddToCartForm[i]);
        };

        $$('.btn-cart').each( function(item) {
            // console.log($(item).up('form').action);
            item.observe('click', function(event) {
                if (item.dataset.ptype == 'simple') {
                    ajaxcart.ajaxCartSubmit(productAddToCartForm[item.dataset.count]);
                } else if (item.dataset.ptype == 'grouped') {
                    formurl = $(item).up('form').action;
                    ajaxcart.ajaxCartSubmit(formurl);
                } else if (item.dataset.ptype == 'configurable') {
                    formurl = $(item).up('form').action + '?options=cart&ajax=true';
                    ajaxcart.getConfigurableOptions(formurl);
                }
                // productAddToCartForm[item.dataset.count].submit(item);
            });
        });
    });

    var ajx_form_submit = function(button, url) {
        if (this.validator.validate()) {
            var form = this.form;
            var oldUrl = form.action;

            if (url) {
               form.action = url;
            }
            var e = null;
            try {
                this.form.submit();
            } catch (e) {
            }
            this.form.action = oldUrl;
            if (e) {
                throw e;
            }

            if (button && button != 'undefined') {
                button.disabled = true;
            }
        }
    };

    var ajx_form_submitLight = function(button, url){
        if(this.validator) {
            var nv = Validation.methods;
            delete Validation.methods['required-entry'];
            delete Validation.methods['validate-one-required'];
            delete Validation.methods['validate-one-required-by-name'];
            // Remove custom datetime validators
            for (var methodName in Validation.methods) {
                if (methodName.match(/^validate-datetime-.*/i)) {
                    delete Validation.methods[methodName];
                }
            }

            if (this.validator.validate()) {
                if (url) {
                    this.form.action = url;
                }
                this.form.submit();
            }
            Object.extend(Validation.methods, nv);
        }
    };

    $$('.product_addtocart_form input.qty').each(function(el) {
        el.observe('blur', function(e){
            if( el.value <= 0 || isNaN(el.value) === true) {
                el.value = 1;
            }
        });
    });
//]]>
</script>
  • please mark this as accepted. – Marius Nov 28 '14 at 8:51
  • I've got ajaxcart is not defined any suggestions please? – mahmoudismail Sep 9 '17 at 11:55
  • Where are you declaring your $counter variable? – MagentoAaron Aug 1 '18 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.