Как сделать обратный вызов JQuery после отправки формы?


119

У меня простая форма с remote = true.

Эта форма фактически находится в диалоговом окне HTML, которое закрывается при нажатии кнопки «Отправить».

Теперь мне нужно внести некоторые изменения на главную HTML-страницу после успешной отправки формы.

Я пробовал это с помощью jQuery. Но это не гарантирует, что задачи будут выполнены после некоторой формы ответа на отправку формы.

$("#myform").submit(function(event) {

// do the task here ..

});

Как прикрепить обратный вызов, чтобы мой код выполнялся только после успешной отправки формы? Есть ли способ добавить в форму обратный вызов .success или .complete?


Почему вы не используете Ajax? С помощью функций jQuery Ajax вы можете определять такие обратные вызовы.
davidbuzatto

12
davidbuzatto, бывают случаи, когда вы не можете использовать ajax. Например, если вы хотите загрузить файл.
Pere

3
@Pere Неправда здесь в будущем.
SparK

Ответы:


119

Я только что сделал это -

 $("#myform").bind('ajax:complete', function() {

         // tasks to do 


   });

И все сработало отлично.

См. Эту документацию по api для получения более подробной информации.


3
Вау ... Я только что узнал кое-что новое. Да, судя по всему, это самое простое решение. Пожалуй, даже лучший. Я заядлый читатель Coding Horror, и в этом блоге Джефф Аттвуд подчеркивает, что мы должны писать меньше кода, и этот метод достигает этого. Хорошая находка. :)
Sal

7
А если <form>присылается обычно? (Я имею в виду не с Ajax) Что я могу указать в качестве первого аргумента .bind()? РЕДАКТИРОВАТЬ: ну, я думаю click. Nvm, извините. : p
4wk_ 04

9
будьте осторожны: это приведет к срабатыванию вашей функции после завершения любого события ajax, а не только вашей отправки формы (если я не ошибаюсь, и в этом случае я бы хотел, чтобы вы предоставили ссылку, где вы это нашли)
DMac The Destroyer

18
«Начиная с jQuery 1.8, метод .ajaxComplete () должен быть прикреплен только к документу»
Мередит

6
У меня не получилось, используя обычную форму, с кнопкой, но кнопка вызывает javascript $ ('# formFile'). Submit ();
Даниэль

35

Я не мог заставить решение номер один работать надежно, но нашел, что это работает. Не уверен, требуется это или нет, но у меня нет атрибута действия или метода в теге, который гарантирует, что POST обрабатывается функцией $ .ajax, и дает вам возможность обратного вызова.

<form id="form">
...
<button type="submit"></button>
</form>

<script>
$(document).ready(function() {
  $("#form_selector").submit(function() {

    $.ajax({
     type: "POST",
      url: "form_handler.php",
      data: $(this).serialize(),
      success: function() {
        // callback code here
       }
    })

  })
})
</script>

1
+1. Ключ к этому ответу - $(this).serialize()линия. Он позволяет использовать jQuery.ajax()для отправки существующей формы в фоновом режиме, затем перехватывать ответ от сервера и что-то с ним делать.
Уоррен Янг,

15
javascript без точек с запятой ... некоторые люди просто хотят смотреть, как мир горит. Ваше решение работает, поэтому спасибо :)
viggity

2
Обратите внимание, что .serializeне включает файловые входы в ваш запрос POSTed. Вместо этого используйте HTML5 FormData (см. Этот вопрос ), если вы не поддерживаете старые браузеры, такие как IE <9
brichins

Реквизит для использования $(this).serialize(), это решило мои проблемы!
gnclmorais

что такое form_selector в вашем html, на который вы ссылаетесь в js?
Кевин Мередит

23

Вам придется делать что-то вручную с помощью AJAX-вызова сервера. Это также потребует от вас переопределения формы.

Но не волнуйтесь, это проще простого. Вот обзор того, как вы будете работать с формой:

  • переопределить действие отправки по умолчанию (благодаря переданному объекту события, у которого есть preventDefaultметод)
  • взять все необходимые значения из формы
  • запустить HTTP-запрос
  • обработать ответ на запрос

Во-первых, вам нужно отменить действие отправки формы следующим образом:

