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

时间:2022-11-23 14:20:14

I have a simple form created using Ajax.BeginForm:

我有一个使用ajax创建的简单表单。

<% 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" />
<% }%>

The controller is wired up and returns a partial view that updates the DescriptionDiv. And it all works neatly.

连接控制器并返回更新DescriptionDiv的部分视图。这一切都很巧妙。

Now I would like to be able to submit this form without having the submit button (via a clik on a link or on an image or whatever). Unfortunately this little jQuery snippet does not do the job:

现在,我希望能够提交这个表单,而不需要提交按钮(通过链接或图像的剪辑)。不幸的是,这个小小的jQuery代码片段并没有起到作用:

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

It does submit the form, but does (I suppose not surprisingly) a regular post-back and not an Ajax one.

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

For the sake of simplicity the above jQuery is wired up like this:

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

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

The form's onsubmit is using the Sys.Mvc.AsyncForm.handleSubmit() but the jQuery submit seems to be bypassing this.

表单的onsubmit使用的是Sys.Mvc.AsyncForm.handleSubmit(),但是jQuery submit似乎绕过了这个问题。

PS. I am looking for a solution in this particular approach. I know how to achieve the same using a normal form and posting it using AJAX+jQuery. I am interested in this particular solution though.

我正在寻找这种方法的解决方案。我知道如何使用一个普通的表单并使用AJAX+jQuery发布它。我对这个特殊的解很感兴趣。

8 个解决方案

#1


37  

I'm going to assume that your lack of quotes around the selector is just a transcription error, but you should check it anyway. Also, I don't see where you are actually giving the form an id. Usually you do this with the htmlAttributes parameter. I don't see you using the signature that has it. Again, though, if the form is submitting at all, this could be a transcription error.

我假设你在选择器周围缺少引号只是一个转录错误,但是你应该检查它。另外,我不知道您实际上在什么地方给表单一个id,通常您是用htmlAttributes参数来这样做的。我没看到你在用签名。同样,如果表单提交了,这可能是一个转录错误。

If the selector and the id aren't the problem I'm suspicious that it might be because the click handler is added via markup when you use the Ajax BeginForm extension. You might try using $('form').trigger('submit') or in the worst case, have the click handler on the anchor create a hidden submit button in the form and click it. Or even create your own ajax submission using pure jQuery (which is probably what I would do).

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

Lastly, you should realize that by replacing the submit button, you're going to totally break this for people who don't have javascript enabled. The way around this is to also have a button hidden using a noscript tag and handle both AJAX and non-AJAX posts on the server.

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

BTW, it's consider standard practice, Microsoft not withstanding, to add the handlers via javascript not via markup. This keeps your javascript organized in one place so you can more easily see what's going on on the form. Here's an example of how I would use the trigger mechanism.

顺便说一句,考虑到标准的做法,微软不受限制,通过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>
<% } %>

#2


7  

A simple example, where a change on a dropdown list triggers an ajax form-submit to reload a datagrid:

一个简单的例子,下拉列表上的更改触发一个ajax表单提交来重新加载一个datagrid:

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

The trigger('onsubmit') is the key thing: it calls the onsubmit function that MVC has grafted onto the form.

触发器('onsubmit')是关键:它调用MVC已经嫁接到窗体上的onsubmit函数。

NB. The UserSearchResults controller returns a PartialView that renders a table using the supplied Model

NB。UserSearchResults控制器返回使用提供的模型呈现表的PartialView

<div id="pnlSearchResults">
    <% Html.RenderPartial("UserSearchResults", Model); %>
</div>

#3


6  

Unfortunately triggering the onsubmit or submit events wont work in all browsers.

不幸的是,触发onsubmit或submit事件在所有浏览器中都不起作用。

  • Works in IE and Chrome: #('form#ajaxForm')trigger('onsubmit');
  • 在IE和Chrome中工作:#('form#ajaxForm')触发器('onsubmit');
  • Works in Firefox and Safari: #('form#ajaxForm')trigger('submit');
  • 在Firefox和Safari中工作:#('form#ajaxForm')触发器('submit');

Also, if you trigger('submit') in Chrome or IE, it causes the entire page to be posted rather than doing an AJAX behavior.

此外,如果在Chrome或IE中触发(“提交”),则会导致整个页面被发布,而不是执行AJAX行为。

What works for all browsers is removing the onsubmit event behavior and just calling submit() on the form itself.

对所有浏览器都有效的方法是删除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> 
<% } %>

Also, the link doesn't have to be contained within the form in order for this to work.

而且,链接不必包含在表单中,这样才能让它工作。

#4


3  

I've tried a few times to get the ajax form submit working nicely, but always met with either complete failure or too many compromises. Here's an example of page that uses the jQuery Form plug-in inside of a MVC page to update a list of projects (using a partially rendered control) as the user types in an input box:

我已经尝试了几次,以使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>

And on the controller side:

在控制器端:

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

#5


2  

Ajax.BeginForm looks to be a fail.

Ajax。BeginForm看起来是一个失败。

Using a regular Html.Begin for, this does the trick just nicely:

使用一个普通的Html。首先,这个技巧很好:

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

#6


2  

Try the following way:

尝试以下方法:

<input type="submit" value="Search" class="search-btn" />
<a href="javascript:;" onclick="$('.search-btn').click();">Go</a>

#7


0  

Rather than using JavaScript perhaps try something like

与其使用JavaScript,不如试试类似的东西

<a href="#">

  <input type="submit" value="save" style="background: transparent none; border: 0px none; text-decoration: inherit; color: inherit; cursor: inherit" />

