Javascript 事件处理程序未拦截表单提交

Posted

技术标签:

【中文标题】Javascript 事件处理程序未拦截表单提交【英文标题】:Javascript event handler is not intercepting the form submission 【发布时间】:2013-09-24 18:03:14 【问题描述】:

我正在使用 asp.net mvc 4 razor,我有一个主视图,其中包含一些复选框和一个提交按钮。这些复选框指示要执行的任务。用户通过复选框选择要执行的任务,然后通过单击提交按钮启动该过程。我有一个 div 块,我想在其上放置控制器中的操作进度,它们当前正在完成的任务。

单击提交按钮后,我希望启动第一个脚本(主要脚本),然后完成下一个任务。

问题是第一个主脚本然后按顺序调用其他脚本没有被调用。

我正在使用 ASP.NET MVC 4

代码下方。

查看:

@using (html.BeginForm(
     "PerformTasks", "Tests", FormMethod.Post,
     htmlAttributes: new  id = "frm" ))
 
   (...)
       @Html.CheckBoxFor(m => m.task01)<span>Task 1</span><br />
       @Html.CheckBoxFor(m => m.task02)<span>Task 2</span><br />
   (...)
       <input type="submit" value="Do Tasks" />
       <div id="divStatus">
       </div>


<script>

// First ajax script
$("#frm").submit(function (event) 
    $("#frm").validate();
    if ($("#frm").valid()) 
       $.ajax(
                url: "/Tests/PerformTasks/",
                type: 'POST',
                data: $("#frm").serialize(),
                success: function()             
                          perFormTask1();
                ,
                beforeSend: function()  
                     $("#divStatus").append('<br/>Begginig tasks...<br/>'); 
                           
       );
       event.preventDefault();
    
);

// second ajax script
function performTask1() 
  $.ajax(
    url: "/Tests/Task1/",
    type: 'POST',
    data: $("#frm").serialize(),
    success: function()  
        $("#divStatus").append('Task1 completed.<br/>');           
        perFormTask2();
    ,
    beforeSend: function()  
        $("#divStatus").append('<br/>Begginig task 1...<br/>'); 
                
  );
;

function performTask2() 
  $.ajax(
    url: "/Tests/Task2/",
    type: 'POST',
    data: $("#frm").serialize(),
    success: function()  
        $("#divStatus").append('Task2 completed.<br/>');
    ,
    beforeSend: function()  
        $("#divStatus").append('<br/>Begginig task 2...<br/>'); 
                
  );
;

</script>

控制器(\Controllers 下的TestsController.cs):

public class TestsController : Controller

  [HttpPost]
  public ActionResult PerformTasks(ViewModel model)
  
      // Nothing to do here, tasks are done individually in the methods below.
      // To stay in the same page after submit button is clicked
      return Redirect(this.Request.UrlReferrer.AbsolutePath);
  

  [HttpPost]
  public ActionResult Task1(ViewModel model)
  
     // Task 1 should be done if checkbox in the main view is checked, otherwise not.
     bool doTask1 = model.task01;
     if (doTask1 )
     
       // Do some stuff
              

     // To stay in the same page after submit button is clicked
     return Redirect(this.Request.UrlReferrer.AbsolutePath);
  

  [HttpPost]
  public ActionResult Task2(ViewModel model)
  
    // Task 2 should be done if checkbox in the main view is checked, otherwise not.
    bool doTask2 = model.task02;
    if (doTask2)
    
       // Do some stuff
    

    // To stay in the same page after submit button is clicked
    return Redirect(this.Request.UrlReferrer.AbsolutePath);
  

视图模型:

public class ViewModel

    public bool task01 get; set; 
    public bool task02 get; set; 

我有以下问题:

    我应该把而不是因为如果不是,我得到 错误消息 javascript '$' 未定义 这个脚本 $("#frm").submit(function (event) ... // body ... 是 没有被执行,所以其他的动作都没有 完成。所以第一个脚本的事件完成不是 到达。

注意:我已经检查了控制器中的操作 PerformTasks 正在执行。未达到控制器上的其他操作 Task1、Task2。 在脚本中,我尝试完成而不是成功,但没有成功。 我还尝试在由 JsonResult 控制的操作中替换 ActionResult 并返回 return Redirect(...) 以返回 Json("") 但也没有成功。

似乎 Javascript 事件处理程序没有拦截表单提交。

有什么想法吗?

生成的代码:

<form action="/Tests/PerformTasks" id="frm" method="post"><fieldset style="margin-top:20px;margin-left:0px;float:left;"> 
   .... 
   <input type="submit" value="Execute" /> 
   ...
   <div id="divStatus"></div>
   ...
</form>

然后在脚本下方:

<script src="/Scripts/jquery-1.7.1.min.js" type="text/javascript">
    alert("Within Script");
    $("#frm").submit(function (event)  .. );
    ...
</script> 

脚本与此处发布的相同。

【问题讨论】:

你能把生成的 HTML 也贴出来吗? 我刚刚发布了渲染视图的重要部分。请告诉我你对哪些部分感兴趣。我无法发布所有信息,因为这些信息来自工作......我检查过的是,由于某种原因,javascript 处理程序没有拦截表单提交,我放置的脚本中的警报永远不会执行(参见在生成的代码中)。 这就是我想要的。提交的表单是否通过验证? AJAX 调用是否触发? 我对它非常感兴趣,我怎么知道我是否通过了验证?我不这么认为。告诉我怎么知道。控制器中的 PerformTasks 操作已到达,但我认为它不是从 ajax 脚本到达的,而是通过表单提交:@using (Html.BeginForm("PerformTasks", "Tests", FormMethod.Post, htmlAttributes: new id = "frm" )) 因为我已经在脚本中添加了警报并且它们永远不会被触发。 我使用的唯一验证是在脚本中使用这些行: $("#frm").validate();if ($("#frm").valid()) .. . 另外,我已经在脚本的选项完成成功错误中发出警报,但从未到达那里。 【参考方案1】:

您没有在 document.ready 中包围您的表单提交处理程序,它会在表单进入 DOM 之前被激活。

<script type="text/javascript">
    $(document).ready(function()
        $("#frm").submit(function (event)  
            var form = $(evt.currentTarget);

            if(!form.validate().valid()) // you'll need to check this line
                return false;

             PerformTask();
             event.preventDefault();
             return false;
        );

    );
</script> 

我认为您的第一个表单正在执行完整的回发。如果您在提交表单时监视 chrome 中的网络选项卡,如果您看到它是由 jquery 或类似的东西请求的,那么您知道您正在执行部分回发。

【讨论】:

以上是关于Javascript 事件处理程序未拦截表单提交的主要内容,如果未能解决你的问题,请参考以下文章

HTML表单提交未在Wordpress帖子中调用Javascript“onsubmit”处理程序[重复]

html/javascript onsubmit 事件未在表单提交上调用以验证表单

jQuery拦截表单提交到参数字符串

回发后未选中复选框

jQuery:表单提交 - 多个事件处理程序

JavaScript基础教程—处理事件