【问题标题】:Put Form contents into list for MVC将表单内容放入 MVC 列表
【发布时间】:2020-08-02 04:53:27
【问题描述】:

我的页面包含一个主表单和多个较小的重复表单。我正在尝试使用带有 JQuery 的一个按钮来发布它们,并按以下顺序处理它们:首先是主表单,然后是较小的表单。但是,当我尝试访问较小的表单时,我只从最后一个表单中获取数据。我在想最好的方法是将较小的表单放入列表中,将其传递给我的处理程序,然后在列表中执行 foreach 循环。在我的处理程序使用它之前,我如何将表单信息放入列表中? 这是我的模型:

public class SubmitModel
    { 
        [BindProperty]
        public Timelineinfo Timelineinfo { get; set; } //main form
        [BindProperty]
        public Media Medias { get; set; }//small form       
    }

我的控制器:

        [HttpPost]
        [Route("/Submit/Submit")]
        [ValidateAntiForgeryToken] //Main form handler
        public async Task<IActionResult> Submit(SubmitModel model)
        {           
            if (ModelState.IsValid)
            {
                //Removed for brevity, but
                //Fill out some more values in main form then submit main form to Database,
            }           
            return View("Pages/Submit.cshtml", model);
        }

      
        [Route("/Submit/MediaAdd")]
        [ValidateAntiForgeryToken] //Add media form handler
        public async Task<IActionResult> MediaAdd(SubmitModel model)
        {
            if (ModelState.IsValid)
            {
               //Removed for brevity, but
               //Fill out some more values in small form then submit small form to Database
            }            
            return View("Pages/Submit.cshtml", model);
        }

