Как опубликовать ASP.NET MVC Ajax форму, используя JavaScript вместо кнопки отправки - PullRequest
43 голосов
/ 20 августа 2009

У меня есть простая форма, созданная с использованием 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>

При отправке формы используется Sys.Mvc.AsyncForm.handleSubmit (), но отправка jQuery, похоже, обходит это.

PS. Я ищу решение в этом конкретном подходе. Я знаю, как добиться того же, используя обычную форму и публикуя ее, используя AJAX + jQuery. Я заинтересован в этом конкретном решении, хотя.

Ответы [ 8 ]

38 голосов
/ 20 августа 2009

Я собираюсь предположить, что отсутствие кавычек вокруг селектора является просто ошибкой транскрипции, но вы все равно должны это проверить. Кроме того, я не вижу, где вы на самом деле даете форме идентификатор. Обычно вы делаете это с параметром htmlAttributes. Я не вижу, чтобы вы использовали подпись, которая имеет это. Опять же, если форма отправляется вообще, это может быть ошибкой транскрипции.

Если селектор и идентификатор не являются проблемой, я подозреваю, что это может быть связано с тем, что обработчик кликов добавляется через разметку при использовании расширения Ajax BeginForm. Вы можете попробовать использовать $ ('form'). Trigger ('submit') или, в худшем случае, заставить обработчик щелчка на привязке создать скрытую кнопку отправки в форме и щелкнуть ее. Или даже создайте свою собственную ajax-заявку, используя чистый jQuery (что, вероятно, я бы и сделал).

Наконец, вы должны понимать, что заменив кнопку отправки, вы полностью сломаете это для людей, у которых не включен JavaScript. Чтобы обойти это, нужно также скрыть кнопку с помощью тега noscript и обрабатывать как AJAX, так и не AJAX-сообщения на сервере.

Кстати, считается стандартной практикой, Microsoft не выдерживает, добавлять обработчики через 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>
<% } %>
7 голосов
/ 27 июля 2010

Простой пример, когда изменение в раскрывающемся списке запускает отправку формы 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>

Триггер ('onsubmit') является ключевым моментом: он вызывает функцию onsubmit, которую MVC ввел в форму.

NB. Контроллер UserSearchResults возвращает PartialView, который отображает таблицу с использованием предоставленной модели

<div id="pnlSearchResults">
    <% Html.RenderPartial("UserSearchResults", Model); %>
</div>
6 голосов
/ 04 января 2011

К сожалению, запуск событий onsubmit или submit не будет работать во всех браузерах.

  • Работает в IE и Chrome: триггер # ('form # ajaxForm') ('onsubmit');
  • Работает в Firefox и Safari: триггер # ('form # ajaxForm') ('submit');

Кроме того, если вы запускаете ('submit') в Chrome или IE, это приводит к публикации всей страницы, а не к поведению 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> 
<% } %>

Кроме того, чтобы это работало, ссылка не должна содержаться в форме.

3 голосов
/ 20 августа 2009

Я несколько раз пытался заставить отправку формы ajax работать нормально, но всегда сталкивался либо с полным провалом, либо со слишком большим количеством компромиссов. Вот пример страницы, которая использует плагин jQuery Form внутри страницы MVC для обновления списка проектов (с использованием частично визуализированного элемента управления) в качестве пользовательских типов в поле ввода:

<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);
}
2 голосов
/ 20 марта 2012

Попробуйте следующим образом:

<input type="submit" value="Search" class="search-btn" />
<a href="javascript:;" onclick="$('.search-btn').click();">Go</a>
2 голосов
/ 16 сентября 2011

Ajax.BeginForm выглядит как сбой.

Используя обычный Html.Begin для, это просто отлично работает:

$('#detailsform').submit(function(e) {
    e.preventDefault();
    $.post($(this).attr("action"), $(this).serialize(), function(r) {
        $("#edit").html(r);
    });
}); 
0 голосов
/ 09 декабря 2016

Просто поместите обычную кнопку рядом с Ajax.BeginForm и при нажатии найдите родительскую форму и отправьте сообщение. Форма Ajax в Razor:

@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 голосов
/ 15 сентября 2010

Вместо использования JavaScript, возможно, попробуйте что-то вроде

<a href="#">

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

</a>
...