jQuery AJAX enviar formulário


939

Eu tenho um formulário com nome orderproductForme um número indefinido de entradas.

Eu quero fazer algum tipo de jQuery.get ou ajax ou qualquer coisa assim que chamaria uma página através do Ajax e enviar todas as entradas do formulário orderproductForm.

Suponho que uma maneira seria fazer algo como

jQuery.get("myurl",
          {action : document.orderproductForm.action.value,
           cartproductid : document.orderproductForm.cartproductid.value,
           productid : document.orderproductForm.productid.value,
           ...

No entanto, eu não sei exatamente todas as entradas do formulário. Existe um recurso, função ou algo que enviaria TODAS as entradas do formulário?

Respostas:


814

Você pode usar as funções ajaxForm / ajaxSubmit do Ajax Form Plugin ou a função de serialização do jQuery.

AjaxForm :

$("#theForm").ajaxForm({url: 'server.php', type: 'post'})

ou

$("#theForm").ajaxSubmit({url: 'server.php', type: 'post'})

o ajaxForm será enviado quando o botão enviar for pressionado. o ajaxSubmit envia imediatamente.

Serializar :

$.get('server.php?' + $('#theForm').serialize())

$.post('server.php', $('#theForm').serialize())

A documentação de serialização AJAX está aqui .


2
idéia interessante, no entanto, eu não controlar o lado do servidor que estou chamando, portanto, não posso enviá-lo serializado dados
Nathan H

25
Sim, você pode, o nome não é importante, o que ele fará é enviar pares de cada chave de formulário e cada variável de formulário.

6
É serializado em uma string de consulta, exatamente como os dados que você está colocando na matriz manualmente na chamada GET. É isso que você quer, tenho certeza.
JAL

1
oooh Entendo, então adiciono essa string ao final do URL na chamada get. Eu estava pensando PHP serializar. Desculpa. Obrigado!
Nathan H

238
.ajaxSubmit()/ .ajaxForm()não são funções básicas do jQuery - você precisa do plugin jQuery Form
Yarin

1401

Esta é uma referência simples:

// this is the id of the form
$("#idForm").submit(function(e) {

    e.preventDefault(); // avoid to execute the actual submit of the form.

    var form = $(this);
    var url = form.attr('action');

    $.ajax({
           type: "POST",
           url: url,
           data: form.serialize(), // serializes the form's elements.
           success: function(data)
           {
               alert(data); // show response from the php script.
           }
         });


});

Espero que ajude você.


46
Mas form.serialize () não pode postar <input type = "file"> no IE
macio.Julho

2
Ótima resposta para envio normal de formulários!
The Sheek Geek

1
Semelhante a @ BjørnBørresen, você também pode usar type: $(this).attr('method')se usar o methodatributo no seu formulário.
djule5

2
Vale a pena mencionar que desde o jQuery 1.8, .success, .error e .complete estão obsoletos em favor de .done, .fail e .sempre.
Adam

2
@ Comentário de JohnKary - ótimo artigo, parece que não está mais disponível. Aqui está um arquivo de jQuery Eventos: Stop (Mis) Usando retornar falso
KyleMit

455

Outra solução semelhante usando atributos definidos no elemento do formulário:

<form id="contactForm1" action="/your_url" method="post">
    <!-- Form input fields here (do not forget your name attributes). -->
</form>

<script type="text/javascript">
    var frm = $('#contactForm1');

    frm.submit(function (e) {

        e.preventDefault();

        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                console.log('Submission was successful.');
                console.log(data);
            },
            error: function (data) {
                console.log('An error occurred.');
                console.log(data);
            },
        });
    });
</script>

Alguma sugestão sobre como fazer isso se o atributo name incluir um "."? (Requisito do lado do servidor, não é minha ideia).
Josef Engelfrost 29/11

Inclua um retorno de chamada de erro para fazer isso. Nunca se sabe quando ocorrerá um erro, deve sempre ser responsável por isso.
codificação aaron

1
Se você não definir método ou ação, eles serão padronizados como gete o URL atual, respectivamente. Poderia fazer com a adição desta suposição ao código.
precisa saber é o seguinte

