jQuery AJAX invia modulo


939

Ho un modulo con nome orderproductForme un numero indefinito di input.

Voglio fare una sorta di jQuery.get o ajax o qualcosa del genere che chiamerebbe una pagina tramite Ajax e invierebbe insieme tutti gli input del modulo orderproductForm.

Suppongo che un modo sarebbe quello di fare qualcosa del genere

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

Tuttavia non conosco esattamente tutti gli input del modulo. C'è una caratteristica, una funzione o qualcosa che invierebbe TUTTI gli input del modulo?

Risposte:


814

È possibile utilizzare le funzioni ajaxForm / ajaxSubmit dal plug -in Ajax Form o dalla funzione di serializzazione jQuery.

AjaxForm :

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

o

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

ajaxForm invierà quando viene premuto il pulsante di invio. ajaxSubmit invia immediatamente.

Serializzare :

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

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

La documentazione di serializzazione AJAX è qui .


2
idea interessante, tuttavia, non controllo il lato server che sto chiamando, quindi non riesco a inviarlo con dati serializzati
Nathan H,

25
Sì, il nome non è importante. Ciò che farà è inviare coppie di ogni chiave di modulo e ogni variabile di modulo.

6
È serializzato in una stringa di query, proprio come ci sarebbero i dati che si inseriscono manualmente nell'array nella chiamata GET. Questo è quello che vuoi, ne sono abbastanza sicuro.
JAL

1
oooh vedo, quindi aggiungo questa stringa alla fine dell'URL nella chiamata get. Stavo pensando di serializzare PHP. Scusate. Grazie!
Nathan H,

238
.ajaxSubmit()/ .ajaxForm()non sono le funzioni principali di jQuery- è necessario il plug
Yarin

1401

Questo è un semplice riferimento:

// 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.
           }
         });


});

Spero che ti aiuti.


46
Ma form.serialize () non può pubblicare <input type = "file"> in IE
macio.Jun

2
Ottima risposta per l'invio normale del modulo!
The Sheek Geek,

1
Simile a @ BjørnBørresen, puoi anche usarlo type: $(this).attr('method')se usi l' methodattributo nel tuo modulo.
djule5,

2
Vale la pena ricordare che da allora jQuery 1.8, .success, .error e .complete sono deprecati a favore di .done, .fail e .always.
Adam,

2
@ Commento di JohnKary - ottimo articolo, sembra che non sia più disponibile però. Ecco un archivio di eventi jQuery: Stop (Mis) utilizzando Return False
KyleMit

455

Un'altra soluzione simile che utilizza attributi definiti sull'elemento modulo:

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

Qualche suggerimento su come eseguire questa operazione se l'attributo name include un "."? (Requisito lato server, non la mia idea).
Josef Engelfrost,

Includere un errore callback a questo per completarlo. Non si sa mai quando si otterrà un errore, si dovrebbe sempre tenerne conto.
codifica in aaron

1
Se non imposti il ​​metodo o l'azione, vengono impostati getrispettivamente sull'URL corrente e sull'URL corrente. Potrebbe fare con l'aggiunta di questo presupposto al codice.
Rybo111,

1
Per la documentazione di jQuery ( api.jquery.com/submit ), frm.submit (funzione (evento) {..}); è equivalente a frm.on ("submit", funzione (evento) {..}) ;. Per me quest'ultimo è più leggibile in quanto è ovvio che si sta collegando un gestore eventi a un elemento da eseguire quando viene generato l'evento.
Mehmet,

177

Ci sono alcune cose che devi tenere a mente.

1. Esistono diversi modi per inviare un modulo

  • utilizzando il pulsante di invio
  • premendo invio
  • attivando un evento di invio in JavaScript
  • forse più a seconda del dispositivo o del dispositivo futuro.

Dovremmo quindi legarci all'evento di invio del modulo , non all'evento clic sul pulsante. Ciò garantirà che il nostro codice funzioni su tutti i dispositivi e le tecnologie di assistenza ora e in futuro.

2. Hijax

È possibile che JavaScript non sia abilitato per l'utente. Un hijax modello è buono qui, dove prendiamo delicatamente il controllo del modulo utilizzando JavaScript, ma lo lasciamo sottomettibile se JavaScript non riesce.

Dovremmo estrarre l'URL e il metodo dal modulo, quindi se l'HTML cambia, non è necessario aggiornare JavaScript.

3. JavaScript discreto

