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?

Nathan H
fonte

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 .

jspcal
fonte
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ê.

Alfrekjv
fonte
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>
Davide Icardi
fonte
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();
});
superluminário
fonte
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 .

macio.Jun
fonte
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
}
Timo Huovinen
fonte
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)
        {


        }
    });        
});
Shaiful Islam
fonte
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 .

BruceHill
fonte
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.

Tarion
fonte
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?

jeet singh parmar
fonte
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();
    });
test30
fonte
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"));
Alain Cruz
fonte
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) {
  ....
Pavel Zheliba
fonte
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 ...
Chris Halcrow
fonte
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/

suresh raj
fonte
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);
        }
    }
});
wonsuc
fonte
2

Tentar

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

Kamil Kiełczewski
fonte
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;
});
Lucas Bustamante
fonte
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>
Marty
fonte
-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

billw
fonte
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