【问题标题】:MVC 5 Ajax form with field updates asynchronously and still supporting a Full form post具有异步字段更新的 MVC 5 Ajax 表单,但仍支持完整表单帖子
【发布时间】:2015-11-12 00:19:15
【问题描述】:

所以我使用 MVC 已经有一段时间了,但使用 Ajax 的次数不多。 所以我遇到的问题是我有一个创建视图,其中创建视图的第一个字段是一个日期选择器,在更改时我希望 ajax 更改表单上另一个字段的选择下拉列表。我有 Ajax 更新工作,但表单 Post(创建按钮)现在只调用控制器上的 Ajax 方法。我希望 Ajax 回帖调用 Controller 上的默认方法 Create 方法。所以创建表单包含 3 个字段

  1. 日期(提交 OnChange Ajax)
  2. ID 和文本的下拉列表
  3. 其他必填字段

我已经包含了模型和 cshtml 视图文件(其中一个)。控制器只是一种获取日期时间值或整个模型的方法。 所以我的代码在哪里工作,当日期更改时,它会更新相关的 LocalIds 字段,但是因为“创建”按钮位于 Ajax.BeginForm 标记内,所以当按下创建按钮时,它会生成一个 Ajax 调用,我想要它生成一个表单帖子。我错过了什么

创建模型

public class IdsSelection
{
    public string Id { get; set; }
    public List<SelectListItem> Selections { get; set; }
}

public class CreateModel
{
    [Display(Name="Local Id's")]
    public IdsSelection LocalIds;
    [Display(Name="Day")]
    [Required, DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",ApplyFormatInEditMode=true)]
    public DateTime Date { get; set; }
    [Required, Display(Name = "Other Value")]
    [Range(1.0, 1000000.0, ErrorMessage ="Value must be greater than zero")]
    public decimal OtherValue { get; set; }

    public CreateModel()
    {
        Date = DateTime.Today;
    }
}

CreateView.cshtml

@Model Demo.Models.CreateModel
....
@using (Ajax.BeginForm("ChangeDate", "Process", new AjaxOptions()
{
    InsertionMode = InsertionMode.Replace,
    HttpMethod = "GET",
    UpdateTargetId = "changeid",
}))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Date, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Date, new
           {
               htmlAttributes = new
               {
                   autofocus = "autofocus",
                   @class = "form-control",
                   @Value = Model.Date.ToString("yyyy-MM-dd"),
                   onchange = "$(this.form).submit();"
               }
           })
            @Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" })
            </div>
        </div>

        @Html.Partial("_ShowIds", Model.LocalIds)

        <div class="form-group">
            @Html.LabelFor(model => model.OtherValue, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.OtherValue, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.OtherValue, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
}

_ShowIds.cshtml

@model Demo.Models.IdsSelection

<div id="changeid" class="form-group">
    @Html.Label("Local Id", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">

        @if(Model.Selections.Count == 1)        // one
        {
            @Html.HiddenFor(model => model.Id)
            @Html.EditorFor(model => model.Selections[0].Text, new
            {
                htmlAttributes = new
                {
                    @class = "form-control",
                    @readonly = "readonly",
                }
            })
        }
        else            // more entries so show a dropdown
        {
            @Html.DropDownListFor(model => model.Id, Model.Selections, new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model, "", new { @class = "text-danger" })
        }
        </div>
    </div>

【问题讨论】:

  • 使用普通表单提交并使用jQuery.ajax 调用单独的服务器方法,该方法根据所选日期更新DOM
  • 是的,这是我不明白的。这是 Javascript 调用吗?
  • 是的。从您的日期选择器中删除 onchange 事件并添加一个脚本 - $('#Date').change(function() { // make ajax call to update the existing DOM });
  • 我确实尝试过这个,但 javascript 似乎没有被解雇(在日期更改时)???我什至包括了 jQuery 脚本,以为我可能没有它
  • 你看到我发布的答案了吗?如果它没有触发,您在浏览器控制台中看到了什么错误?

标签: ajax asp.net-mvc


【解决方案1】:

您没有向您展示控制器方法,但假设生成此视图的方法名为Create(),然后创建相应的 POST 方法

[httpPost]
public ActionResult Create(CreateModel model)

用于保存数据。删除@using (Ajax.BeginForm("ChangeDate", "Process", new AjaxOptions() { ..... ]))并替换为正常形式回传到服务器(你可以删除jquery.unobtrusive-ajax.min.js

@using (Html.BeginForm())
{
    ....

接下来创建一个控制器方法,根据所选日期返回部分视图

public PartialViewResult FetchLocalIds(DateTime date)
{
  IdsSelection model = // populate model based on selected date
  return PartialView("_ShowIds", model);
}

接下来,在视图中,将当前的@Html.Partial() 包装在一个占位符元素中

<div id="localids">
    @Html.Partial("_ShowIds", Model.LocalIds)
</div>

然后使用 jquery 处理 datepickers .change() 事件并调用 FetchLocalIds() 方法使用 .load() 函数更新 DOM。

$('#Date').change(function() {
  $('#localids').load('@Url.Action("FetchLocalIds")', { date: $(this).val() })
})

还要注意从@Html.EditorFor(model =&gt; model.Date, new { ... }) 中删除onchange = "$(this.form).submit();"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2019-04-23
    • 2022-11-25
    • 2018-10-16
    • 1970-01-01
    • 2022-01-26
    • 2017-07-23
    相关资源
    最近更新 更多