L'uso di event.preventDefault () invece di return false è una buona pratica in quanto consente all'evento di fare il bubble up. Ciò consente ad altri script di collegarsi all'evento, ad esempio script di analisi che potrebbero monitorare le interazioni dell'utente.

Velocità

Idealmente dovremmo utilizzare uno script esterno, anziché inserire il nostro script in linea. Possiamo collegarci a questo nella sezione head della pagina usando un tag script, o collegarlo ad esso nella parte inferiore della pagina per la velocità. Lo script dovrebbe migliorare silenziosamente l'esperienza dell'utente, non interferire.

Codice

Supponendo che tu sia d'accordo con tutto quanto sopra e desideri catturare l'evento di invio e gestirlo tramite AJAX (un modello hijax), potresti fare qualcosa del genere:

$(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...
    });
  });
});

Puoi attivare manualmente l'invio di un modulo ogni volta che vuoi tramite JavaScript usando qualcosa come:

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

Modificare:

Di recente ho dovuto farlo e ho finito per scrivere un 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)

Aggiungi un attributo data-autosubmit al tuo tag del modulo e puoi farlo:

HTML

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

JS

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

2
come posso aggiungere i callback alle funzioni 'done' e 'fail'? qualcosa come $ ('form [data-autosubmit]'). autosubmit (). done (funzione ({...}); questo è possibile?
Crusader

1
Ciao @Crusader - certamente, invece di fare in modo che questo plugin restituisca questo, potresti farlo restituire l'evento ajax, quindi puoi incatenarlo direttamente su di esso. In alternativa, il plug-in potrebbe ricevere un callback di successo.
superluminario,

Non vedo come questo ".. lo lasci sottomettibile se JavaScript non riesce" accade qui?
Mehmet,

@mmatt - Se JavaScript è disabilitato, il modulo è ancora solo un modulo. L'utente fa clic su Invia e si verifica un normale invio di moduli basato su browser. Chiamiamo questo miglioramento progressivo. Oggigiorno non è un grosso problema poiché i moderni screen reader supportano JavaScript.
superluminario,

@mmatt - I callback promettenti riceveranno facoltativamente un parametro che contiene i dati.
superluminario,

41

Puoi anche usare FormData (ma non disponibile in 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)} 
});

Ecco come si utilizza FormData .


8
Vedo che FormData è ora supportato da IE10. Tra qualche anno questa sarà la soluzione preferita.
superluminario,

3
Quale vantaggio di questo modo?
firma il

1
Il vantaggio di @insign è che non è richiesto alcun plug-in e funziona su molti browser moderni.
KhoPhi,

4
@insign FormData può gestire anche i file (se nel modulo è presente uno di questi campi) mentre serialize () lo ignora.
Mehmet,

Uncaught TypeError: impossibile costruire 'FormData': il parametro 1 non è di tipo 'HTMLFormElement'
rahim.nagori

28

Versione semplice (non invia immagini)

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

Copia e incolla ajaxification di un modulo o tutti i moduli su una pagina

È una versione modificata della risposta di Alfrekjv

  • Funzionerà con jQuery> = 1.3.2
  • Puoi eseguirlo prima che il documento sia pronto
  • Puoi rimuovere e aggiungere nuovamente il modulo e funzionerà comunque
  • Verrà pubblicato nella stessa posizione del modulo normale, specificato nell'attributo "azione" del modulo

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)
            }
        });
    }
});

Volevo modificare la risposta di Alfrekjv, ma mi sono allontanato troppo da essa, quindi ho deciso di pubblicare questa come una risposta separata.

Non invia file, non supporta pulsanti, ad esempio facendo clic su un pulsante (incluso un pulsante di invio) si invia il suo valore come dati del modulo, ma poiché si tratta di una richiesta Ajax, il clic sul pulsante non verrà inviato.

Per supportare i pulsanti è possibile acquisire il clic del pulsante effettivo anziché l'invio.

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);
            }
        });
    }
});

Sul lato server è possibile rilevare una richiesta Ajax con questa intestazione che jquery imposta HTTP_X_REQUESTED_WITH per php

PHP

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

Come funzionerebbe se DID volesse inviare un file con questo modulo?
Yami Medina,

1
@YamiMedina non è una soluzione semplice, devi inviare l'intera richiesta in un formato diverso (formato multipart) con i dati del file
Timo Huovinen,

22

Questo codice funziona anche con l'input di file

