如何使用 JavaScript 而不是提交按钮发布 ASP.NET MVC Ajax 表单

IT技术 javascript asp.net-mvc asp.net-ajax jquery
2021-02-24 16:05:56

我有一个使用创建的简单表单Ajax.BeginForm

<% using (Ajax.BeginForm("Update", "Description", new { id = Model.Id },
     new AjaxOptions
     {
       UpdateTargetId = "DescriptionDiv",
       HttpMethod = "post"
     },new {id ='AjaxForm' })) {%>
Description:
<%= Html.TextBox("Description", Model.Description) %><br />
<input type="submit" value="save" />
<% }%>

控制器已连接并返回更新DescriptionDiv. 这一切都很好。

现在我希望能够在没有提交按钮的情况下提交此表单(通过点击链接或图像或其他任何东西)。不幸的是,这个小小的 jQuery 代码片段并没有完成这项工作:

$('form#AjaxForm').submit();

它确实提交了表单,但是(我想这并不奇怪)是常规的回传而不是 Ajax 的回传。

为了简单起见,上面的 jQuery 是这样连接的:

<a href="#" onclick="$('form#AjaxForm').submit(); return false;">submit</a>

表单的 onsubmit 正在使用 Sys.Mvc.AsyncForm.handleSubmit() 但 jQuery submit 似乎绕过了这一点。

附注。我正在寻找这种特定方法的解决方案。我知道如何使用普通表单实现相同的功能并使用 AJAX+jQuery 发布它。不过,我对这个特定的解决方案感兴趣。

6个回答

我将假设您在选择器周围缺少引号只是转录错误,但无论如何您都应该检查它。另外,我没有看到您实际上在哪里为表单提供了 id。通常您使用 htmlAttributes 参数执行此操作。我没有看到你使用拥有它的签名。不过,如果表单完全提交,这可能是转录错误。

如果选择器和 id 不是问题,我怀疑这可能是因为在您使用 Ajax BeginForm 扩展时通过标记添加了点击处理程序。您可以尝试使用 $('form').trigger('submit') 或者在最坏的情况下,让锚点上的单击处理程序在表单中创建一个隐藏的提交按钮并单击它。或者甚至使用纯 jQuery 创建您自己的 ajax 提交(这可能是我会做的)。

最后,您应该意识到,通过替换提交按钮,对于没有启用 javascript 的人来说,您将完全打破这一点。解决这个问题的方法是使用 noscript 标签隐藏一个按钮,并处理服务器上的 AJAX 和非 AJAX 帖子。

