Javascript and php while loop - only returning first entry

  • Thread starter Deleted member 66701
  • Start date

Deleted member 66701

D

Deleted member 66701

Hi all.

I'm pulling all products in a category back to display on a page (which is working fine). I have a javascript function attached to a "add to cart" to add each product to a $_SESSION cart. However, the problem is that it is only ever picking up the first product returned - i.e. no matter what "add to cart" link you click on, it's always adding the first product to the cart. Here's my code:-

Javascript:
Code:
  <script>
  	$(document).ready(function() {
	$('.addtocartlink').click(function() {	
		
		var randNum = Math.floor(Math.random() *10000000);

		$.ajax({
			url: "mng_cart.php?rand=" + randNum,
			dataType: 'text',
			type: 'POST',
			data: 'action=add&product_id=' + $('.addtocartlink').attr('alt'),
			beforeSend: function() {
				$('#cartload').html('loading');
				},
			complete: function() {
				$('#cartload').html('');
				},
			success:function(result) {
				$("#holdcart").html('').append(result);
			}
		});
		
		return false;  //stops link clicking normally
	});
});

HTML/PHP:
Code:
         <?php while($row=mysqli_fetch_array($product)) { 
           ?>

           <p><br /><?php echo $row['p_short_desc']; ?></p>
           <ul class="buttons">
            <li class="cart"><a href="#" class="addtocartlink"
              alt="<?php echo $row['product_id']; ?>">Add To Cart</a></li>
              <li class="shop_btn"><a href="product.php?MainCat=<?php echo $_GET['MainCat'] ?>&SubCat=<?php echo $_GET['SubCat'] ?>&id=<?php echo $row['product_id']; ?>">Read More</a></li>                           
           </ul>
              <?php
            } //end while loop ?>

It's the alt part of $('.addtocartlink').attr('alt') that is always set to the first product id in the JS function. It should vary depending on the product id for each product returned.

Any ideas?
 
Last edited by a moderator:
Associate
Joined
23 Mar 2006
Posts
1,739
$('.addtocartlink') will search for the first element of class addtocartlink in the page. So every time you press on a link it searches again, always finding the same element.

You need to do something along the lines of:

Code:
$(.addtocartlink).click(funtion(this)){
...
...
product_id = $(this).attr('alt');

I think, my js is a bit rusty.
 

Deleted member 66701

D

Deleted member 66701

OP
You beauty!

New code:-
Code:
  <script>
  	$(document).ready(function() {
	$('.addtocartlink').click(function() {
		var randNum = Math.floor(Math.random() *10000000);
		window.alert("Debug message - product_id passed to add to cart onclick function:  "+'action=add&product_id=' + product_id);
		$.ajax({
			url: "mng_cart.php?rand=" + randNum,
			dataType: 'text',
			type: 'POST',
			data: 'action=add&product_id=' + $[B][U](this)[/U][/B].attr('alt'),
			beforeSend: function() {
				$('#cartload').html('loading');
				},
			complete: function() {
				$('#cartload').html('');
				},
			success:function(result) {
				$("#holdcart").html('').append(result);
			}
		});
		
		return false;  //stops link clicking normally
	});
});

</script>

Working perfectly - here - have a virtual cookie!
 
Last edited by a moderator:
Associate
Joined
26 Sep 2007
Posts
1,252
Location
Amsterdam
Unrelated to your question, but don't use alt to store the product ID. Give it a data attribute and use that instead and let alt fulfil its purpose (providing a textual backup, hover text and for users with vision problems) :)
 

Deleted member 66701

D

Deleted member 66701

OP
Unrelated to your question, but don't use alt to store the product ID. Give it a data attribute and use that instead and let alt fulfil its purpose (providing a textual backup, hover text and for users with vision problems) :)

Good point well made!

Cheers.
 
Soldato
Joined
18 Oct 2002
Posts
15,177
Location
The land of milk & beans
Just a couple of pointers with your jQuery. Best practices say that you should always give $.ajax an object when passing data as it means it will be encoded for you. Not a big deal in your case, but good for consistency. Also, don't use 'return false' as it also stop propagation as well as the default event handling, use event.preventDefault() instead. Finally it looks like you're returning HTML as a string from your PHP - it would be better to return JSON which contains a message to the user about the state of the request, and build the required HTML on the client DOM as it reduces the bandwidth taken by the site and reduces server load.

Code:
$('.addtocartlink').click(function (e) {
    e.preventDefault();
    var $cartload = $('#cartload');
    var $holdcart = $('#holdcart');

    $.ajax({
        url: "mng_cart.php?rand=" + Math.floor(Math.random() * 10000000),
        dataType: 'JSON',
        type: 'POST',
        data: {
            action: 'add',
            product_id: $('.addtocartlink').data('product-id');
        },
        beforeSend: function () {
            $cartload.html('loading');
        },
        complete: function () {
            $cartload.html('');
        },
        success: function (result) {
            var $result = $('<p />', { text: result });
            $holdcart.html('').append($result);
        }
    });
});
 

Deleted member 66701

D

Deleted member 66701

OP
Just a couple of pointers with your jQuery. Best practices say that you should always give $.ajax an object when passing data as it means it will be encoded for you. Not a big deal in your case, but good for consistency. Also, don't use 'return false' as it also stop propagation as well as the default event handling, use event.preventDefault() instead. Finally it looks like you're returning HTML as a string from your PHP - it would be better to return JSON which contains a message to the user about the state of the request, and build the required HTML on the client DOM as it reduces the bandwidth taken by the site and reduces server load.

Code:
$('.addtocartlink').click(function (e) {
    e.preventDefault();
    var $cartload = $('#cartload');
    var $holdcart = $('#holdcart');

    $.ajax({
        url: "mng_cart.php?rand=" + Math.floor(Math.random() * 10000000),
        dataType: 'JSON',
        type: 'POST',
        data: {
            action: 'add',
            product_id: $('.addtocartlink').data('product-id');
        },
        beforeSend: function () {
            $cartload.html('loading');
        },
        complete: function () {
            $cartload.html('');
        },
        success: function (result) {
            var $result = $('<p />', { text: result });
            $holdcart.html('').append($result);
        }
    });
});

Thanks for the heads up, but we're doing procedural atm and we go on to object orientated next semester - I'm already getting my hands smacked for progressing too fast :(

I'll take a look at then other suggestions though and try to rework my code - as soon as I have a clue what you're talking about! :D
 
Back
Top Bottom