$(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
Solo per notare formData () è IE10 + developer.mozilla.org/en-US/docs/Web/API/FormData
Chris Hopkins,

1
il tipo di dati: 'json' è importante se si desidera utilizzare form.serialize ()
David Morrow,

wow, questo FormData è meraviglioso! nel caso qualcuno ne abbia bisogno: Array.from(new FormData(form))scorre su questo iteratore formdata :)
test30

13

Mi è davvero piaciuta questa risposta di Superluminary e soprattutto il modo in cui ha racchiuso la soluzione in un plugin jQuery . Quindi grazie al superluminario per una risposta molto utile. Nel mio caso, però, volevo un plugin che mi permettesse di definire il successo e l' errore gestori di eventi di mediante le opzioni quando il plug-in è inizializzato.

Quindi ecco cosa mi è venuto in mente:

;(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);

Questo plug-in mi permette di "ajaxify" molto facilmente i moduli html sulla pagina e di fornire gestori di eventi onsubmit , success ed errori per implementare un feedback all'utente sullo stato dell'invio del modulo. Ciò ha consentito di utilizzare il plug-in come segue:

 $('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
      }
 });

Si noti che i gestori di eventi di successo ed errore ricevono gli stessi argomenti che si riceverebbero dagli eventi corrispondenti del metodo jQuery ajax .


9

Ho ottenuto quanto segue per me:

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

dove

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();
    });
}

Ciò presuppone che il post in "url" restituisca un ajax nella forma di {success: false, error:'my Error to display'}

Puoi variare questo come preferisci. Sentiti libero di usare quel frammento.


1
Che cosa è targetper qui? Perché inviare un modulo con AJAX, solo per reindirizzare a una nuova pagina?
1252748,

9

jQuery AJAX invia modulo , non è altro che inviare un modulo utilizzando l'ID modulo quando si fa clic su un pulsante

Si prega di seguire i passaggi

Passaggio 1: il tag del modulo deve avere un campo ID

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

Pulsante su cui si farà clic

<button>Save</button>

Passaggio 2: l' invio dell'evento è in jQuery che aiuta a inviare un modulo. nel codice seguente stiamo preparando la richiesta JSON dal nome dell'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);
        }
    });
});

per la demo live clicca sul link qui sotto

Come inviare un modulo utilizzando jQuery AJAX?


5

considerare l'utilizzo 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

So che questa è una jQuerydomanda correlata, ma ora i giorni con JS ES6 sono molto più facili. Dal momento che non esiste una javascriptrisposta pura , ho pensato di poter aggiungere una semplice javascriptsoluzione pura a questo, che secondo me è molto più pulita, usando l' fetch()API. Questo è un modo moderno di implementare le richieste di rete. Nel tuo caso, poiché hai già un elemento modulo, possiamo semplicemente usarlo per costruire la nostra richiesta.

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

Per evitare invii multipli di formdata:

Non dimenticare di sbloccare l'evento di invio, prima che il modulo venga inviato di nuovo, l'utente può chiamare la funzione sumbit più di una volta, forse ha dimenticato qualcosa o si è verificato un errore di convalida.

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

4

Se stai usando form .serialize () - devi dare ad ogni elemento del modulo un nome come questo:

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

E il modulo viene serializzato in questo modo:

firstName=Chris&lastName=Halcrow ...

4

È possibile utilizzare questa funzione di invio come di seguito.

Modulo 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>

funzione 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>

Per maggiori dettagli e visita di esempio: http://www.spiderscode.com/simple-ajax-contact-form/


2

Questa non è la risposta alla domanda di OP,
ma nel caso in cui non sia possibile utilizzare DOM di moduli statici, è possibile provare anche in questo modo.

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

Provare

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


1

Solo un promemoria amichevole che datapuò essere anche un oggetto:

$('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

C'è anche l'evento submit, che può essere attivato in questo modo $ ("# form_id"). Submit (). Utilizzeresti questo metodo se il modulo è già ben rappresentato in HTML. Avresti semplicemente letto nella pagina, popolato gli input del modulo con elementi, quindi chiamato .submit (). Utilizzerà il metodo e l'azione definiti nella dichiarazione del modulo, quindi non è necessario copiarlo nel tuo javascript.

esempi


58
se elimini il tuo post, otterrai i punti di penalità che ti sono stati tolti indietro.
sparkyspider,

2
Questo invierà il modulo, ma non tramite AJAX, quindi non risponde alla domanda.
superluminario,

11
cosa ha detto @spider, inoltre ottieni un bel badge chiamato "pressione dei pari"
nurettin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.