1
Por documentação do jQuery ( api.jquery.com/submit ), frm.submit (function (evento) {..}); é equivalente a frm.on ("submit", function (event) {..}) ;. Para mim, o último é mais legível, pois é óbvio que você está anexando um manipulador de eventos a um elemento a ser executado quando o evento é acionado.
mehmet

177

Há algumas coisas que você precisa ter em mente.

1. Existem várias maneiras de enviar um formulário

  • usando o botão enviar
  • pressionando enter
  • acionando um evento de envio em JavaScript
  • possivelmente mais dependendo do dispositivo ou dispositivo futuro.

Portanto, devemos vincular ao evento de envio de formulário , não ao evento de clique no botão. Isso garantirá que nosso código funcione em todos os dispositivos e tecnologias assistivas agora e no futuro.

2. Hijax

O usuário pode não ter o JavaScript ativado. Um padrão hijax é bom aqui, onde assumimos o controle suavemente do formulário usando JavaScript, mas o deixamos submissível se o JavaScript falhar.

Devemos extrair o URL e o método do formulário, portanto, se o HTML mudar, não precisaremos atualizar o JavaScript.

3. JavaScript Discreto

Usar event.preventDefault () em vez de return false é uma boa prática, pois permite que o evento borbulhe . Isso permite que outros scripts se vinculem ao evento, por exemplo, scripts de análise que podem estar monitorando as interações do usuário.

Rapidez

Idealmente, devemos usar um script externo, em vez de inserir nosso script embutido. Podemos criar um link para isso na seção de cabeçalho da página usando uma tag de script ou um link para ele na parte inferior da página, para acelerar. O script deve melhorar silenciosamente a experiência do usuário, não atrapalhar.

Código

Supondo que você concorda com todas as opções acima, e deseja capturar o evento de envio e manipulá-lo via AJAX (um padrão de hijax), você pode fazer algo assim:

$(function() {
  $('form.my_form').submit(function(event) {
    event.preventDefault(); // Prevent the form from submitting via the browser
    var form = $(this);
    $.ajax({
      type: form.attr('method'),
      url: form.attr('action'),
      data: form.serialize()
    }).done(function(data) {
      // Optionally alert the user of success here...
    }).fail(function(data) {
      // Optionally alert the user of an error here...
    });
  });
});

Você pode acionar manualmente o envio de um formulário sempre que quiser via JavaScript usando algo como:

$(function() {
  $('form.my_form').trigger('submit');
});

Editar:

Recentemente, tive que fazer isso e acabei escrevendo um plugin.

(function($) {
  $.fn.autosubmit = function() {
    this.submit(function(event) {
      event.preventDefault();
      var form = $(this);
      $.ajax({
        type: form.attr('method'),
        url: form.attr('action'),
        data: form.serialize()
      }).done(function(data) {
        // Optionally alert the user of success here...
      }).fail(function(data) {
        // Optionally alert the user of an error here...
      });
    });
    return this;
  }
})(jQuery)

Adicione um atributo data-autosubmit à sua tag de formulário e você poderá fazer o seguinte:

HTML

<form action="/blah" method="post" data-autosubmit>
  <!-- Form goes here -->
</form>

JS

$(function() {
  $('form[data-autosubmit]').autosubmit();
});

