Como fazer um retorno de chamada Jquery após o envio do formulário?

119

Eu tenho um formulário simples com remote = true.

Na verdade, este formulário está em uma caixa de diálogo HTML, que é fechada assim que o botão Enviar é clicado.

Agora, preciso fazer algumas alterações na página HTML principal após o envio do formulário com êxito.

Eu tentei isso usando jQuery. Mas isso não garante que as tarefas sejam executadas após alguma forma de resposta do envio do formulário.

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

// do the task here ..

});

Como anexar um retorno de chamada, para que meu código seja executado somente após o envio do formulário com êxito? Existe alguma maneira de adicionar algum retorno de chamada .success ou .complete ao formulário?

geeky_monster
fonte
Por que você não usa o Ajax? Com as funções do jQuery Ajax, você pode definir esses retornos de chamada.
Davidbuzatto
12
davidbuzatto, existem alguns casos em que você não pode usar o ajax. Por exemplo, quando você deseja fazer upload de um arquivo.
Pere
3
@ Pere Não é verdade aqui no futuro.
SparK

Respostas:

119

Eu apenas fiz isso -

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

         // tasks to do 


   });

E as coisas funcionaram perfeitamente.

Consulte esta documentação da API para obter detalhes mais específicos.

geeky_monster
fonte
3
Uau ... Acabei de aprender algo novo. Sim, pelo que parece, esta é a solução mais simples. Talvez seja até o melhor. Sou um ávido leitor de Coding Horror e, nesse blog, Jeff Attwood enfatiza que devemos escrever menos código, e esse método consegue isso. Boa descoberta. :)
Sal
7
E se o <form>é enviado normalmente? (Quero dizer, não com o Ajax) O que posso colocar no primeiro argumento de .bind()? EDIT: bem, eu acho click. Nvm, desculpe. : p
4wk_
9
cuidado: isso disparará sua função após a conclusão de qualquer evento do ajax, não apenas o envio do formulário (a menos que eu esteja enganado; nesse caso, eu adoraria que você fornecesse um link para onde você o encontrou)
DMac the Destroyer
18
"A partir do jQuery 1.8, o método .ajaxComplete () deve ser anexado apenas ao documento"
Meredith
6
Não funcionou comigo, usando Form normal, com um botão, mas o botão chama javascript $ ('# formFile'). Submit ();
Daniel
35

Não consegui que a solução votada número um funcionasse de maneira confiável, mas achei que isso funciona. Não tenho certeza se é necessário ou não, mas não tenho um atributo de ação ou método na tag, o que garante que o POST seja tratado pela função $ .ajax e oferece a opção de retorno de chamada.

<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>
Bradley Bossard
fonte
1
+1. A chave para esta resposta é a $(this).serialize()linha. Ele permite jQuery.ajax()enviar o formulário existente em segundo plano, capturar a resposta do servidor e fazer algo com ele.
21814 Warren Young
15
javascript sem ponto e vírgula ... algumas pessoas só querem ver o mundo queimar. Sua solução funciona embora, por isso obrigado :)
viggity
2
Observe que .serializenão inclui entradas de arquivo na sua solicitação POST. Use o HTML5 FormData (ver esta questão ) em vez a menos que você está apoiando navegadores antigos como o IE <9
brichins
Adereços para uso $(this).serialize(), resolveu meus problemas!
Gnclmorais
o que é 'form_selector' em seu html que você faz referência nos js?
22616 Kevin Meredith
23

Você precisará fazer as coisas manualmente com uma chamada AJAX para o servidor. Isso exigirá que você substitua o formulário também.

Mas não se preocupe, é um pedaço de bolo. Aqui está uma visão geral de como você trabalhará com seu formulário:

  • substituir a ação de envio padrão (graças ao objeto de evento passado, que possui um preventDefaultmétodo)
  • pegue todos os valores necessários do formulário
  • disparar uma solicitação HTTP
  • lidar com a resposta à solicitação

Primeiro, você precisará cancelar a ação de envio do formulário da seguinte forma:

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

E então, pegue o valor dos dados. Vamos apenas assumir que você tem uma caixa de texto.

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

E, em seguida, dispare uma solicitação. Vamos apenas assumir que é uma solicitação 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.
    });
});

E isso deve fazê-lo.

Nota 2: para analisar os dados do formulário, é preferível usar um plug - in . Isso tornará sua vida muito fácil, além de fornecer uma boa semântica que imita uma ação de envio de formulário real.

Nota 2: Você não precisa usar adiadores. É apenas uma preferência pessoal. Você também pode fazer o seguinte e deve funcionar também.

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});
Sal
fonte
2
Ótima amostra. Como fazer a mesma coisa com o upload de arquivos (multi-part / form-data) ???
Adam W
11

Para o MVC, havia uma abordagem ainda mais fácil. Você precisa usar o formulário Ajax e definir o AjaxOptions

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

aqui está o código de envio, está na seção de documentos prontos e vincula o evento onclick do botão para enviar o formulário

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

aqui está o retorno de chamada mencionado em AjaxOptions

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

no método do controlador para MVC parece com isso

[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");
    }
}
edepperson
fonte
2
Esses códigos são códigos .Net e, na questão, nunca o especificaram.
MrMins
13
Isso realmente não é um bom motivo para votar a favor. A resposta funciona e pode ajudar um desenvolvedor .NET que está enfrentando o mesmo problema.
Edepperson
Eu gosto dessa ideia, mas por algum motivo o retorno de chamada não está disparando. O método do controlador precisa retornar um JsonResult? Meu método de controlador atualmente retorna um ActionResult.
mattpm
7

Não acredito que exista uma função de retorno de chamada como a que você descreve.

O que é normal aqui é fazer as alterações usando alguma linguagem do lado do servidor, como PHP.

No PHP, você pode, por exemplo, buscar um campo oculto no seu formulário e fazer algumas alterações, se houver.

PHP:

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

Uma maneira de fazer isso no Jquery é usar o Ajax. Você pode ouvir o envio, retornar false para cancelar seu comportamento padrão e usar o jQuery.post (). O jQuery.post possui um retorno de chamada bem-sucedido.

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

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

Sindre
fonte
0

Os manipuladores "ao enviar" do formulário são chamados antes do envio do formulário. Não sei se há um manipulador a ser chamado após o envio do formulário. No sentido tradicional não-Javascript, o envio do formulário recarregará a página.

enguia ghEEz
fonte
A menos que o envio do formulário seja redirecionado para um download de arquivo, nesse caso, a página permanece intacta. Não consigo usar o envio de JavaScript porque uma solicitação do Ajax não pode iniciar o download de um arquivo (sem jogos de tags de âncora), mas também não posso dizer ao usuário para aguardar ou limpar uma vez que ele tenha o arquivo ...
kitsu .eb 29/08/19
-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });
Aikanáro
fonte
3
Você ajaxForm()instalou um componente de terceiros? Não é uma parte padrão do jQuery.
21814 Warren Young