如何在表单提交后进行Jquery回调?

132

我有一个带有remote=true的简单表单。

实际上,这个表单在HTML对话框中,该对话框在单击提交按钮后立即关闭。

现在,在表单成功提交后,我需要在主HTML页面上进行一些更改。

我尝试使用jQuery来完成这个任务。但是这并不能确保在表单提交后获得某种响应后执行任务。

$("#myform").submit(function(event) {

// do the task here ..

});

如何附加回调函数才能在表单成功提交后执行代码?有没有办法将一些 .success 或 .complete 回调函数添加到表单中?


为什么不使用Ajax呢?使用jQuery Ajax函数,您可以定义这样的回调函数。 - davidbuzatto
12
有些情况下,您无法使用ajax。比如说,当您想要上传文件时。 - Pere
4
在这里,未来并非如此。 - SparK
7个回答

128
我刚刚做了这件事 -
 $("#myform").bind('ajax:complete', function() {

         // tasks to do 


   });

而且事情运行得非常完美。

有关更具体细节,请参见此API文档


3
哇...我刚学了一件新事物。看起来,这是最简单的解决方法。或许,它甚至是最好的。我是一个热爱《编程恐惧症》博客的读者,在那个博客中,Jeff Attwood强调我们应该写更少的代码,而这种方法正好可以实现。很不错的发现。 :) - Sal Rahman
7
如果表单通常是通过提交而不是 Ajax 提交的,我应该在 .bind() 的第一个参数中放什么?编辑:好吧,我想应该是 click。不用管了,对不起。 :p - 4wk_
11
请注意:这将在任何ajax事件完成后触发您的函数,而不仅仅是在表单提交时(除非我搞错了,在这种情况下,我希望您能够提供您找到此信息的链接)。 - DMac the Destroyer
19
自 jQuery 1.8 开始,应该只将 .ajaxComplete() 方法附加到 document。 - Meredith
8
对我来说没有用,使用普通表格和按钮,但按钮调用JavaScript代码 $('#formFile').submit(); - Daniel
显示剩余9条评论

41

我无法可靠地使用得分最高的解决方案,但发现这个方法有效。不确定是否必需,但我在 <form> 标签上没有 action 或 method 属性,这确保了 POST 请求由 $.ajax 函数处理,并提供了回调选项。

<form id="form">
...
<button type="submit"></button>
</form>

<script>
$(document).ready(function() {
  $("#form_selector").submit(function() {

    $.ajax({
     type: "POST",
      url: "form_handler.php",
      data: $(this).serialize(),
      success: function() {
        // callback code here
       }
    })

  })
})
</script>

1
这个答案的关键是 $(this).serialize() 这一行。它让你可以使用 jQuery.ajax() 在后台提交现有表单,然后捕获服务器的回复并对其进行处理。 - Warren Young
20
JavaScript没有分号...有些人只是想看世界燃烧。不过你的解决方案有效,谢谢 :) - viggity
2
请注意,.serialize 不会在您的 POST 请求中包含文件输入。除非您支持 IE < 9 等旧浏览器,否则请改用 HTML5 FormData(参见此问题)。 - brichins
你的HTML中引用的JS中的'form_selector'是什么? - Kevin Meredith
@wenwen 这个lint规则是针对额外的分号的。它并不反对使用它们,只是说当一个足够时不要使用两个。我个人同意viggity的观点,不使用它们会让世界燃烧,或者至少在某人意外删除换行符时会烧掉你的代码。 - Carl
显示剩余4条评论

24
您需要通过向服务器发起 AJAX 调用来手动完成操作。这将要求您同时覆盖表单。
但是不用担心,这很简单。以下是您如何处理表单的概述:
- 重写默认提交操作(通过传递的事件对象,该对象具有 preventDefault 方法) - 从表单中获取所有必要的值 - 发送 HTTP 请求 - 处理请求的响应。
首先,您需要取消表单提交操作,如下所示:
$("#myform").submit(function(event) {
    // Cancels the form's submit action.
    event.preventDefault();
});