还有我的小表单的截断版本(主表单看起来很相似,但使用Submit 而不是MediaAdd

@using (Html.BeginForm("MediaAdd", "Timeline", FormMethod.Post))
{  
    @Html.AntiForgeryToken()
    <div class="container">
        <div class="form-row">
            <label asp-for="Medias.Blurb" class="control-label">Blurb<span class="text-danger ml-1">*</span> <span class="text-muted ml-1">Explain what is in the media</span></label>
            <input asp-for="Medias.Blurb" class="form-control" />
            <span asp-validation-for="Medias.Blurb" class="text-danger"></span>
        </div>
        <div class="form-row">
            <div class="ml-3 col-4">
                <label class="form-check-label">Is there any blood or gore in the video?<span class="text-danger ml-1">*</span></label>
                <div class="form-check m-2 d-inline">
                    <input type="radio" asp-for="Medias.Gore" class="form-check-input" value="0">
                    <label class="form-check-label">No</label>
                </div>
                <div class="form-check m-2 d-inline">
                    <input type="radio" asp-for="Medias.Gore" class="form-check-input" value="1" />
                    <label class="form-check-label">Yes</label>
                    <span asp-validation-for="Medias.Gore" class="text-danger"></span>
                </div>
            </div>
        </div>
    </div>
}

最后,我目前如何提交表单:

$('#submitButton').click(function () {
  $('form').submit();
});

【问题讨论】:

  • 为什么要提交jquery?您可以通过表单的提交按钮来完成。是的,在一个模型中组合表单数据是正确的方法。现在有什么问题吗?
  • 我想通过单击一个提交按钮将它们一起提交,据我所知,这是这样做的方法
  • 你把提交按钮放在哪里了?对于通过Html.BeginForm 提交的表单,以下链接会有所帮助aspsnippets.com/Articles/…
  • 抱歉,我真的看不出那个链接有什么帮助,表单都在提交,但是因为它们不在列表中,所以小表单会相互覆盖。

标签: c# jquery asp.net-mvc asp.net-core


【解决方案1】:

我根据你的要求做了一个例子,你可以参考一下:

型号:

public class SubmitModel
{
    [BindProperty]
    public Timelineinfo Timelineinfo { get; set; } 
    [BindProperty]
    public List<Media> Medias { get; set; }
}

public class Timelineinfo
{
    public int TimeId { get; set; }
    public string Description { get; set; }
}

public class Media
{
    public string Blurb { get; set; }
    public string Gore { get; set; }
}

主窗体视图(索引):

@model SubmitModel

<button id="AddMedia" type="button" class="btn btn-primary">Add Media</button>

@using (Html.BeginForm("MediaAdd", "Timeline", FormMethod.Post))
{
    <div class="container">
        <div class="form-row">
            <label asp-for="Timelineinfo.TimeId" class="control-label">TimeId</label>
            <input asp-for="Timelineinfo.TimeId" class="form-control" />
        </div>
        <div class="form-row">
            <label asp-for="Timelineinfo.Description" class="control-label">Description</label>
            <input asp-for="Timelineinfo.Description" class="form-control" />
        </div>
    </div>

    <div id="subformsArea">

    </div>

    <div>
        <input type="submit" value="submit" class="btn btn-primary" />
    </div>
}

@section scripts{ 
<script>
    var count = 0;
    $("#AddMedia").on('click', function () {
        $.ajax({
            url: '/Timeline/Media',
            method: 'get',
            data: {data : count},
            success: function (result) {
                $("#subformsArea").append(result);
                count++;
            }
        })

    })
</script>

}

子表单视图(部分视图):

@model SubmitModel

@{ 
    int i = ViewBag.Count;
}

<div class="container">
    <div class="form-row">
        <label asp-for="Medias[i].Blurb" class="control-label">Blurb<span class="text-danger ml-1">*</span> <span class="text-muted ml-1">Explain what is in the media</span></label>
        <input asp-for="Medias[i].Blurb" class="form-control" />
        <span asp-validation-for="Medias[i].Blurb" class="text-danger"></span>
    </div>
    <div class="form-row">
        <div class="ml-3 col-4">
            <label class="form-check-label">Is there any blood or gore in the video?<span class="text-danger ml-1">*</span></label>
            <br />
            <div class="form-check m-2 d-inline">
                <input type="radio" asp-for="Medias[i].Gore" class="form-check-input" value="0">
                <label class="form-check-label">No</label>
            </div>
            <div class="form-check m-2 d-inline">
                <input type="radio" asp-for="Medias[i].Gore" class="form-check-input" value="1" />
                <label class="form-check-label">Yes</label>
                <span asp-validation-for="Medias[i].Gore" class="text-danger"></span>
            </div>
        </div>
    </div>
</div>

控制器:

public class TimelineController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [Route("/Submit/MediaAdd")]
    [ValidateAntiForgeryToken] //Add media form handler
    public IActionResult MediaAdd(SubmitModel model)
    {
        if (ModelState.IsValid)
        {
            //Removed for brevity, but
            //Fill out some more values in small form then submit small form to Database
        }
        return View("Pages/Submit.cshtml", model);
    }

    public IActionResult Media(int data)
    {
        ViewBag.Count = data;
        return PartialView();
    }
}

结果:

【讨论】:

  • 非常感谢,这很好用。过去我花了太多时间尝试建立一个更笨重的方法。
  • 实际上,我不知道为什么,但是当我运行您的代码并按下添加媒体按钮时,我相当于您的 MediaAdd 方法正在触发。
  • 确保按钮 id AddMedia 是唯一的,并且 ajax url 是正确的。
  • 对不起,我应该更清楚一点,我正在让新表单出现,但在它中断后立即出现。因此,get new form 方法运行良好,但在它运行之后,MediaAdd 函数也会运行,但它不应该运行。 imgur.com/a/Um5Bu8k
  • 一头雾水,不是我这边发生的,有没有其他脚本可以触发提交动作。
【解决方案2】:

这就是我的做法。越简单越好:

<form action='myAction' method='postOrGet'>
//subform 1
<input name='inputA' subform='s1'.../>
//subform 2
<input name='inputX' subform='s2'.../>
...
<button type='submit'>submit</button>
</form>

然后您可以根据“子表单”属性(s1,s2.等)轻松分离提交的数据

【讨论】:

  • 不幸的是,我认为我做不到。小表单的数量是未知的,用户可以添加或删除他们想要的任意数量。我正在生成从 ajax 请求到部分的每个小表单,因此我不能拥有单独的识别功能。
  • @Bubinga 如果加载多个局部视图会出现问题,因为子表单中有一个单选按钮,如果您向主表单添加两个或多个子表单,那么您只需选择一个单选按钮因为它们具有相同的 name 属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 2011-07-06
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多