LoneWolfPR
LoneWolfPR

Reputation: 4090

How to execute JQuery BEFORE Safari submits form

I've run into an issue that only seems to a problem in Safari. I have an overlay that is set to display:none in it's css. When the user clicks submit I want the overlay to show until processing is finished. I did this initially by just binding this to the button's on('click'... function in jquery. This worked just fine except in Safari. Safari wants to execute the submit before the calls in the click. So, based on some other things I found I instead put this all on the submit event for the form instead of the click and used a timeout object set to 0. Like this:

$('#tcmi-shop-cart-checkout').submit(function(){
    var showOverlay = function(){$('#processing-overlay').css('display','block')};
     setTimeout(showOverlay,0);
});

This, again, works in all other browsers except Safari. Safari still wants to submit the form data and wait for a response before it executes this. How can I make Safari show this overlay BEFORE submitting the data?

Upvotes: 4

Views: 1532

Answers (7)

Srdjan Dejanovic
Srdjan Dejanovic

Reputation: 1409

I had a same issue and I solve it with:

$(document).on("click", "input[type=\"submit\"]", function (e) {
    e.preventDefault();
    var $form = $(this).closest("form"),

    // Do whatever you want

    setTimeout(function () {
        $form.unbind('submit').submit();
    }, 200);
});

You can add additional check for safari browser if you want.

Upvotes: 1

Mishack
Mishack

Reputation: 1

This works for me. It's not "clean" but it works :)

var someForm = $('.someform');
var someOverlay = $('.someOverlay');

someForm.on('submit', function(e) {
    e.preventDefault();
    someForm.off('submit');
    someOverlay.fadeIn('fast', function(){
        someForm.submit();
    });
});

Upvotes: 0

LoneWolfPR
LoneWolfPR

Reputation: 4090

I wound up having to do a crazy hack to make this work. It's basically a combination of preventDefault() as mentioned above with some other stuff. Because it's a Drupal form if I do form.submit() it would use the 'back' button i have on my form instead of the actual submit causing an obvious problem. So I had to use the actual submit button to do the trigger. This involved basically triggering a second call on the button. The first time shows the overlay then calls the submit again and actually triggers the submit. Here's the code:

        var submitOpen = true;
        $('#edit-submit-order').on('click',function(e){
          if (submitOpen) {
               e.preventDefault();
               $('#processing-overlay').css('display','block');
               submitOpen = false;
               setTimeout(function(){$('#edit-submit-order').trigger('click')},5);
          } else {
               submitOpen = true
          }
        });

Upvotes: 0

guest271314
guest271314

Reputation: 1

Try

$("#tcmi-shop-cart-checkout").on("click", function(e) {
   e.preventDefault();
   e.stopPropagation();
    var el = $(this), elem = $("#processing-overlay");
    var settings = {};
    settings.url = el.attr("action");
    settings.type = el.attr("method");
    settings.context = elem;
    settings.data = el.serialize();

   elem.toggle(function() {
       $.ajax(settings)
       .then(function success(data, textStatus, jqxhr) {
         console.log(data);
         $(this).toggle()
       }, function error(jqxhr, textStatus, errorThrown) {
         console.log(textStatus, errorThrown)
       })
    })
});

jsfiddle http://jsfiddle.net/bmLkauzp/

Upvotes: 1

clav
clav

Reputation: 4251

I'm assuming the button is a "submit" button and the submit event fired by clicking it is firing before your javascript has a chance to show the overlay. Try submitting the form with javascript instead and use preventDefault to eat the submit event from the button, like this:

$(function() {
    $('#submitButton').click(function(e) {
        $('#processing-overlay').css('display', 'block');
        $('#tcmi-shop-cart-checkout').submit();
        e.preventDefault();
    });             
});

Upvotes: 1

Isaiah Lee
Isaiah Lee

Reputation: 687

Have you tried preventDefault()?

If you're just POSTing some data via the form, you could do something like this (in pseudocode):

#form.submit() {
  preventDefault()
  setOverlay(true)
  POST()
    .then(setOverlay(false))
}

Basically, you want to prevent the default form submit, display the overlay right after, and then submit the form data using ajax. You have access to the callback function when its finished, and its there you can turn the overlay off.

Upvotes: 2

taxicala
taxicala

Reputation: 21759

Remove the setTimeout and it should work fine. When calling setTimeout you are pushing the function to the event-queue and releasing the thread and the form submit is happening at that time.

In code:

$('#tcmi-shop-cart-checkout').submit(function(){
    $('#processing-overlay').css('display','block');
});

Upvotes: 0

Related Questions