SabKo SabKo - 2 months ago 6
HTML Question

Javascript beforesend function incorrectly displayed on all "add to cart" buttons

On my ecommerce webshop, I have a page where some products are listed row by row in a table. After each product, there is an "add to cart" button displayed. When a visitor clicks the add to cart button of a specific product, then the corresponding "add to cart" button should temporarily change in "... loading" before the product is effectively added to the cart. The problem on my page is that ALL "add to cart" button are showing the "...loading" message when only one of the buttons is clicked (see picture below).

enter image description here

I have no idea how to solve this. Please find the corresponding piece of code below. I hope somebody can point me in the correct direction. The product itself however (and only this product) is correctly added to the cart.

Thanks,
SabKo

The HTML:

<? $r=($page-1)*20+1; foreach($products AS $product){ ?>
<tr id="row_<?=$product['product_id']?>">
<td class="center">
<input type="hidden" value="<?=$product['product_id']?>" size="2" name="product_id" />
<input type="hidden" value="<?=$product['gift_products_id']?>" size="2" name="gift_products_id" />
<? if($product['quantity']!==$product['total']){ ?>
<select name="quantity" class="form-control_cart" id="input-quantity" value="1" >
<?php foreach (range(1, $product['quantity'], 1) as $stap) {
if ($stap == 1) {
echo "<option value='$stap' selected>$stap</option>";
} else {
echo "<option value='$stap'>$stap</option>";
}
} ?>
</select>
<a class="btn btn-default addtocart" style="margin-top:-4px" lang="<?=$product['product_id']?>" href="javascript:void(0)" data-toggle="tooltip" title="<?=$_['gr_m_add_to_cart']?>"><i class="fa fa-shopping-cart"></i></a>
</td>
</tr>
<? $r++;} ?>


The javascript:

<script type="text/javascript">
$('.deletelink').click(function(){
if(confirm('<?=$_['gr_remove_q']?>')){
return true;
} else {
return false;
}
});
$('.addtocart').click(function() {

id = $(this).attr('lang');

$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: $('#row_'+id+' input[type=\'text\'], #row_'+id+' input[type=\'hidden\'], #row_'+id+' select'),
dataType: 'json',
beforeSend: function() {
$('.addtocart').button('loading');
},
complete: function() {
$('.addtocart').button('reset');
},
success: function(json) {
$('.alert, .text-danger').remove();
$('.form-group').removeClass('has-error');

if (json['error']) {
if (json['error']['option']) {
for (i in json['error']['option']) {
var element = $('#input-option' + i.replace('_', '-'));

if (element.parent().hasClass('input-group')) {
element.parent().after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
} else {
element.after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
}
}
}

if (json['error']['recurring']) {
$('select[name=\'recurring_id\']').after('<div class="text-danger">' + json['error']['recurring'] + '</div>');
}

// Highlight any found errors
$('.text-danger').parent().addClass('has-error');
}

if (json['success']) {
if (!Journal.showNotification(json['success'], json['image'])) {
$('.breadcrumb').after('<div class="alert alert-success success">' + json['success'] + '<button type="button" class="close" data-dismiss="alert">&times;</button></div>');
}

$('#cart-total').html(json['total']);

$('html, body').animate({ scrollTop: 0 }, 'slow');

$('#cart ul').load('index.php?route=common/cart/info ul li');
}
}
});
});
</script>

Answer

$('.addtocart') matches all the buttons. You need to select just the one they clicked on.

$('.addtocart').click(function() {

    var id = $(this).attr('lang');
    var self = $(this);

    $.ajax({
        url: 'index.php?route=checkout/cart/add',
        type: 'post',
        data: $('#row_'+id+' input[type=\'text\'], #row_'+id+' input[type=\'hidden\'], #row_'+id+' select'),
        dataType: 'json',
        beforeSend: function() {
            self.button('loading');
        },
        complete: function() {
            self.button('reset');
        },
        success: function(json) {
            $('.alert, .text-danger').remove();
            $('.form-group').removeClass('has-error');

            if (json['error']) {
                if (json['error']['option']) {
                    for (i in json['error']['option']) {
                        var element = $('#input-option' + i.replace('_', '-'));

                        if (element.parent().hasClass('input-group')) {
                            element.parent().after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
                        } else {
                            element.after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
                        }
                    }
                }

                if (json['error']['recurring']) {
                    $('select[name=\'recurring_id\']').after('<div class="text-danger">' + json['error']['recurring'] + '</div>');
                }

                // Highlight any found errors
                $('.text-danger').parent().addClass('has-error');
            }

            if (json['success']) {
                if (!Journal.showNotification(json['success'], json['image'])) {
                    $('.breadcrumb').after('<div class="alert alert-success success">' + json['success'] + '<button type="button" class="close" data-dismiss="alert">&times;</button></div>');
                }

                $('#cart-total').html(json['total']);

                $('html, body').animate({ scrollTop: 0 }, 'slow');

                $('#cart ul').load('index.php?route=common/cart/info ul li');
            }
        }
    });
});