JQuery GET works only first time, second time I just get server response... why?

792 Views Asked by At

I have some JQuery where when you click on a "Add to Basket" button (it's really a link), the first time everything works as expected however click the button a second time, although the product is added to basket (database row has increased quantity), the response sent by server is outputted rather than "captured" by JQuery in the SUCCESS function.

I don't understand why this would happen, any thoughts on this?

JQuery

$(function() {
            $( '.button' ).click(function( e ) {
                e.preventDefault();

                var url = $( this ).children( 'a' ).attr( 'href' );

                var elem = $( this ); 
                var parent = $( this ).parent().parent(); 
                var html = parent.html(); alert( html );

                $.ajax({
                    type: 'get',
                    url: url,
                    data: '',
                    cache: false,
                    dataType: 'text',
                    beforeSend: function( rs ) {
                        parent.html( '<div class="basket-item item-border" style="width:896px;text-align:center;"><p class="para"><img src="/media/images/spinner.gif" />Please wait...</p></div>' );
                    },
                    success: function( rs ) {
                        parent.html( html );

                        if( rs = 'YES' ) {
                            alert( 'Okay' );
                        } else {
                            alert( 'Something went wrong' );
                        }
                    },
                    error: function( rs, err ) {
                        if( rs.status == 0 ) {
                            alert( '--- Offline' );
                        } else if( rs.status == 404 ) {
                            alert( '404 Not Found' );
                        } else if( rs.status == 501 ) {
                            alert( '501 Internal Error' );
                        } else if( err == 'timeout' ) {
                            alert( '--- Timeout' );
                        } else {
                            alert( '--- Unknown' );
                        }
                    }
                 });
            });
        });

And here is a section of the HTML the JQuery works on

<div>
            <div class="basket-item item-border" style="width:512px;text-align:left;">
                <p class="para">

                    <img 
                        width="48" 
                        height="48" 
                        alt="Sample Soap Pack (&pound;3.99)" 
                        src="http://www.mj.local/media/images/products/generic/0929005236213037.jpg" />
                <a href="http://www.mj.local/products/sample-soap-pack/">Sample Soap Pack</a></p>
            </div>

            <div class="basket-item item-border"><p>3.99</p></div>
            <div class="basket-item item-border" style="width:256px;text-align:center;">
                <p class="button"><a href="http://www.mj.local/shop/add/sample-soap-pack/">
                    <span class="add">Add to Basket</span>

                </a></p>
            </div>
        </div>

The contents of the parent DIV are replaced with a "Please wait.." message and then restored, as expected so would this alter any way JQuery works? I have another JQuery working okay when swapping HTML so why now with this?

Thanks.

2

There are 2 best solutions below

5
Bassam Mehanni On BEST ANSWER

it's because on success you are replacing the html of the parent, your .button will be replaced, and the new .button won't have the click event binded anymore.

You could fix it by using live jQuery <1.7:

$(function() {
  $('.button').live('click', function() {
     //your function here
   });
});

or on for jquery >1.7:

$(function() {
  $(document).on("click", ".button", function(){ });
});
2
Jasper On

You are replacing your .button element inside the callback function for the AJAX request that clicking on the .button element makes and when you remove the .button element the click event handler for that element is also removed. I would use event delegation so the event handler will affect all the elements currently in the DOM and ones added later (for example by an AJAX call):

Just change:

$( '.button' ).click(function( e ) {

To:

$(document).delegate('.button', 'click', function( e ) {

Here are docs for .delegate(): http://api.jquery.com/delegate