jQuery AJAX soumettre le formulaire

939

J'ai un formulaire avec un nom orderproductFormet un nombre indéfini d'entrées.

Je veux faire une sorte de jQuery.get ou ajax ou quelque chose comme ça qui appelerait une page via Ajax, et enverrait toutes les entrées du formulaire orderproductForm.

Je suppose qu'une façon serait de faire quelque chose comme

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

Cependant, je ne connais pas exactement toutes les entrées du formulaire. Existe-t-il une fonctionnalité, une fonction ou quelque chose qui enverrait TOUTES les entrées du formulaire?

Nathan H
la source

Réponses:

814

Vous pouvez utiliser les fonctions ajaxForm / ajaxSubmit d' Ajax Form Plugin ou la fonction de sérialisation jQuery.

AjaxForm :

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

ou

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

ajaxForm enverra lorsque le bouton d'envoi est enfoncé. ajaxSubmit envoie immédiatement.

Sérialiser :

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

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

La documentation de sérialisation AJAX est ici .

jspcal
la source
2
idée intéressante, cependant, je ne contrôle pas le côté serveur que j'appelle, donc je ne peux pas lui envoyer de données sérialisées
Nathan H
25
Oui, le nom n'a pas d'importance ce qu'il fera est d'envoyer des paires de chaque clé de formulaire et de chaque variable de formulaire.
6
Il est sérialisé en une chaîne de requête, tout comme les données que vous placez manuellement dans le tableau lors de l'appel GET. C'est ce que tu veux, j'en suis presque sûr.
JAL
1
oooh je vois, j'ajoute ensuite cette chaîne à la fin de l'URL dans l'appel get. Je pensais que PHP sérialisait. Désolé. Merci!
Nathan H
238
.ajaxSubmit()/ .ajaxForm()ne sont pas des fonctions jQuery de base - vous avez besoin du plugin de formulaire jQuery
Yarin
1401

Ceci est une simple référence:

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


});

J'espère que ça t'aide.

Alfrekjv
la source
46
Mais form.serialize () ne peut pas publier <input type = "file"> dans IE
macio.juin
2
Excellente réponse pour la soumission d'un formulaire normal!
The Sheek Geek
1
Semblable à @ BjørnBørresen, vous pouvez également utiliser type: $(this).attr('method')si vous utilisez l' methodattribut sur votre formulaire.
djule5
2
Il convient de mentionner que depuis jQuery 1.8, .success, .error et .complete sont déconseillés au profit de .done, .fail et .always.
Adam
2
Commentaire de JohnKary - excellent article, il semble qu'il ne soit plus disponible cependant. Voici une archive des événements jQuery: Stop (Mis) Using Return False
KyleMit
455

Une autre solution similaire utilisant des attributs définis sur l'élément de formulaire:

<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
la source
Des suggestions sur la façon de procéder si l'attribut name comprend un "."? (Exigence côté serveur, pas mon idée).
Josef Engelfrost
Incluez un rappel d'erreur à cela pour le terminer. On ne sait jamais quand on obtiendra une erreur, il faut toujours en tenir compte.
codage aaron
1
Si vous ne définissez pas de méthode ou d'action, ils sont définis par défaut sur getet l'URL actuelle respectivement. Pourrait faire avec l'ajout de cette hypothèse au code.
rybo111
1
Selon la documentation jQuery ( api.jquery.com/submit ), frm.submit (function (event) {..}); est équivalent à frm.on ("soumettre", fonction (événement) {..}) ;. Pour moi, ce dernier est plus lisible car il est évident que vous attachez un gestionnaire d'événements à un élément à exécuter lorsque l'événement est déclenché.
mehmet
177

Il y a quelques choses que vous devez garder à l'esprit.

1. Il existe plusieurs façons de soumettre un formulaire

  • en utilisant le bouton soumettre
  • en appuyant sur enter
  • en déclenchant un événement de soumission en JavaScript
  • éventuellement plus en fonction de l'appareil ou futur appareil.

Nous devons donc nous lier à l' événement de soumission du formulaire , et non à l'événement de clic de bouton. Cela garantira que notre code fonctionne sur tous les appareils et technologies d'assistance, maintenant et à l'avenir.

2. Hijax

L'utilisateur peut ne pas avoir activé JavaScript. Un modèle hijax est bon ici, où nous prenons doucement le contrôle du formulaire en utilisant JavaScript, mais le laissons soumis en cas d'échec de JavaScript.

Nous devons extraire l'URL et la méthode du formulaire, donc si le HTML change, nous n'avons pas besoin de mettre à jour le JavaScript.

3. JavaScript discret

L'utilisation de event.preventDefault () au lieu de renvoyer false est une bonne pratique car elle permet à l'événement de se propager. Cela permet à d'autres scripts de se lier à l'événement, par exemple des scripts d'analyse qui peuvent surveiller les interactions des utilisateurs.