2
como posso adicionar os retornos de chamada às funções 'concluído' e 'falhar'? .. algo como $ ( 'forma [dados-autosubmit])', autosubmit () feito (function ({...}); Isso é possível?
Crusader

1
Oi @Crusader - certamente, em vez de fazer com que este plugin retorne isso, você pode fazer com que ele retorne o evento ajax e, em seguida, encadeie diretamente nele. Como alternativa, o plugin pode receber um retorno de chamada bem-sucedido.
superluminary

Não vejo como isso ".. deixa submissível se o JavaScript falhar" acontecer aqui?
mehmet

@matmat - Se o JavaScript estiver desativado, o formulário ainda será apenas um formulário. O usuário clica em enviar e ocorre um envio regular de formulário com base no navegador. Chamamos isso de aprimoramento progressivo. Hoje em dia, não é grande coisa, já que os leitores de tela modernos suportam JavaScript.
superluminary

@matmat - opcionalmente, os retornos de chamada prometidos receberão um parâmetro que contém os dados.
superluminary

41

Você também pode usar FormData (mas não disponível no IE):

var formData = new FormData(document.getElementsByName('yourForm')[0]);// yourForm: form selector        
$.ajax({
    type: "POST",
    url: "yourURL",// where you wanna post
    data: formData,
    processData: false,
    contentType: false,
    error: function(jqXHR, textStatus, errorMessage) {
        console.log(errorMessage); // Optional
    },
    success: function(data) {console.log(data)} 
});

É assim que você usa FormData .


8
Vejo que FormData agora é suportado pelo IE10. Dentro de alguns anos, essa será a solução preferida.
superluminar

3
Que vantagem dessa maneira?
insira

1
A vantagem do @insign é que nenhum plugin é necessário e funciona em muitos navegadores modernos.
KhoPhi 29/05

4
@insign FormData também pode manipular arquivos (se houver um desses campos no formulário), enquanto serialize () apenas os ignora.
mehmet

TypeError não detectado: falha ao construir 'FormData': o parâmetro 1 não é do tipo 'HTMLFormElement'
rahim.nagori 26/03

28

Versão simples (não envia imagens)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>

Copie e cole ajaxificação de um formulário ou de todos os formulários em uma página

É uma versão modificada da resposta de Alfrekjv

  • Funcionará com jQuery> = 1.3.2
  • Você pode executar isso antes que o documento esteja pronto
  • Você pode remover e adicionar novamente o formulário e ele ainda funcionará
  • Ele será lançado no mesmo local que o formulário normal, especificado no atributo "action" do formulário

Javascript

jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

Eu queria editar a resposta de Alfrekjv, mas me desviei muito dela e decidi postar isso como uma resposta separada.

Não envia arquivos, não suporta botões; por exemplo, clicar em um botão (incluindo um botão de envio) envia seu valor como dados do formulário, mas, por se tratar de uma solicitação ajax, o clique no botão não será enviado.

Para oferecer suporte aos botões, você pode capturar o clique real do botão em vez do envio.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});

No lado do servidor, você pode detectar uma solicitação ajax com este cabeçalho que o jquery defineHTTP_X_REQUESTED_WITH para php

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

Como isso funcionaria se você quisesse enviar um arquivo com este formulário?
precisa saber é o seguinte

1
@YamiMedina isso não é uma solução simples, você precisa enviar o pedido na totalidade em um formato diferente (formato multipart) com os dados do arquivo
Timo Huovinen

22

Esse código funciona mesmo com entrada de arquivo

$(document).on("submit", "form", function(event)
{
    event.preventDefault();        
    $.ajax({
        url: $(this).attr("action"),
        type: $(this).attr("method"),
        dataType: "JSON",
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        },
        error: function (xhr, desc, err)
        {


        }
    });        
});

3
Apenas a nota FormData () é IE10 + developer.mozilla.org/en-US/docs/Web/API/FormData
Chris Hopkins

1
O tipo de dados: 'json' é importante se você quiser usar Form.serialize ()
David Morrow

uau, este FormData é maravilhoso! no precisa de alguém de caso: Array.from(new FormData(form))itera sobre este iterador FormData :)
test30

13

Eu realmente gostei desta resposta do superluminário e, especialmente, a maneira como ele envolveu a solução em um plugin jQuery . Então, obrigado ao superluminário por uma resposta muito útil. No meu caso, porém, eu queria um plug-in que me permitisse definir os manipuladores de eventos de sucesso e erro por meio de opções quando o plug-in for inicializado.

Então, aqui está o que eu vim com:

;(function(defaults, $, undefined) {
    var getSubmitHandler = function(onsubmit, success, error) {
        return function(event) {
            if (typeof onsubmit === 'function') {
                onsubmit.call(this, event);
            }
            var form = $(this);
            $.ajax({
                type: form.attr('method'),
                url: form.attr('action'),
                data: form.serialize()
            }).done(function() {
                if (typeof success === 'function') {
                    success.apply(this, arguments);
                }
            }).fail(function() {
                if (typeof error === 'function') {
                    error.apply(this, arguments);
                }
            });
            event.preventDefault();
        };
    };
    $.fn.extend({
        // Usage:
        // jQuery(selector).ajaxForm({ 
        //                              onsubmit:function() {},
        //                              success:function() {}, 
        //                              error: function() {} 
        //                           });
        ajaxForm : function(options) {
            options = $.extend({}, defaults, options);
            return $(this).each(function() {
                $(this).submit(getSubmitHandler(options['onsubmit'], options['success'], options['error']));
            });
        }
    });
})({}, jQuery);

