Как продолжить отправку формы после вызова AJAX? - PullRequest
3 голосов
/ 17 февраля 2012

Я хочу проверить пользовательские записи в сообщении WordPress после нажатия кнопки «Отправить», отобразить сообщение об ошибке, если есть проблемы, и отправить форму, если все в порядке.У меня есть функция PHP, которая выполняет проверку, возвращая true, если данные в form_data в порядке, в противном случае код ошибки.Следующий JavaScript выполняет запрос AJAX и должен был продолжить отправку формы после успешной проверки, но это не так:

        jQuery(document).ready(function() {
            jQuery('#post').submit(function() {

                var form_data = jQuery('#post').serializeArray();
                var data = {
                    action: 'ep_pre_submit_validation',
                    security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
                    form_data: jQuery.param(form_data),
                };
                var proceed = false;
                jQuery.post(ajaxurl, data, function(response) {
                    if (response.indexOf('true') > -1 || response == true) {
                        proceed = true;
                    } else {
                        alert("Error: " + response);
                        proceed = false;
                    }
                });
                jQuery('#ajax-loading').hide();
                jQuery('#publish').removeClass('button-primary-disabled');
                return proceed; //breakpoint here makes the code run
            });
        });

Код адаптирован из WPSE вопроса ,который изначально не работал для меня, так как форма не была отправлена.Я обнаружил, что если функция jQuery, связанная с .submit(), возвращает true, форма должна быть отправлена, поэтому я попытался реализовать ее.С приведенным выше кодом, кажется, сначала не работает (форма не отправляется, когда нет ошибок), но при тщательном рассмотрении с Firebug proceed, кажется, дает правильный результат, если точка останова вставлена ​​вreturn proceed строка.Он работает, как и предполагалось, с действительными данными только , если я немного подожду после достижения точки останова, а затем продолжу выполнение.Если есть ошибки, предупреждение выдается без проблем.

Каков наилучший способ справиться с этим?

РЕДАКТИРОВАТЬ

Основываясь на ответе @Linus ниже, следующий код работает как с действительными, так и с недействительными данными:

        jQuery(document).ready(function() {
            jQuery('#post').submit(function() {
                if(jQuery(this).data("valid")) {
                    return true;
                }

                var form_data = jQuery('#post').serializeArray();
                var data = {
                    action: 'ep_pre_submit_validation',
                    security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
                    form_data: jQuery.param(form_data),
                };
                jQuery.post(ajaxurl, data, function(response) {
                    if (response.indexOf('true') > -1 || response == true) {
                        jQuery("#post").data("valid", true).submit();
                    } else {
                        alert("Error: " + response);
                        jQuery("#post").data("valid", false);

                    }
                    //hide loading icon, return Publish button to normal
                    jQuery('#ajax-loading').hide();
                    jQuery('#publish').removeClass('button-primary-disabled');
                });
                return false;
            });
        });

Ответы [ 4 ]

6 голосов
/ 17 февраля 2012

Краткий ответ: Вы не можете - не таким образом.

Некоторые предыстории: обратные вызовы, которые вы предоставляете в качестве аргументов для таких функций, как $.post, выполняются асинхронно. Это означает, что вы будете return proceed до вашего успешного обратного вызова, и proceed всегда будет false. С вашей точкой останова, если вы дождетесь успешного завершения обратного вызова, proceed будет true, и все будет хорошо.

Итак, если вы хотите отправить форму после того, как ваш ajax-запрос завершится, вы должны отправить ее, используя javascript. Это довольно просто с jQuery, просто сделайте jQuery $.post с data: $("yourForm").serialize() и url: yourForm.action.

Это в основном то, что вы уже делаете, вам просто нужно повторить этот вызов на URL, по которому вы действительно хотите опубликовать данные.

EDIT:

Другим способом было бы установить атрибут в вашей форме, скажем, valid, а в обработчике submit проверить, что:

jQuery("#post").submit(function() {
    if($(this).data("valid")) {
        return true;
    }
    // Rest of your code
});

И при успешном обратном вызове для вашего ajax-запроса проверки вы устанавливаете / очищаете этот атрибут и затем отправляете:

$("#post").data("valid", true).submit();

EDIT:

Вы также хотите, чтобы ваша / ajax-loading / кнопка включалась внутри функции обратного вызова для $.post по тем же причинам, указанным выше - поскольку они произойдут немедленно, до того, как ваш вызов ajax вернется.

6 голосов
/ 17 февраля 2012

Свяжите свою кнопку с функцией проверки вместо отправки. Если он проходит проверку, вызовите submit ().

2 голосов
/ 24 октября 2012

Wordpress имеет собственный механизм обработки запросов Ajax, используя wp-admin / wp-ajax.php.Это позволяет вам запускать произвольный код с любой стороны границы Ajax без необходимости писать код проверки состояния вперед и назад и все такое.Настройте свои обратные вызовы и вперед ....

1 голос
/ 17 февраля 2012

Реальный вопрос - почему вы делаете проверку на стороне сервера?Почему вы не можете загрузить критерии проверки раньше - когда пишется сообщение?Тогда ваша проверка может выполняться в режиме реального времени, а не при отправке.

jquery.post выполняется асинхронно, что означает, что JS продолжит работу, прежде чем получит ответ.Вы застряли с ответом Диодея - привяжите кнопку к проверке, которая затем отправляет форму (что ухудшает ее качество), или измените ваш $ .post на ajax и отключите асинхронность, что заставит его ждать ответа, прежде чем продолжить... возможно блокирование JS на вашей странице до истечения времени ожидания.

$.ajax({
    type: 'POST',
    url: ajaxurl,
    async:false,
    data: data,
    timeout:3000,
    success: function(){

    }
});
...