$("#myform").submit(function(event) {
    // Cancels the form's submit action.
    event.preventDefault();
});

А затем возьмите значение данных. Предположим, у вас есть одно текстовое поле.

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();
});

А затем отправьте запрос. Давайте просто предположим, что это запрос POST.

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();

    // I like to use defers :)
    deferred = $.post("http://somewhere.com", { val: val });

    deferred.success(function () {
        // Do your stuff.
    });

    deferred.error(function () {
        // Handle any errors here.
    });
});

И это должно обойтись.

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

Примечание 2: вам не нужно использовать отсрочки. Это просто личное предпочтение. Вы также можете сделать следующее, и это тоже должно сработать.

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});

2
Отличный образец. Как сделать то же самое с загрузкой файла (multi-part / form-data) ???
Adam W

11

Для MVC здесь был еще более простой подход. Вам нужно использовать форму Ajax и установить AjaxOptions

@using (Ajax.BeginForm("UploadTrainingMedia", "CreateTest", new AjaxOptions() { HttpMethod = "POST", OnComplete = "displayUploadMediaMsg" }, new { enctype = "multipart/form-data", id = "frmUploadTrainingMedia" }))
{ 
  ... html for form
}

вот код отправки, он находится в разделе готовности документа и связывает событие onclick кнопки с отправкой формы

$("#btnSubmitFileUpload").click(function(e){
        e.preventDefault();
        $("#frmUploadTrainingMedia").submit();
});

вот обратный вызов, указанный в AjaxOptions

function displayUploadMediaMsg(d){
    var rslt = $.parseJSON(d.responseText);
    if (rslt.statusCode == 200){
        $().toastmessage("showSuccessToast", rslt.status);
    }
    else{
        $().toastmessage("showErrorToast", rslt.status);
    }
}

в методе контроллера для MVC это выглядит так

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult UploadTrainingMedia(IEnumerable<HttpPostedFileBase> files)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            // there is only one file  ... do something with it
        }
        return Json(new
        {
            statusCode = 200,
            status = "File uploaded",
            file = "",
        }, "text/html");
    }
    else
    {
        return Json(new
        {
            statusCode = 400,
            status = "Unable to upload file",
            file = "",
        }, "text/html");
    }
}

2
Эти коды являются кодами .Net, и в вопросе он никогда не указывался.
MrMins 01

13
Это действительно не повод для отрицательного голосования. Ответ работает и может помочь разработчику .NET, который сталкивается с той же проблемой.
edepperson 02

Мне нравится эта идея, но по какой-то причине обратный вызов не срабатывает. Должен ли метод контроллера возвращать JsonResult? Мой метод контроллера в настоящее время возвращает ActionResult.
mattpm

7

Я не верю, что существует функция обратного вызова, подобная описанной вами.

Что здесь нормально, так это делать изменения на каком-нибудь серверном языке, например PHP.

В PHP вы можете, например, получить скрытое поле из формы и внести некоторые изменения, если оно есть.

PHP:

  $someHiddenVar = $_POST["hidden_field"];
    if (!empty($someHiddenVar)) {
        // do something 
    }

Один из способов сделать это в JQuery - использовать Ajax. Вы можете прослушать отправку, вернуть false, чтобы отменить поведение по умолчанию, и вместо этого использовать jQuery.post (). jQuery.post имеет успешный обратный вызов.

$.post("test.php", $("#testform").serialize(), function(data) {
  $('.result').html(data);
});

http://api.jquery.com/jQuery.post/


0

Обработчики формы «при отправке» вызываются перед отправкой формы. Я не знаю, есть ли обработчик, который нужно вызвать после отправки формы. В традиционном смысле, отличном от Javascript, при отправке формы страница перезагружается.


Если при отправке формы не выполняется перенаправление на загрузку файла, в этом случае страница остается нетронутой. Я не могу использовать отправку JavaScript, потому что запрос Ajax не может инициировать загрузку файла (без игр с якорными тегами), но я также не могу сказать пользователю, чтобы он подождал или очистил, когда у него есть файл ...
kitsu .eb

-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });

3
Является ajaxForm()компонентом третьей стороной вы установили? Это не стандартная часть jQuery.
Уоррен Янг,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.