顺便说一句,微软不考虑通过javascript而不是通过标记添加处理程序,这是一种标准做法。这将您的 javascript 组织在一个地方,以便您可以更轻松地查看表单上发生的事情。这是我将如何使用触发机制的示例。

  $(function() {
      $('form#ajaxForm').find('a.submit-link').click( function() {
           $('form#ajaxForm').trigger('submit');
      }).show();
  }

<% using (Ajax.BeginForm("Update", "Description", new { id = Model.Id },
     new AjaxOptions
     {
       UpdateTargetId = "DescriptionDiv",
       HttpMethod = "post"
     }, new { id = "ajaxForm" } )) {%>
   Description:
   <%= Html.TextBox("Description", Model.Description) %><br />
   <a href="#" class="submit-link" style="display: none;">Save</a>
   <noscript>
       <input type="submit" value="Save" />
   </noscript>
<% } %>
如果差异是 .submit() 到 .trigger('submit');,则不能解决问题。
2021-04-24 16:05:56
加载 jquery.unobtrusive-ajax.(min.)js 对我也有帮助。
2021-05-06 16:05:56
感谢您的意见。这一切都是有道理的 - 我快速地将示例放在一起,因此表单没有引号和显式 Id(它们存在于实际应用程序中)。事实上,用 jQuery 来做这一切更清晰,但目前还不是一个选择。
2021-05-13 16:05:56
$('form#ajaxForm').submit();使用 jQuery 1.4.4 和 MVC 3 为我工作。但我花了很长时间才弄清楚您需要引用一些脚本文件,否则这将回退到常规回传。这些文件在我的情况下:jquery.unobtrusive-ajax.(min.)js + MicrosoftAjax 和 MicrosoftMvcAjax
2021-05-18 16:05:56
实际上,这不适用于所有浏览器。它适用于 Safari 和 Firefox,但不适用于 IE 和 Chrome。在 Safri/Firefox 中触发 'submit' 事件在 Chrome/IE 中起作用,触发 'onsubmit' 起作用并触发 'submit' 实际上会导致传统的非 ajax 帖子发生。
2021-05-19 16:05:56

一个简单的例子,下拉列表上的更改触发 ajax 表单提交以重新加载数据网格:

<div id="pnlSearch">

    <% using (Ajax.BeginForm("UserSearch", "Home", new AjaxOptions { UpdateTargetId = "pnlSearchResults" }, new { id="UserSearchForm" }))
    { %>

        UserType: <%: Html.DropDownList("FilterUserType", Model.UserTypes, "--", new { onchange = "$('#UserSearchForm').trigger('submit');" })%>

    <% } %>

</div>

trigger('onsubmit') 是关键:它调用 MVC 嫁接到表单上的 onsubmit 函数。

注意。UserSearchResults 控制器返回一个 PartialView,它使用提供的模型呈现表格

<div id="pnlSearchResults">
    <% Html.RenderPartial("UserSearchResults", Model); %>
</div>
好吧,我尝试了您的解决方案并使用onsubmit引发了 JS 错误,使用submit没有。就那么简单。不过我并没有真正考虑太多。
2021-04-24 16:05:56
@Abel 你确定你的编辑吗?我记得当时它是非常明确的触发器('onsubmit'),而不是触发器('提交')。
2021-05-02 16:05:56

不幸的是,触发 onsubmit 或 submit 事件不适用于所有浏览器。

  • 适用于 IE 和 Chrome:#('form#ajaxForm')trigger('onsubmit');
  • 适用于 Firefox 和 Safari:#('form#ajaxForm')trigger('submit');

此外,如果您在 Chrome 或 IE 中触发 ('submit'),它会导致发布整个页面而不是执行 AJAX 行为。

适用于所有浏览器的方法是删除 onsubmit 事件行为并仅在表单本身上调用 submit()

<script type="text/javascript">
$(function() {

    $('form#ajaxForm').submit(function(event) { 
        eval($(this).attr('onsubmit')); return false; 
        });

    $('form#ajaxForm').find('a.submit-link').click( function() { 
        $'form#ajaxForm').submit();
        });

  }
</script>
  <% using (Ajax.BeginForm("Update", "Description", new { id = Model.Id },
     new AjaxOptions
     {
       UpdateTargetId = "DescriptionDiv",
       HttpMethod = "post"
     }, new { id = "ajaxForm" } )) {%>
   Description:
   <%= Html.TextBox("Description", Model.Description) %><br />
   <a href="#" class="submit-link">Save</a> 
<% } %>

此外,链接不一定要包含在表单中才能使其工作。

一个 Eval,真的吗?那是安全噩梦。为什么这如此困难?
2021-05-16 16:05:56

我已经尝试过几次让 ajax 表单提交工作得很好,但总是遇到完全失败或太多妥协。下面是一个页面示例,它使用MVC 页面内jQuery 表单插件在用户在输入框中键入内容时更新项目列表(使用部分呈现的控件):

<div class="searchBar">
    <form action="<%= Url.Action ("SearchByName") %>" method="get" class="searchSubmitForm">
        <label for="projectName">Search:</label>
        <%= Html.TextBox ("projectName") %>
        <input class="submit" type="submit" value="Search" />
    </form>
</div>
<div id="projectList">
    <% Html.RenderPartial ("ProjectList", Model); %>
</div>

<script type="text/javascript">
    jQuery(document).ready(function() {
        jQuery("#projectName").keyup(function() {
            jQuery(".searchSubmitForm").submit();
        });

        jQuery(".searchSubmitForm").submit(function() {
            var options = {
                target : '#projectList'
            }

            jQuery(this).ajaxSubmit(options);

            return false;
        });

        // We remove the submit button here - good Javascript depreciation technique
        jQuery(".submit").remove();
    });
</script>

在控制器端:

public ActionResult SearchByName (string projectName)
{
    var service = Factory.GetService<IProjectService> ();
    var result = service.GetProjects (projectName);

    if (Request.IsAjaxRequest ())
        return PartialView ("ProjectList", result);
    else
    {
        TempData["Result"] = result;
        TempData["SearchCriteria"] = projectName;

        return RedirectToAction ("Index");
    }
}

public ActionResult Index ()
{
    IQueryable<Project> projects;
    if (TempData["Result"] != null)
        projects = (IQueryable<Project>)TempData["Result"];
    else
    {
        var service = Factory.GetService<IProjectService> ();
        projects = service.GetProjects ();
    }

    ViewData["projectName"] = TempData["SearchCriteria"];

    return View (projects);
}
感谢您提供此示例,但我正试图深入了解这个特定问题 - 正如我所指出的,我有一个使用 jQuery 的替代解决方案,但我无法使用它。
2021-04-23 16:05:56

Ajax.BeginForm 看起来失败了。

使用常规的 Html.Begin for,这很好地完成了这个技巧:

$('#detailsform').submit(function(e) {
    e.preventDefault();
    $.post($(this).attr("action"), $(this).serialize(), function(r) {
        $("#edit").html(r);
    });
});