La vitesse

Nous devrions idéalement utiliser un script externe, plutôt que d'insérer notre script en ligne. Nous pouvons créer un lien vers cela dans la section d'en-tête de la page en utilisant une balise de script, ou un lien vers celui-ci au bas de la page pour plus de rapidité. Le script devrait tranquillement améliorer l'expérience utilisateur, ne pas gêner.

Code

En supposant que vous êtes d'accord avec tout ce qui précède et que vous souhaitez intercepter l'événement de soumission et le gérer via AJAX (un modèle hijax), vous pouvez faire quelque chose comme ceci:

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

Vous pouvez déclencher manuellement une soumission de formulaire à tout moment via JavaScript en utilisant quelque chose comme:

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

Éditer:

J'ai récemment dû le faire et j'ai fini par écrire 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)

Ajoutez un attribut data-autosubmit à votre balise de formulaire et vous pouvez ensuite faire ceci:

HTML

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

JS

$(function() {
  $('form[data-autosubmit]').autosubmit();
});
superluminaire
la source
2
comment puis-je ajouter les rappels aux fonctions «terminé» et «échoué»? quelque chose comme $ ('form [data-autosubmit]'). autosubmit (). done (function ({...}); C'est possible?
Crusader
1
Salut @Crusader - certainement, au lieu que ce plugin retourne ceci, vous pourriez lui faire retourner l'événement ajax, alors vous pouvez enchaîner directement dessus. Alternativement, vous pouvez faire en sorte que le plugin reçoive un rappel réussi.
superluminaire
Je ne vois pas comment cela "... le laisse soumis si JavaScript échoue" se produit-il ici?
mehmet
@mmatt - Si JavaScript est désactivé, le formulaire n'est encore qu'un formulaire. L'utilisateur clique sur Soumettre et une soumission régulière de formulaire basée sur un navigateur se produit. Nous appelons cette amélioration progressive. Ce n'est pas si grave de nos jours puisque les lecteurs d'écran modernes prennent en charge JavaScript.
superluminaire
@mmatt - Les rappels de promesse recevront éventuellement un paramètre qui contient les données.
superluminaire
41

Vous pouvez également utiliser FormData (mais non disponible dans 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)} 
});

Voici comment vous utilisez FormData .

macio.Jun
la source
8
Je vois que FormData est maintenant pris en charge par IE10. Dans quelques années, ce sera la solution préférée.
superluminaire
3
Quel avantage de cette façon?
insigne
1
L'avantage @insign est, aucun plugin que ce soit requis, et fonctionne sur de nombreux navigateurs modernes.
KhoPhi
4
@insign FormData peut également gérer des fichiers (s'il existe un tel champ dans votre formulaire) tandis que serialize () l'ignore.
mehmet
TypeError non capturé: échec de construction de 'FormData': le paramètre 1 n'est pas de type 'HTMLFormElement'
rahim.nagori
28

Version simple (n'envoie pas d'images)

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

Copiez et collez l'ajaxification d'un formulaire ou de tous les formulaires d'une page

Il s'agit d'une version modifiée de la réponse d' Alfrekjv

  • Cela fonctionnera avec jQuery> = 1.3.2
  • Vous pouvez l'exécuter avant que le document ne soit prêt
  • Vous pouvez supprimer et rajouter le formulaire et cela fonctionnera toujours
  • Il sera publié au même emplacement que le formulaire normal, spécifié dans l'attribut "action" du formulaire

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

Je voulais modifier la réponse d'Alfrekjv mais je m'en suis trop écartée, j'ai donc décidé de poster ceci comme une réponse distincte.

N'envoie pas de fichiers, ne prend pas en charge les boutons, par exemple en cliquant sur un bouton (y compris un bouton d'envoi) envoie sa valeur en tant que données de formulaire, mais comme il s'agit d'une demande ajax, le clic sur le bouton ne sera pas envoyé.

Pour prendre en charge les boutons, vous pouvez capturer le clic du bouton réel au lieu de la soumettre.

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

Côté serveur, vous pouvez détecter une requête ajax avec cet en-tête que jquery définit HTTP_X_REQUESTED_WITH pour php

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}
Timo Huovinen
la source
Comment cela fonctionnerait-il si vous souhaitiez envoyer un fichier avec ce formulaire?
Yami Medina
1
@YamiMedina ce n'est pas une solution simple, vous devez envoyer la demande entière dans un format différent (format multipartie) avec les données du fichier
Timo Huovinen
22

Ce code fonctionne même avec une entrée de fichier

$(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)
        {


        }
    });        
});
L'Islam Shaiful
la source
3
Il suffit de noter que formData () est IE10 + developer.mozilla.org/en-US/docs/Web/API/FormData
Chris Hopkins
1
le dataType: 'json' est important si vous souhaitez utiliser form.serialize ()
David Morrow
wow, ce FormData est merveilleux! dans le cas où quelqu'un a besoin: Array.from(new FormData(form))itère sur cet itérateur de données de formulaire :)
test30
13