Esse plug-in permite que eu facilmente "ajaxifique" formulários html na página e forneça manipuladores de submissão , sucesso e erro para implementar feedback ao usuário sobre o status do envio do formulário. Isso permitiu que o plugin fosse usado da seguinte maneira:

 $('form').ajaxForm({
      onsubmit: function(event) {
          // User submitted the form
      },
      success: function(data, textStatus, jqXHR) {
          // The form was successfully submitted
      },
      error: function(jqXHR, textStatus, errorThrown) {
          // The submit action failed
      }
 });

Observe que os manipuladores de eventos de sucesso e erro recebem os mesmos argumentos que você receberia dos eventos correspondentes do método jQuery ajax .


9

Eu tenho o seguinte para mim:

formSubmit('#login-form', '/api/user/login', '/members/');

Onde

function formSubmit(form, url, target) {
    $(form).submit(function(event) {
        $.post(url, $(form).serialize())
            .done(function(res) {
                if (res.success) {
                    window.location = target;
                }
                else {
                    alert(res.error);
                }
            })
            .fail(function(res) {
                alert("Server Error: " + res.status + " " + res.statusText);

            })
        event.preventDefault();
    });
}

Isso pressupõe que a postagem para 'url' retorne um ajax na forma de {success: false, error:'my Error to display'}

Você pode variar isso como quiser. Sinta-se livre para usar esse trecho.


1
Para que serve targetaqui? Por que você enviaria um formulário com o AJAX, apenas para redirecionar para uma nova página?
1252748

9

jQuery AJAX enviar formulário , nada mais é do que enviar um formulário usando o ID do formulário quando você clica em um botão

Siga os passos

Etapa 1 - a tag do formulário deve ter um campo de ID

<form method="post" class="form-horizontal" action="test/user/add" id="submitForm">
.....
</form>

Botão no qual você clicará

<button>Save</button>

Etapa 2 - o evento de envio está no jQuery, o que ajuda a enviar um formulário. no código abaixo, estamos preparando a solicitação JSON a partir do nome do elemento HTML .

$("#submitForm").submit(function(e) {
    e.preventDefault();
    var frm = $("#submitForm");
    var data = {};
    $.each(this, function(i, v){
        var input = $(v);
        data[input.attr("name")] = input.val();
        delete data["undefined"];
    });
    $.ajax({
        contentType:"application/json; charset=utf-8",
        type:frm.attr("method"),
        url:frm.attr("action"),
        dataType:'json',
        data:JSON.stringify(data),
        success:function(data) {
            alert(data.message);
        }
    });
});

para demonstração ao vivo, clique no link abaixo

Como enviar um formulário usando o jQuery AJAX?


5

considere usar closest

$('table+table form').closest('tr').filter(':not(:last-child)').submit(function (ev, frm) {
        frm = $(ev.target).closest('form');
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                alert(data);
            }
        })
        ev.preventDefault();
    });

5

Eu sei que essa é uma jQuerypergunta relacionada, mas agora os dias com o JS ES6 são muito mais fáceis. Como não há uma javascriptresposta pura , pensei em adicionar uma javascriptsolução pura e simples para isso, que na minha opinião é muito mais limpa, usando a fetch()API. Essa é uma maneira moderna de implementar solicitações de rede. No seu caso, como você já possui um elemento de formulário, podemos simplesmente usá-lo para criar nossa solicitação.

const form = document.forms["orderproductForm"];
const formInputs = form.getElementsByTagName("input"); 
let formData = new FormData(); 
for (let input of formInputs) {
    formData.append(input.name, input.value); 
}

