0

Okay coding gurus, I have been working on this for a few weeks now and I have pretty much everything figured out and functioning. The project is an abandoned cart recovery script. I have the form setup and Javascript that stores all input values as they are typed to localstorage. On page refresh, the values are sent off to the PHP processing file and written into the MySQL database correctly.

However, the Ajax post should occur on page close or navigation away as well, and not just page refresh. The only reason I am testing with page refresh is that it fires off an unload event and I can test the response back from the server as well as what my local variables and localstorage data is set to.

The Ajax post is set to be synchronous, and seems to be working fine through the unload event triggered on a page refresh. Is there something different between a page refresh and a window close? The code is below, if you need the form and PHP code I will post that as well.

For clarification, at the bottom of the script is what we are looking at. There is a beforeunload event bound to the window through Jquery that calls the submitform function, and commented out is a onunload handler for the window that also calls the submitform function. Both methods seem to be working the same, and properly calling the function on a page refresh and not a page close. They also do not work for navigation away from the page.

$( function() {
$( "#myform" ).sisyphus( {
    excludeFields: $( "#useShippingRadio" ),
    excludeFields: $( "#useBillingRadio" ),
    excludeFields: $( "#billing-first-name" ),
    excludeFields: $( "#billing-last-name" ),
    excludeFields: $( "#billing-company" ),
    excludeFields: $( "#billing-address1" ),
    excludeFields: $( "#billing-address2" ),
    excludeFields: $( "#billing-city" ),
    excludeFields: $( "#billing-first-name" ),
    excludeFields: $( "#billing-first-name" ),
    excludeFields: $( "#billing-first-name" ),
    excludeFields: $( "#billing-first-name" ),
    excludeFields: $( "#paymentSelection_0" ),
    excludeFields: $( "#ccSelectedRadio" ),
    excludeFields: $( "#card-type" ),
    excludeFields: $( "#card-number" ),
    excludeFields: $( "#card-exp-month" ),
    excludeFields: $( "#card-exp-year" ),
    excludeFields: $( "#card-cvv" ),
    excludeFields: $( "#paymentSelection_1" ),
    excludeFields: $( "#ppSelectedRadio" ),
});
});
function submitform(){
$.ajax({
  type: "POST",
  url: 'process.php',
  dataType: 'json',
  data: {
    myform:[{
        fname: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_first_name'),
        lname: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_last_name'),
        company: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_company'),
        address: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_address1'),
        city: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_city'),
        state: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_state'),
        zip: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_zip'),
        phone: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_phone'),
        country: localStorage.getItem('myformundefinedshippingAddressDS.shipping_ROW0_country'),
        cart_coupon: localStorage.getItem('myformundefinedgcPaymentDS.gcpayment_ROW0_redemptionCode'),
        email: localStorage.getItem('myformundefinedmiscDS.shopperEmailAddress'),
        orderSubTotal: orderSubTotal,
        orderTotal: orderTotal,
        numOfItems: numOfItems,
        items: items,
        ids: ids,
        codes: codes,
        qtys: qtys,
        price: price,
        orderTax: orderTax,
        orderShipping: orderShipping,
        appliedPromoIdList: appliedPromoIdList,
        coupon: coupon,
        storeId: storeId,
        activeShipPromotionCount: activeShipPromotionCount,
        itemImages: itemImages
        }]
        },
  async: false,
});
};
$(window).bind('beforeunload', submitform());
//window.onunload(submitform());
Will Case
  • 105
  • 8
  • Your form is posting but the page is closing before data is sent. I think what you're asking is "How do I make the page close wait until the form has been successfully submitted?" – Popnoodles Dec 01 '13 at 20:46
  • If the page is closing before the data is sent, then that means the async:false check in the Ajax post is not setting the post submission to be synchronous. Would a page close have a different effect than a page refresh on whether the browser does in fact wait for the synchronous request to finish? – Will Case Dec 01 '13 at 20:56
  • I wouldn't expect them to be different. I'm interested to see if there is a solution to this. – Popnoodles Dec 01 '13 at 20:57
  • According to this SO post ( http://stackoverflow.com/questions/2970782/javascript-wait-until-ajax-request-finishes-to-close-page ) it's possible making the ajax post synchronous prevents the beforeunload event from firing. Since the Jquery trigger is more of an all around, it still submits the form, but it does so in the same event as the regular Javascript trigger. However, as of yet I have not found a reason why the page would close while a synchronous request is pending. – Will Case Dec 01 '13 at 21:01
  • Because the close button destroys the page. – Popnoodles Dec 01 '13 at 21:02
  • That question doesn't do what you want, it forms a dialog, which it seems is the only thing you can do onbeforeunload. https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload – Popnoodles Dec 01 '13 at 21:03
  • I think the solution then is for me to assign a unique identifier to each cart on the client-side and have form data posted every few seconds. The PHP processing file will have to verify the unique id and modify the MySQL database entry accordingly. As a bonus, I'll leave the current functionality in so that if the user refreshes between save cycles, it does a full form save as well. – Will Case Dec 01 '13 at 21:07
  • Hundreds of requests each with a DB update? Even if it's on request per change of form field you're going to give your server a massive headache. Why don't you save a cookie (with javascript) that you can check for, leaving the work on the client side? – Popnoodles Dec 01 '13 at 21:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42352/discussion-between-will-case-and-popnoodles) – Will Case Dec 02 '13 at 17:10

0 Answers0