Comment soumettre un formulaire HTML sans redirection

95

Si j'ai un formulaire comme celui-ci,

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm"> ... </form>

comment puis-je le soumettre sans rediriger vers une autre vue par JavaScript / jQuery?

J'ai lu beaucoup de réponses de Stack Overflow, mais toutes me redirigent vers la vue renvoyée par la fonction POST.

Duc Nuke
la source
Vous voulez une requête XHR (AJAX)
Sterling Archer
2
XHR / AJAX est une façon - il soumet le poste et obtient la réponse dans les coulisses, de sorte que le navigateur ne quitte jamais la page , il est sur. Une autre façon est une redirection côté serveur après le traitement de la publication, qui dépend de la technologie de serveur que vous utilisez.
Stephen P
@StephenP J'utilise ASP.NET MVC 5.1.
Duke Nuke
@Duke, tout ce que je dis, c'est qu'il y a plus d'une approche (ajax vs serveur-redirect) et votre choix dépend de vos besoins. Les sites modernes voudront probablement faire de l'ajax. Notez également que toutes ces réponses disent que vous avez besoin de jQuery - jQuery est génial mais il existe , en fait, d'autres façons de faire ajax ... même si j'utiliserais effectivement jQuery moi-même.
Stephen P
1
Mon chemin est simple, propre et élégant, et ce n'est que 2 lignes de code. Il n'utilise aucun script et fonctionne en HTML4 et au-dessus, même si JavaScript est désactivé.
Issa Chanzi le

Réponses:

74

Afin d'obtenir ce que vous voulez, vous devez utiliser jQuery Ajax comme ci-dessous:

$('#myForm').submit(function(e){
    e.preventDefault();
    $.ajax({
        url: '/Car/Edit/17/',
        type: 'post',
        data:$('#myForm').serialize(),
        success:function(){
            // Whatever you want to do after the form is successfully submitted
        }
    });
});

Essayez également celui-ci:

function SubForm(e){
    e.preventDefault();
    var url = $(this).closest('form').attr('action'),
    data = $(this).closest('form').serialize();
    $.ajax({
        url: url,
        type: 'post',
        data: data,
        success: function(){
           // Whatever you want to do after the form is successfully submitted
       }
   });
}

Solution finale

Cela a fonctionné parfaitement. J'appelle cette fonction depuisHtml.ActionLink(...)

function SubForm (){
    $.ajax({
        url: '/Person/Edit/@Model.Id/',
        type: 'post',
        data: $('#myForm').serialize(),
        success: function(){
            alert("worked");
        }
    });
}
Amin Jafari
la source
Cela a très bien fonctionné, le problème est que je ne veux pas qu'il soit automatiquement (toujours) soumis de cette façon. Je voudrais avoir une fonction avec un nom pour faire ce que vous avez publié dans votre réponse. Je peux donc l'invoquer manuellement quand je le souhaite, pour qu'il affiche le formulaire. Comme ci-dessous, je peux donner le nom de la fonction à invoquer. @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke
Cela a fonctionné:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke
Pour une raison quelconque, votre deuxième solution n'a pas fonctionné, mais celle que j'ai publiée dans le dernier commentaire a fonctionné. J'ajouterai ma solution à votre message car c'est uniquement grâce à vous que je pourrais y parvenir.
Duke Nuke
1
le second doit également fonctionner, il y a peut-être autre chose, mais si vous trouvez la solution, nous n'avons pas besoin de suivre cette voie maintenant! heureux que cela ait aidé;)
Amin Jafari
Merci cette réponse m'a également aidé à mettre un texte personnalisé à la place du formulaire après la soumission
Anupam
116

Vous pouvez y parvenir en redirigeant le formulaire actionvers un fichier invisible <iframe>. Il ne nécessite aucun JavaScript ni aucun autre type de script.

<iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe>

<form action="submitscript.php" target="dummyframe">
    <!-- Form body here -->
</form>
Issa Chanzi
la source
1
C'est bien. Mais comment puis-je faire quelque chose, une fois le formulaire soumis? c'est-à-dire que les champs de texte du formulaire devront être vides, le focus revient au premier champ, etc.?
Pranjal Choladhara
1
Il existe une sorte de javascript qui peut le faire. Il suffit de changer le <input type='submit'...pour <input type='reset'et ajouteronclick='document.forms["myForm"].submit();'>
Issa Chanzi
Belle réponse! Works great
Cybrus
Attention, il est susceptible de recharger la page dans laquelle se trouve votre formulaire dans l'iframe, ce qui peut entraîner des problèmes de performances si vous créez une application ou un grand site Web.
Alexandre Daubricourt le
22

Placez un caché iFrameen bas de votre page et targetle dans votre formulaire:

<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm" target="hiddenFrame"> ... </form>

Rapide et facile. Gardez à l'esprit que bien que l' targetattribut soit toujours largement pris en charge (et pris en charge dans HTML5), il était obsolète dans HTML 4.01.

Vous devriez donc vraiment utiliser Ajax à l'épreuve du temps.

Steven Black
la source
Selon MDN, ce comportement pour le targetest complètement valide, donc AJAX est toujours facultatif.
Daniel De León
18

Étant donné que toutes les réponses actuelles utilisent jQuery ou des astuces avec iframe, il n'y a aucun mal à ajouter une méthode avec juste du JavaScript:

function formSubmit(event) {
  var url = "/post/url/here";
  var request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.onload = function() { // request successful
  // we can use server response to our request now
    console.log(request.responseText);
  };

  request.onerror = function() {
    // request failed
  };

  request.send(new FormData(event.target)); // create FormData from form that triggered event
  event.preventDefault();
}

// and you can attach form submit event like this for example
function attachFormSubmitEvent(formId){
  document.getElementById(formId).addEventListener("submit", formSubmit);
}
UI Ethuil
la source
2
Merci beaucoup!
Joshua Evans
Je lève mon chapeau à vous. J'ai passé des heures à essayer de comprendre comment faire en sorte que jquery envoie un formulaire à un backend nginx avec le paramètre contentType = false et obtienne toujours un 415 en conséquence. C'était la seule solution que j'ai trouvée pour résoudre mon problème particulier.
user12066
7

D'accord, je ne vais pas vous dire une façon magique de le faire parce qu'il n'y en a pas. Si vous avez défini un attribut d'action pour un élément de formulaire, il sera redirigé.

Si vous ne voulez pas qu'il redirige simplement, ne définissez aucune action et définissez onsubmit="someFunction();"

Dans votre someFunction()vous faites ce que vous voulez, (avec AJAX ou pas) et à la fin, vous ajoutez return false;pour dire au navigateur de ne pas soumettre le formulaire ...

Anshu Dwibhashi
la source
1
Il existe une manière magique de le faire. Définissez un attribut cible pour que le formulaire redirige vers un autre emplacement que le cadre actuel. Si vous ajoutez une iframe invisible pour des choses comme celle-ci dans vos pages. C'est assez simple.
Issa Chanzi
5

Vous avez besoin d'Ajax pour y arriver. Quelque chose comme ça:

$(document).ready(function(){
    $("#myform").on('submit', function(){
        var name = $("#name").val();
        var email = $("#email").val();
        var password = $("#password").val();
        var contact = $("#contact").val();

        var dataString = 'name1=' + name + '&email1=' + email + '&password1=' + password + '&contact1=' + contact;
        if(name=='' || email=='' || password=='' || contact=='')
        {
            alert("Please fill in all fields");
        }
        else
        {
            // Ajax code to submit form.
            $.ajax({
                type: "POST",
                url: "ajaxsubmit.php",
                data: dataString,
                cache: false,
                success: function(result){
                    alert(result);
                }
           });
        }
        return false;
    });
});
Bojan Petkovski
la source
5
Y a-t-il une raison particulière pour laquelle vous ne mettez pas en retrait ce code source? Cela ressemble à du code des années soixante avant l'invention du C. Je pensais que nous en étions depuis longtemps.
Alfe
2

Voir la postfonction de jQuery .

Je créerais un bouton, définirais un onClickListener( $('#button').on('click', function(){});) et enverrais les données dans la fonction.

Voir également la preventDefaultfonction, de jQuery!

Nagy Vilmos
la source
2

Solution One-Liner à partir de 2020, si vos données ne sont pas destinées à être envoyées en tant que multipart/form-dataou application/x-www-form-urlencoded:

<form onsubmit='return false'>
    <!-- ... -->           
</form>
Alexandre Daubricourt
la source
3
Si vous combinez cela avec les OP action="...", cela empêche efficacement le changement de page, mais empêche également la soumission de données sur le réseau.
Kev
@Kev J'envoie personnellement mes données via JS XHR, c'est pourquoi je ne veux pas de redirection de page, car c'est une application JS
Alexandre Daubricourt
@Kev Désolé j'aurais dû mentionner ça
Alexandre Daubricourt
1

L'effet souhaité peut également être obtenu en déplaçant le bouton d'envoi en dehors du formulaire comme décrit ici:

Empêcher le rechargement de la page et la redirection lors de l'envoi du formulaire ajax / jquery

Comme ça:

<form id="getPatientsForm">
    Enter URL for patient server
    <br/><br/>
    <input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
    <input name="patientRootUrl" size="100"></input>
    <br/><br/>
</form>

<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
John
la source
1

En utilisant cet extrait, vous pouvez soumettre le formulaire et éviter la redirection. Au lieu de cela, vous pouvez passer la fonction de succès comme argument et faire ce que vous voulez.

function submitForm(form, successFn){
    if (form.getAttribute("id") != '' || form.getAttribute("id") != null){
        var id = form.getAttribute("id");
    } else {
        console.log("Form id attribute was not set; the form cannot be serialized");
    }

    $.ajax({
        type: form.method,
        url: form.action,
        data: $(id).serializeArray(),
        dataType: "json",
        success: successFn,
        //error: errorFn(data)
    });
}

Et puis faites simplement:

var formElement = document.getElementById("yourForm");
submitForm(formElement, function() {
    console.log("Form submitted");
});
jmojico
la source
0

Si vous contrôlez le back-end, utilisez quelque chose comme à la response.redirectplace de response.send.

Vous pouvez créer des pages HTML personnalisées pour cela ou simplement rediriger vers quelque chose que vous avez déjà.

Dans Express.js:

const handler = (req, res) => {
  const { body } = req
  handleResponse(body)
  .then(data => {
    console.log(data)
    res.redirect('https://yoursite.com/ok.html')
  })
  .catch(err => {
    console.log(err)
    res.redirect('https://yoursite.com/err.html')
  })
}
...
app.post('/endpoint', handler)
etw3
la source