Cómo enviar un formulario HTML sin redirección

95

Si tengo un formulario como este,

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

¿Cómo puedo enviarlo sin redirigir a otra vista mediante JavaScript / jQuery?

Leí muchas respuestas de Stack Overflow, pero todas me redirigen a la vista devuelta por la función POST.

Duke Nuke
fuente
Quieres una solicitud XHR (AJAX)
Sterling Archer
2
XHR / AJAX es una manera - somete al puesto y obtiene la respuesta detrás de las escenas, por lo que el navegador nunca sale de la página que está. Otra forma es una redirección del lado del servidor después de procesar la publicación, que depende de la tecnología de servidor que esté utilizando.
Stephen P
@StephenP Yo uso ASP.NET MVC 5.1.
Duke Nuke
@Duke, todo lo que digo es que hay más de un enfoque (ajax frente a redireccionamiento del servidor) y su elección depende de sus necesidades. Los sitios modernos probablemente querrán usar ajax. Tenga en cuenta también que todas estas respuestas están diciendo que necesitan jQuery - jQuery de grande, pero no son , de hecho, otras maneras de hacer ajax ... aunque me gustaría usar jQuery hecho a mí mismo.
Stephen P
1
Mi forma es simple, limpia y elegante, y solo tiene 2 líneas de código. No utiliza scripts y funciona en HTML4 y superior, incluso si JavaScript está desactivado.
Issa Chanzi

Respuestas:

74

Para lograr lo que desea, debe usar jQuery Ajax de la siguiente manera:

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

Prueba también este:

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

Solución final

Esto funcionó a la perfección. Llamo a esta función desdeHtml.ActionLink(...)

function SubForm (){
    $.ajax({
        url: '/Person/Edit/@Model.Id/',
        type: 'post',
        data: $('#myForm').serialize(),
        success: function(){
            alert("worked");
        }
    });
}
Amin Jafari
fuente
Esto funcionó muy bien, el problema es que no quiero que se envíe automáticamente (siempre) de esta manera. Me gustaría tener una función con un nombre para hacer estas cosas que publicaste en tu respuesta. Entonces puedo invocarlo manualmente cuando quiero, para que publique el formulario. Como a continuación, puedo dar el nombre de la función a invocar. @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke
Esto funcionó:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke
Por alguna razón, su segunda solución no funcionó, pero la que publiqué en el último comentario sí. Agregaré mi solución a tu publicación porque solo gracias a ti pude lograr esto.
Duke Nuke
1
el segundo también debe funcionar, puede que haya algo más, pero si encontraste la solución, ¡no es necesario que vayas por ese camino ahora mismo! me alegro de haber ayudado;)
Amin Jafari
Gracias esta respuesta también me ayudó a poner un texto personalizado en lugar de la forma después de la presentación
Anupam
116

Puede lograrlo redirigiendo el formulario actiona un archivo invisible <iframe>. No requiere JavaScript ni ningún otro tipo de scripts.

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

<form action="submitscript.php" target="dummyframe">
    <!-- Form body here -->
</form>
Issa Chanzi
fuente
1
Esto es genial. Pero, ¿cómo puedo hacer algo después de enviar el formulario? es decir, los campos de texto del formulario deberán estar vacíos, el foco volverá al primer campo, etc.
Pranjal Choladhara
1
Existe algún tipo de javascript que puede hacer eso. Sólo cambia la <input type='submit'...a <input type='reset'y añadironclick='document.forms["myForm"].submit();'>
Issa Chanzi
¡Hermosa respuesta! Funciona muy bien
Cybrus
Tenga cuidado, es probable que vuelva a cargar la página en la que se encuentra su formulario en el iframe, lo que puede causar problemas de rendimiento si está creando una aplicación o un sitio web grande.
Alexandre Daubricourt
22

Coloque un oculto iFrameen la parte inferior de su página y targeten su formulario:

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

Rapido y Facil. Tenga en cuenta que, si bien el targetatributo todavía se admite ampliamente (y se admite en HTML5), quedó obsoleto en HTML 4.01.

Entonces, realmente debería usar Ajax a prueba de futuro.

Steven Black
fuente
Según MDN, este comportamiento para el targetes completamente válido, por lo que AJAX sigue siendo opcional.
Daniel De León
18

Dado que todas las respuestas actuales usan jQuery o trucos con iframe, pensé que no hay ningún daño para agregar un método con solo 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);
}
Interfaz de usuario de Ethuil
fuente
2
Muchas gracias!
Joshua Evans
Me quito el sombrero ante ti. Pasé horas tratando de averiguar cómo hacer que jquery envíe un formulario a un backend nginx con el parámetro contentType = false y siempre obtengo un 415 como resultado. Esta fue la única solución que encontré que resolvió mi problema particular.
user12066
7

De acuerdo, no les voy a contar una forma mágica de hacerlo porque no la hay. Si tiene un atributo de acción establecido para un elemento de formulario, lo redireccionará.

Si no desea que se redirija, simplemente no configure ninguna acción y configure onsubmit="someFunction();"

En tu someFunction()haces lo que quieras, (con AJAX o no) y al final, agregas return false;para decirle al navegador que no envíe el formulario ...

Anshu Dwibhashi
fuente
1
Hay una forma mágica de hacerlo. Establezca un atributo de destino para que el formulario se redirija a otro lugar que no sea el marco actual. Si agrega un iframe invisible para cosas como esta en sus páginas. Es bastante simple.
Issa Chanzi
5

Necesitas Ajax para que esto suceda. Algo como esto:

$(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
fuente
5
¿Hay alguna razón en particular por la que no sangra este código fuente? Parece un código de los años sesenta antes de que se inventara C. Pensé que habíamos superado esto durante mucho tiempo.
Alfe
2

Vea la postfunción de jQuery .

Crearía un botón, establecería un onClickListener( $('#button').on('click', function(){});) y enviaría los datos en la función.

Además, vea la preventDefaultfunción de jQuery!

Nagy Vilmos
fuente
2

Solución de una sola línea a partir de 2020, si sus datos no están destinados a enviarse como multipart/form-datao application/x-www-form-urlencoded:

<form onsubmit='return false'>
    <!-- ... -->           
</form>
Alexandre Daubricourt
fuente
3
Si combina esto con los OP action="...", esto evita efectivamente el cambio de página, pero también evita que los datos se envíen a través de la red.
Kev
@Kev Personalmente envío mis datos a través de JS XHR, es por eso que no quiero la redirección de página, porque es una aplicación JS
Alexandre Daubricourt
@Kev Lo siento, debería haber mencionado eso
Alexandre Daubricourt
1

El efecto deseado también se puede lograr moviendo el botón de envío fuera del formulario como se describe aquí:

Evite la recarga de la página y la redirección en el formulario enviar ajax / jquery

Me gusta esto:

<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>
Juan
fuente
1

Con este fragmento, puede enviar el formulario y evitar la redirección. En su lugar, puede pasar la función de éxito como argumento y hacer lo que quiera.

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

Y luego simplemente haz:

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

Si controlas el back-end, usa algo como en response.redirectlugar de response.send.

Puede crear páginas HTML personalizadas para esto o simplemente redirigir a algo que ya tiene.

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