как в jQuery, чтобы вызвать событие после отправки формы возврата?


У меня есть дорогостоящее действие form, которое создает zip-файл на сервере и возвращает его в браузер.

<form action='/download' method='post'>

<input type='submit' value='download'/>

</form>

Я хочу заблокировать страницу при нажатии кнопки, чтобы пользователь не нажимал кнопку повторно.

Однако я хочу разблокировать страницу после возврата формы.

Как можно вызвать событие при успешном заполнении формы?

(я знаю, что могу вызвать это, изменив форму, чтобы быть отправкой ajax, но тогда диалоговое окно Сохранить файл не будет появиться...)

Есть предложения?

Спасибо

3 3

3 ответа:

Одним из способов справиться с этим без использования AJAX может быть передача содержимого формы элементу iframe. Если вы прикрепите функцию onsubmit к форме, которая отключает дальнейшие отправки, и прикрепите функцию onload к iframe, вы сможете отключить пользователя от отправки формы несколько раз.

Пример HTML:

<form action="/download" method="post" target="downloadFrame" onsubmit="return downloadFile();">
  <input type="submit" value="download" />
</form>
<iframe style="width: 0px; height: 0px;" scrolling="no" frameborder="0" border="0" name="downloadFrame" onload="downloadComplete();"></iframe>

Пример Javascript:

var downloading = false;
function downloadFile() {
    var isDownloading = downloading;
    downloading = true;
    return !isDownloading;
}
function downloadComplete() {
    downloading = false;
}

Похоже, что никто еще не нашел способ обнаружить возврат сообщения в самом браузере, но есть еще одна возможность с помощью AJAX. Это немного более вовлечено, хотя:

<script type="text/javascript">
    $(function () {
        $('#submitbtn').click (function () {
            window.setTimeout (dldone, 100);
            return true;
        });

        function dldone () {
            $.get ("/downloadstatus?rand="+$('#rand').val (), function (data) {
                if (data == 'done') {
                    // data generation finished, do something
                } else {
                   window.setTimeout (dldone, 100);
                }
            });
        }
    });
</script>
<form action="/generatedata" method="post">
    <input type="hidden" id="rand" value="[RANDOMVALUE]">
    <input type="submit" id="submitbtn" value="Download Data">
</form>

На сервере вам нужно будет выполнить некоторую межпроцессную коммуникацию, чтобы подать сигнал, когда генерация данных будет завершена. Поскольку у меня уже есть база данных, я сделал это так:

public function downloadstatusAction () {
    if ($this->db->fetchOne ("SELECT rand FROM dlstatus WHERE rand = ?", (int) $_GET["rand"])) {
        $db->delete ("dlstatus", array ("rand = ?" => (int) $_GET["rand"]));
        print "done";
    } else {
        print "loading";
    }
}

public function generatedataAction () {
    // generate data
    $this->db->insert ("dlstatus", array ("rand" => (int) $_POST["rand"]));
    // output data
}
Я уверен, что есть более элегантные способы сделать это, но вы понимаете идею. Это, кажется, работает нормально во всех браузерах I проверенный.

Я использовал это:

function generatePdfZipViaWS_ajax(theUrl) {

    //=========================
    // testé avec Chrome 37.0.2062.124 m, Firefox  32.0.3
    // ça block avec IE9 à cause du xmlHttp.overrideMimeType
    //=========================
    var xmlHttp = new XMLHttpRequest();

    var alert = document.getElementById("alertError");
    block_UI();

    var url = "undefined";

    xmlHttp.open("GET", theUrl, true);
    xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xmlHttp.overrideMimeType("application/octet-stream");
    xmlHttp.responseType = "blob";

    xmlHttp.onload = function(oEvent) {
        if (xmlHttp.status == 200) {

            deblock_UI();
            // a mettre apres un certain temps:  window.URL.revokeObjectURL(url);

        } else {
            alert.style.display = "block";
            deblock_UI();

            //  console.log("Error " + xmlHttp.status + " occurred downloading your file.<br \/>");
        }
    };

    xmlHttp.onreadystatechange = function() {

        if (xmlHttp.readyState == xmlHttp.DONE) {

            if (xmlHttp.status == 200) {

                var contentDisposition = xmlHttp.getResponseHeader("Content-Disposition");
                var type = xmlHttp.getResponseHeader("Content-Type");

                var reponseType = xmlHttp.responseType;

                var pos1 = contentDisposition.indexOf("archive");
                var pos2 = contentDisposition.lastIndexOf(".zip") + 4;
                var fileName = contentDisposition.substring(pos1, pos2);

                if (fileName === null) {
                    fileName = "archivexxxxxxxxxxxxxx.zip";
                }

                console.log("fileName:" + fileName);

                var blob = xmlHttp.response;
                url = URL.createObjectURL(blob);

                var a = document.createElement('a');
                a.style = "display: none";
                a.href = url;
                a.download = fileName;
                a.type = type;
                document.body.appendChild(a);
                a.click();
                //a.delete();

                deblock_UI();

            } else {

                var msg =" Une erreur "  + xmlHttp.status +" est apparue pendant que votre demande était traitée.\n"

                msg = msg + "Merci de réessayer plus tard!";

                alert.innerHTML = msg;
                alert.style.display = "block";

                deblock_UI();
                console.log(msg);
            }
        }
    };
    xmlHttp.send();
}