malsup / blockui

jQuery BlockUI Plugin
http://jquery.malsup.com/block/
1.69k stars 506 forks source link

safari 6 blockui called by a submit button inside a form tag does not seem to work #89

Open mwae opened 10 years ago

mwae commented 10 years ago

Hi there,

I have a problem with safari 6 not being able to blockUI before sending a form. It's ok if the submit button is not within a form.

Works in Safari 6:

<span id="spinner" style="display:none;"><h1><img src="images/busy.gif" />  Please wait while we load ...</h1></span>
<input id="submit" name="Submit" type="submit" value="Upload"/>

Does not work in Safari 6 but works in FireFox 24.0:

<span id="spinner" style="display:none;"><h1><img src="images/busy.gif" />  Please wait while we load ...</h1></span>
<form><input id="submit" name="Submit" type="submit" value="Upload"/></form>

html (js):

<script>
$(document).ready(function() {
        $('#submit').click(function () {
              $.blockUI({ message: $('#spinner') });
        });
}); 
</script>
malsup commented 10 years ago

That's probably because Safari is immediately submitting the form without taking a breath to repaint. Try this instead:

$(document).ready(function() {
    $('#submit').click(function (e) {
        var form = this.form;
        e.preventDefault();
        $.blockUI({ message: $('#spinner') });
        setTimeout(function() {
            form.submit();
        }, 10);
    });
}); 
mwae commented 10 years ago

Thanks! I combined it with your other module jquery.form so that I could have the spinner block the ui while my files were uploading. The above works except for file input type inside the form - for those using the above, make sure your submit button does not have name/id as submit..rename to something else; I used uploaded. So the final combo that works for me in Firefox, chrome, Safari (have not tested on IE yet but I think it should be fine) is below:

<html>
<head>
                <script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
                <script src="http://malsup.github.com/jquery.form.js"></script>
                <scriptsrc="http://malsup.github.com/jquery.blockUI.js"></script>
</head>
<body>
<span id="spinner" style="display:none;"><h1><img src="images/busy.gif" />  Please wait while we load ...</h1></span>

<form id="myform" enctype="multipart/form-data" action="processfile.php" method="post">
<br />
<input type="file" name="filesToUpload[]" id="filesToUpload" multiple/>
<br />
<input id="uploaded" name="uploaded" type="submit" value="Upload"/>
</form>
</body>
</html>

<script>
(function() {
        $('#myform').ajaxForm({
            beforeSend: function() {
              $.blockUI({ message: $('#spinner') });
        },
        complete: function(xhr) {
                $.unblockUI;
                alert(xhr.responseText);
            }
        }); 
})();
</script>

processfile.php

<?php

    foreach($_FILES as $file) {
        $n = $file['name'];
        $s = $file['size'];
        if (is_array($n)) {
            $c = count($n);
            for ($i=0; $i < $c; $i++) {
                echo "\nuploaded: " . $n[$i] . " (" . $s[$i] . " bytes)";
            }
        }
        else {
            echo "\nuploaded: $n ($s bytes)";
        }
    }
?>
justintoth commented 8 years ago

I'm running into the same issue, where the blockui dialog shows in Chrome, Firefox, and Edge but doesn't show in Safari when submitting a form. @malsup's solution works if it's a basic button click event, however if you're using the jquery ajaxForm then I don't see a way to implement this solution, as there is no e.preventDefault event, nor can you setTimeout then submit the form, unless I'm missing something...

this.setupAjaxForm = function (opts) { var formId = opts.formId || 'form'; var form = $('#' + formId); form.ajaxForm({ iframe: true, dataType: 'json', beforeSubmit: function (e) { if (opts.beforeSubmit) opts.beforeSubmit(); var isValid = form.valid(); if (isValid) { //show progress. e.preventDefault();//TODO: this errors, preventDefault not a function utils.block($('#form'), opts.progressText || 'Saving'); //submit form. setTimeout(function () {//TODO: this doesn't work, form submission is determined by the return value form.submit(); }, 10); } return isValid; }, success: function (result) { ... }, error: function (xhr, textStatus, errorThrown) { ... } }); };

mattkaz commented 6 years ago

I'm having this same issue... we're validating a form, and then trigger blockUI afterwards. Works in all browsers except Safari. I've tried the above, but it's a fine line to walk in choosing that timeout value. Either way, no matter what I set that to, then error messages do not appear on page reload as they should, if form input is invalid.

Here is our code:

<script id="globalPaymentPageData" type="text/javascript">
            $(function() {
                $("form[id*='creditCardForm']").validate({
                    debug: false,
                    errorClass: "errorMessage",
                    errorElement: "span",
                    // trigger blockUI after form validation has taken place and form is valid
                    submitHandler: function(form) {
                        $.blockUI.defaults.css = {};
                        $.blockUI({
                            message: '<img src="images/store/ajax-loader.gif" class="checkout-ajaxLoaderImage" width="160" height="24" /><p class="checkout-pleaseWait">Please wait &mdash; your order is being submitted.</p>',
                            centerX: true,
                            centerY: true
                        });
                        form.submit();
                    }
                });
            });
        </script>

Any help would be greatly appreciated! Thank you.

marmz commented 6 years ago

Did you try to submit form AFTER block completes ("onBlock" parameter)?

$.blockUI({    ............

        onBlock: function() {
               form.submit();
         }

});
mattkaz commented 6 years ago

@marmz Thank you for the super speedy reply.

I had not tried that. I just did, and I get the same thing that I mentioned in my comment/question above... the blockUI 'block' appears, but my errors messages/feedback no longer appear when the page reloads (when bad data is entered in the form). It is a credit card form, and when the user clicks/taps the submit button, blockUI should execute (which it does), but then since invalid data was entered, the page should reload and our error messages should appear. The validator we're using here is separate from the error messaging... it's an inline validator for the form (https://jqueryvalidation.org/).

So here's what I am using right now, and still having problems with, just so you have my latest code:

<script id="globalPaymentPageData" type="text/javascript">
            $(document).ready(function () {
                $("form[id*='creditCardForm']").validate({
                    debug: true,
                    errorClass: "errorMessage",
                    errorElement: "span",
                    // trigger blockUI after form validation has taken place and form is valid
                    submitHandler: function(form) {
                        $.blockUI.defaults.css = {};
                        $.blockUI({
                            message: '<img src="/images/store/ajax-loader.gif" class="checkout-ajaxLoaderImage" width="160" height="24" /><p class="checkout-pleaseWait">Please wait &mdash; your order is being submitted.</p>',
                            centerX: true,
                            centerY: true,
                            onBlock: function() {
                                form.submit();
                            }
                        });
                    }
                });
            });
        </script>

Thanks again very much!

mattkaz commented 6 years ago

Any further thoughts on this? I've tried and tried and tried all kinds of different options, etc, and no luck. Thank you!