</a>

#8


0  

Simply place normal button indide Ajax.BeginForm and on click find parent form and normal submit. Ajax form in Razor:

只需将普通按钮放置到Ajax中。BeginForm和点击查找父表单和常规提交。在剃须刀Ajax表单:

@using (Ajax.BeginForm("AjaxPost", "Home", ajaxOptions))
    {        
        <div class="form-group">
            <div class="col-md-12">

                <button class="btn btn-primary" role="button" type="button" onclick="submitParentForm($(this))">Submit parent from Jquery</button>
            </div>
        </div>
    }

and Javascript:

和Javascript:

function submitParentForm(sender) {
    var $formToSubmit = $(sender).closest('form');

    $formToSubmit.submit();
}

#1


37  

I'm going to assume that your lack of quotes around the selector is just a transcription error, but you should check it anyway. Also, I don't see where you are actually giving the form an id. Usually you do this with the htmlAttributes parameter. I don't see you using the signature that has it. Again, though, if the form is submitting at all, this could be a transcription error.

我假设你在选择器周围缺少引号只是一个转录错误,但是你应该检查它。另外,我不知道您实际上在什么地方给表单一个id,通常您是用htmlAttributes参数来这样做的。我没看到你在用签名。同样,如果表单提交了,这可能是一个转录错误。

If the selector and the id aren't the problem I'm suspicious that it might be because the click handler is added via markup when you use the Ajax BeginForm extension. You might try using $('form').trigger('submit') or in the worst case, have the click handler on the anchor create a hidden submit button in the form and click it. Or even create your own ajax submission using pure jQuery (which is probably what I would do).

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

Lastly, you should realize that by replacing the submit button, you're going to totally break this for people who don't have javascript enabled. The way around this is to also have a button hidden using a noscript tag and handle both AJAX and non-AJAX posts on the server.

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

BTW, it's consider standard practice, Microsoft not withstanding, to add the handlers via javascript not via markup. This keeps your javascript organized in one place so you can more easily see what's going on on the form. Here's an example of how I would use the trigger mechanism.

顺便说一句,考虑到标准的做法,微软不受限制,通过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>
<% } %>

#2


7  

A simple example, where a change on a dropdown list triggers an ajax form-submit to reload a datagrid:

一个简单的例子,下拉列表上的更改触发一个ajax表单提交来重新加载一个datagrid:

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

The trigger('onsubmit') is the key thing: it calls the onsubmit function that MVC has grafted onto the form.

触发器('onsubmit')是关键:它调用MVC已经嫁接到窗体上的onsubmit函数。

NB. The UserSearchResults controller returns a PartialView that renders a table using the supplied Model

NB。UserSearchResults控制器返回使用提供的模型呈现表的PartialView

<div id="pnlSearchResults">
    <% Html.RenderPartial("UserSearchResults", Model); %>
</div>

#3


6  

Unfortunately triggering the onsubmit or submit events wont work in all browsers.

不幸的是,触发onsubmit或submit事件在所有浏览器中都不起作用。

  • Works in IE and Chrome: #('form#ajaxForm')trigger('onsubmit');
  • 在IE和Chrome中工作:#('form#ajaxForm')触发器('onsubmit');
  • Works in Firefox and Safari: #('form#ajaxForm')trigger('submit');
  • 在Firefox和Safari中工作:#('form#ajaxForm')触发器('submit');

Also, if you trigger('submit') in Chrome or IE, it causes the entire page to be posted rather than doing an AJAX behavior.

此外,如果在Chrome或IE中触发(“提交”),则会导致整个页面被发布,而不是执行AJAX行为。

What works for all browsers is removing the onsubmit event behavior and just calling submit() on the form itself.

对所有浏览器都有效的方法是删除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> 
<% } %>

Also, the link doesn't have to be contained within the form in order for this to work.

而且,链接不必包含在表单中,这样才能让它工作。

#4


3  

I've tried a few times to get the ajax form submit working nicely, but always met with either complete failure or too many compromises. Here's an example of page that uses the jQuery Form plug-in inside of a MVC page to update a list of projects (using a partially rendered control) as the user types in an input box:

我已经尝试了几次,以使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>

And on the controller side:

在控制器端:

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

#5


2  

Ajax.BeginForm looks to be a fail.

Ajax。BeginForm看起来是一个失败。

Using a regular Html.Begin for, this does the trick just nicely:

使用一个普通的Html。首先,这个技巧很好:

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

#6


2  

Try the following way:

尝试以下方法:

<input type="submit" value="Search" class="search-btn" />
<a href="javascript:;" onclick="$('.search-btn').click();">Go</a>

#7


0  

Rather than using JavaScript perhaps try something like

与其使用JavaScript,不如试试类似的东西

<a href="#">

  <input type="submit" value="save" style="background: transparent none; border: 0px none; text-decoration: inherit; color: inherit; cursor: inherit" />

</a>

#8


0  

Simply place normal button indide Ajax.BeginForm and on click find parent form and normal submit. Ajax form in Razor:

只需将普通按钮放置到Ajax中。BeginForm和点击查找父表单和常规提交。在剃须刀Ajax表单:

@using (Ajax.BeginForm("AjaxPost", "Home", ajaxOptions))
    {        
        <div class="form-group">
            <div class="col-md-12">

                <button class="btn btn-primary" role="button" type="button" onclick="submitParentForm($(this))">Submit parent from Jquery</button>
            </div>
        </div>
    }

and Javascript:

和Javascript:

function submitParentForm(sender) {
    var $formToSubmit = $(sender).closest('form');

    $formToSubmit.submit();
}