J'ai vraiment aimé cette réponse de superluminary et surtout la façon dont il est enveloppé est une solution dans un plugin jQuery . Merci donc au superluminaire pour une réponse très utile. Dans mon cas, cependant, je voulais un plugin qui me permettrait de définir les gestionnaires d'événements de réussite et d' erreur au moyen d'options lorsque le plugin est initialisé.

Voici donc ce que j'ai trouvé:

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

Ce plugin me permet "d'ajaxifier" très facilement les formulaires html sur la page et de fournir des gestionnaires d'événements onsubmit , success et error pour implémenter un feedback à l'utilisateur du statut du formulaire soumis. Cela a permis au plugin d'être utilisé comme suit:

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

Notez que les gestionnaires d'événements de réussite et d' erreur reçoivent les mêmes arguments que ceux que vous recevriez des événements correspondants de la méthode ajQuery jQuery .

BruceHill
la source
9

J'ai obtenu ce qui suit pour moi:

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

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

Cela suppose que le message à «url» renvoie un ajax sous la forme de {success: false, error:'my Error to display'}

Vous pouvez varier cela à votre guise. N'hésitez pas à utiliser cet extrait.

Tarion
la source
1
À quoi sert targetici? Pourquoi soumettriez-vous un formulaire avec AJAX, uniquement pour rediriger vers une nouvelle page?
1252748
9

jQuery AJAX soumettre un formulaire , n'est rien d'autre que soumettre un formulaire en utilisant l'ID de formulaire lorsque vous cliquez sur un bouton

Veuillez suivre les étapes

Étape 1 - La balise de formulaire doit avoir un champ ID

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

Bouton sur lequel vous allez cliquer

<button>Save</button>

Étape 2 - soumettre l' événement est dans jQuery qui aide à soumettre un formulaire. dans le code ci-dessous, nous préparons la demande JSON à partir du nom de l' élément 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);
        }
    });
});

pour une démonstration en direct, cliquez sur le lien ci-dessous

Comment soumettre un formulaire en utilisant jQuery AJAX?

jeet singh parmar
la source
5

envisager d'utiliser 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
la source
5

Je sais que c'est une jQueryquestion connexe, mais maintenant, avec JS ES6, les choses sont beaucoup plus faciles. Puisqu'il n'y a pas de javascriptréponse pure , j'ai pensé que je pourrais ajouter une javascriptsolution pure simple à cela, qui à mon avis est beaucoup plus propre, en utilisant l' fetch()API. C'est une façon moderne de mettre en œuvre les requêtes réseau. Dans votre cas, puisque vous avez déjà un élément de formulaire, nous pouvons simplement l'utiliser pour construire notre demande.

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
la source
4

Pour éviter plusieurs envois de données de formulaire:

N'oubliez pas de dissocier l'événement de soumission, avant que le formulaire ne soit soumis à nouveau, l'utilisateur peut appeler la fonction sumbit plus d'une fois, peut-être qu'il a oublié quelque chose ou était une erreur de validation.

 $("#idForm").unbind().submit( function(e) {
  ....
Pavel Zheliba
la source
4

Si vous utilisez le formulaire .serialize () - vous devez donner à chaque élément du formulaire un nom comme celui-ci:

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

Et le formulaire est sérialisé comme ceci:

firstName=Chris&lastName=Halcrow ...
Chris Halcrow
la source
4

Vous pouvez l'utiliser sur la fonction d'envoi comme ci-dessous.

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

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

Pour plus de détails et un exemple de visite: http://www.spiderscode.com/simple-ajax-contact-form/

suresh raj
la source
2

Ce n'est pas la réponse à la question d'OP,
mais si vous ne pouvez pas utiliser le formulaire statique DOM, vous pouvez également essayer comme ceci.

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
la source
2

Essayer

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

Kamil Kiełczewski
la source
1

Juste un rappel amical qui datapeut aussi être un objet:

$('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
la source
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
la source
-21

Il y a aussi l'événement submit, qui peut être déclenché comme ceci $ ("# form_id"). Submit (). Vous utiliseriez cette méthode si le formulaire est déjà bien représenté en HTML. Il vous suffit de lire la page, de remplir les entrées du formulaire avec des éléments, puis d'appeler .submit (). Il utilisera la méthode et l'action définies dans la déclaration du formulaire, vous n'avez donc pas besoin de les copier dans votre javascript.

exemples

billw
la source
58
si vous supprimez votre message, vous obtenez les points de pénalité qui vous ont été retirés.
sparkyspider
2
Cela soumettra le formulaire, mais pas via AJAX, donc ne répond pas à la question.
superluminaire
11
ce que @spider a dit, en plus vous obtenez un joli badge appelé "pression des pairs"
nurettin