fetch(form.action,
    {
        method: form.method,
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.log(error.message))
    .finally(() => console.log("Done"));

4

Para evitar vários envios de dados do formulário:

Não se esqueça de desvincular o evento de envio, antes que o formulário seja enviado novamente, o usuário pode chamar a função sumbit mais de uma vez, talvez ele tenha esquecido algo ou tenha sido um erro de validação.

 $("#idForm").unbind().submit( function(e) {
  ....

4

Se você estiver usando o formulário .serialize () - precisará dar a cada elemento do formulário um nome como este:

<input id="firstName" name="firstName" ...

E o formulário é serializado assim:

firstName=Chris&lastName=Halcrow ...

4

Você pode usar isso na função de envio como abaixo.

Formulário HTML

<form class="form" action="" method="post">
    <input type="text" name="name" id="name" >
    <textarea name="text" id="message" placeholder="Write something to us"> </textarea>
    <input type="button" onclick="return formSubmit();" value="Send">
</form>

Função jQuery:

<script>
    function formSubmit(){
        var name = document.getElementById("name").value;
        var message = document.getElementById("message").value;
        var dataString = 'name='+ name + '&message=' + message;
        jQuery.ajax({
            url: "submit.php",
            data: dataString,
            type: "POST",
            success: function(data){
                $("#myForm").html(data);
            },
            error: function (){}
        });
    return true;
    }
</script>

Para obter mais detalhes e amostra, visite: http://www.spiderscode.com/simple-ajax-contact-form/


2

Esta não é a resposta para a pergunta do OP,
mas , se você não puder usar o formulário estático DOM, também poderá tentar assim.

var $form = $('<form/>').append(
    $('<input/>', {name: 'username'}).val('John Doe'),
    $('<input/>', {name: 'user_id'}).val('john.1234')
);

$.ajax({
    url: 'api/user/search',
    type: 'POST',
    contentType: 'application/x-www-form-urlencoded',
    data: $form.serialize(),
    success: function(data, textStatus, jqXHR) {
        console.info(data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        var errorMessage = jqXHR.responseText;
        if (errorMessage.length > 0) {
            alert(errorMessage);
        }
    }
});

2

Tentar

fetch(form.action,{method:'post', body: new FormData(form)});


1

Apenas um lembrete amigável que também datapode ser um objeto:

$('form#foo').submit(function () {
    $.ajax({
        url: 'http://foo.bar/some-ajax-script',
        type: 'POST',
        dataType: 'json',
        data: {
            'foo': 'some-foo',
            'bar': 'some-bar'
        }
    }).always(function (data) {
        console.log(data);
    });

    return false;
});

1

Javascript

(function ($) {
    var form= $('#add-form'),
      input = $('#exampleFormControlTextarea1');


   form.submit(function(event) {

       event.preventDefault(); 

       var req = $.ajax({
           url: form.attr('action'),
           type: 'POST',
           data: form.serialize()
       });
    req.done(function(data) {
       if (data === 'success') {
           var li = $('<li class="list-group-item">'+ input.val() +'</li>');
            li.hide()
                .appendTo('.list-group')
                .fadeIn();
            $('input[type="text"],textarea').val('');
        }
   });
});


}(jQuery));

HTML

    <ul class="list-group col-sm-6 float-left">
            <?php
            foreach ($data as $item) {
                echo '<li class="list-group-item">'.$item.'</li>';
            }
            ?>
        </ul>

        <form id="add-form" class="col-sm-6 float-right" action="_inc/add-new.php" method="post">
            <p class="form-group">
                <textarea class="form-control" name="message" id="exampleFormControlTextarea1" rows="3" placeholder="Is there something new?"></textarea>
            </p>
            <button type="submit" class="btn btn-danger">Add new item</button>
        </form>

-21

Há também o evento de envio, que pode ser acionado como este $ ("# form_id"). Submit (). Você usaria esse método se o formulário já estiver bem representado em HTML. Você acabou de ler a página, preencher as entradas do formulário com as coisas e chamar .submit (). Ele usará o método e a ação definidos na declaração do formulário, para que você não precise copiá-lo para o seu javascript.

exemplos


58
se você excluir sua postagem, receberá os pontos de penalidade que foram retirados de você.
sparkyspider

2
Isso enviará o formulário, mas não via AJAX, portanto não responde à pergunta.
superluminar

11
o que @spider disse, além de obter um crachá agradável chamada "pressão dos pares"
nurettin
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.