web-dev-qa-db-ja.com

送信ボタンではなくJavaScriptを使用してASP.NET MVC Ajaxフォームを投稿する方法

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送信はこれをバイパスしているようです。

PS。この特定のアプローチで解決策を探しています。通常のフォームを使用して同じことを実現し、AJAX + jQueryを使用して投稿する方法を知っています。しかし、この特定のソリューションに興味があります。

43
mfloryan

セレクターの周りの引用符の欠如は、単なる文字起こしエラーであると想定しますが、とにかくチェックする必要があります。また、フォームに実際にIDを提供している場所がわかりません。通常、これはhtmlAttributesパラメーターを使用して行います。あなたはそれを持っている署名を使用して見ていません。繰り返しますが、フォームがまったく送信されていない場合、これは文字起こしエラーである可能性があります。

セレクターとIDが問題でない場合は、Ajax BeginForm拡張機能を使用するときにクリックハンドラーがマークアップを介して追加されることが原因であると思われます。 $( 'form')。trigger( 'submit')を使用するか、最悪の場合、アンカーのクリックハンドラーにフォームに非表示の送信ボタンを作成させてクリックさせます。または、純粋なjQueryを使用して独自のAjaxサブミッションを作成することもできます(これはおそらく私が行うことです)。

最後に、送信ボタンを置き換えることで、javascriptが有効になっていない人のためにこれを完全に破ることに気付く必要があります。これを回避するには、noscriptタグを使用してボタンを非表示にし、サーバー上のAJAXと非AJAX投稿の両方を処理します。

ところで、マークアップ経由ではなくjavascript経由でハンドラーを追加することは、Microsoftが承諾していない標準的な慣行と考えています。これにより、JavaScriptが1か所に整理されるため、フォームで何が起こっているかをより簡単に確認できます。トリガーメカニズムの使用例を次に示します。

  $(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>
<% } %>
38
tvanfosson

ドロップダウンリストの変更がajax form-submitをトリガーしてデータグリッドをリロードする単純な例:

<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関数を呼び出します。

NB。 UserSearchResultsコントローラーは、指定されたモデルを使用してテーブルをレンダリングするPartialViewを返します

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

残念ながら、すべてのブラウザでonsubmitイベントまたはsubmitイベントをトリガーすることはできません。

  • IE and Chrome:#( 'form#ajaxForm')trigger( 'onsubmit');
  • FirefoxおよびSafariで動作:#( 'form#ajaxForm')trigger( 'submit');

また、ChromeまたはIEでtrigger( '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> 
<% } %>

また、これを機能させるために、リンクをフォームに含める必要はありません。

6
Brian Reiter

私はajaxフォームの送信がうまく機能するように何回か試みましたが、常に完全な失敗または多すぎる妥協のいずれかに遭遇しました。以下は、MVCページ内で jQuery Formプラグイン を使用して、ユーザーが入力ボックスに入力するときにプロジェクトのリストを(部分的にレンダリングされたコントロールを使用して)更新するページの例です。

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

Ajax.BeginFormは失敗したようです。

通常のHtml.Beginを使用して、これはうまく機能します。

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

次の方法を試してください。

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

Ajax.BeginForm内に通常のボタンを配置し、クリックすると親フォームを検索して通常の送信を行います。 Razorの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>
    }

およびJavaScript:

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

    $formToSubmit.submit();
}
0

JavaScriptを使用するのではなく、次のようなことを試してください。

<a href="#">

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

</a>
0
Benjamin