然后,获取数据的值。假设您有一个文本框。

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();
});

接着发送一个请求。我们假定这是一个POST请求。

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();

    // I like to use defers :)
    deferred = $.post("http://somewhere.com", { val: val });

    deferred.success(function () {
        // Do your stuff.
    });

    deferred.error(function () {
        // Handle any errors here.
    });
});

这应该就可以了。

注意2:为解析表单数据,最好使用一个插件。它会让你的生活变得更加轻松,同时提供一种很好的语义,模拟实际的表单提交操作。

注意2:你不必使用延迟加载。这只是个人偏好。你也可以同样地采用以下方式,它同样有效。

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});

2
很棒的示例。如何使用文件上传(multi-part/form-data)执行相同的操作??? - Adam W
注意2:不要使用插件来处理表单数据,也不要手动从表单中抓取每个值。使用JS FormData对象一次性获取整个表单的数据,包括多部分/文件数据: var formData = new FormData(this); - Tim

10

MVC 的另一种更简单的方法是使用 Ajax 表单并设置 AjaxOptions。

@using (Ajax.BeginForm("UploadTrainingMedia", "CreateTest", new AjaxOptions() { HttpMethod = "POST", OnComplete = "displayUploadMediaMsg" }, new { enctype = "multipart/form-data", id = "frmUploadTrainingMedia" }))
{ 
  ... html for form
}

这是提交代码,在文档准备部分,并将按钮的onclick事件与提交表单绑定

$("#btnSubmitFileUpload").click(function(e){
        e.preventDefault();
        $("#frmUploadTrainingMedia").submit();
});

这里是AjaxOptions中所引用的回调函数。

function displayUploadMediaMsg(d){
    var rslt = $.parseJSON(d.responseText);
    if (rslt.statusCode == 200){
        $().toastmessage("showSuccessToast", rslt.status);
    }
    else{
        $().toastmessage("showErrorToast", rslt.status);
    }
}

在MVC的控制器方法中,它看起来像这样

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult UploadTrainingMedia(IEnumerable<HttpPostedFileBase> files)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            // there is only one file  ... do something with it
        }
        return Json(new
        {
            statusCode = 200,
            status = "File uploaded",
            file = "",
        }, "text/html");
    }
    else
    {
        return Json(new
        {
            statusCode = 400,
            status = "Unable to upload file",
            file = "",
        }, "text/html");
    }
}

2
这些代码是 .Net 代码,而问题中从未指定。 - Benjamin RD
14
这真的不是一个好的理由来点踩这个回答。这个答案是有效的,可能会帮助一个面临相同问题的.NET开发者。 - edepperson
我喜欢这个想法,但是由于某些原因回调函数没有触发。控制器方法必须返回JsonResult吗?我的控制器方法目前返回一个ActionResult。 - mattpm

7

我不认为有像你描述的回调函数。

在这里正常的做法是使用某些服务器端语言,比如PHP。

在PHP中,你可以从表单中获取一个隐藏字段,如果存在的话,进行一些更改。

PHP:

  $someHiddenVar = $_POST["hidden_field"];
    if (!empty($someHiddenVar)) {
        // do something 
    }

在Jquery中实现的一种方法是使用Ajax。您可以监听提交事件,返回false以取消其默认行为,并使用jQuery.post()代替。jQuery.post具有成功回调函数。

$.post("test.php", $("#testform").serialize(), function(data) {
  $('.result').html(data);
});

http://api.jquery.com/jQuery.post/


1
表单的“on submit”处理程序在提交表单之前被调用。我不知道是否有一个在表单提交后被调用的处理程序。在传统的非JavaScript意义上,表单提交将重新加载页面。

2
除非表单提交重定向到文件下载,否则页面将保持不变。我不能使用JavaScript提交,因为Ajax请求无法启动文件下载(没有锚标签游戏),但我也不能告诉用户等待或在他们获得文件后清理... - kitsu.eb

-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });

3
ajaxForm() 是您安装的第三方组件吗?它不是 jQuery 的标准组成部分。 - Warren Young

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接