使用 jquery 从视图提交包含输入和 List<Model> 的表单到操作

Posted

技术标签:

【中文标题】使用 jquery 从视图提交包含输入和 List<Model> 的表单到操作【英文标题】:Submit form containing inputs and a List<Model> from view to action using jquery 【发布时间】:2014-03-22 10:10:35 【问题描述】:

我目前正在使用 jquery mobile 和 ASP.NET MVC 4 为 iPad 构建一个移动网站。我在视图上有两个表单 - 我们称它们为 FormA 和 FormB。每个表单都有用户输入和单独的提交。当FormA提交时,我也想提交FormB。 (但是,反之则不然——当用户提交 FormB 时,FormA 不应该提交——这就是它们分开的原因。)

两种形式都使用一个看起来(部分)像这样的模型:

public class MyModel

    [Display(Name = "ID Number:")]
    public string idNumber  get; set; 

    [Display(Name = "First Name:")]
    public string fName  get; set; 

    [Display(Name = "Equipment List:")]
    public IEnumerable<EquipmentModel> listOfEquipment  get; set; 



public class EquipmentModel

    [Display(Name = "Equipment ID:")]
    public string EquipID  get; set; 

    [Display(Name = "Equipment Type:")]
    public string EquipType  get; set; 

    [Display(Name = "Equipment Description:")]
    public string EquipDesc  get; set; 

    [Display(Name = "Equipment Usage Hours: ")]
    public string EquipUsageHours  get; set; 

    [Display(Name = "Added By:")]
    public string EquipAddedBy  get; set; 

    [Display(Name = "Add Date:")]
    public string EquipAddDate  get; set; 

    [Display(Name = "Costkey:")]
    public string EquipCostKey  get; set; 


FormB 如下所示(基本上显示了设备列表以及每件设备的相关使用时间。用户可以通过移动滑块来调整每件设备的使用时间):

       @using (html.BeginForm("ActionBName", "ControllerName", FormMethod.Post, new  id = "FormB" ))
        
            @Html.ValidationSummary(true)
            <input type="hidden" name="idNumber" value="@Model.idNumber"> 
            <input type="hidden" name="fName" value="@Model.fName">

            if (Model.listOfEquipment != null)
            
                int i = 0;
                foreach (var liEquipModel in Model.listOfEquipment)
                 
                    <input type="hidden" name="[@i].EquipID" value="@liEquipModel.EquipID"> 
                    <input type="hidden" name="[@i].EquipType" value="@liEquipModel.EquipType"> 
                    <input type="hidden" name="[@i].EquipDesc" value="@liEquipModel.EquipDesc">  
                    <input type="hidden" name="[@i].EquipAddedBy" value="@liEquipModel.EquipAddedBy">
                    <input type="hidden" name="[@i].EquipAddDate" value="@liEquipModel.EquipAddDate"> 
                    <input type="hidden" name="[@i].EquipCostKey" value="@liEquipModel.EquipCostKey"> 
                    DateTime eqAddDateTime = Convert.ToDateTime(liEquipModel.EquipAddDate);
                    string eqAddDate = eqAddDateTime.ToString("d");
                    string eqAddTime = eqAddDateTime.ToString("t"); 
                    <ul data-role="listview" data-inset="true" data-theme="c" style="margin-top:5px;"> 
                       <li data-role="list-divider">
                            @woEquipModel.EquipDesc 
                            <span style="float:right;">
                                Equipment ID:&nbsp; <span>@liEquipModel.EquipID</span> 
                            </span> 
                        </li>     
                        <li>
                            <span style="font-size: 12px; font-weight:bold; color:#474747;">


                                <span style="color:#29537E;">Hours:&nbsp;</span>
                            </span>  
                            <span class="ui-li-aside" style="float:right; width:92%; text-align:left; margin-top:-14px;"> 
                                <span style="font-size: 14px; font-weight:bold; color:#474747;">  
                                    <input type="range"
                                        data-theme="c" 
                                        name="[@i].EquipUsageHours" 
                                        id="slider-1"  
                                        style="font-size: 12px; color:#474747; margin-top:0px;" 
                                        value="@liEquipModel.EquipUsageHours" min="0" max="16" step=".25" 
                                        data-highlight="true" 
                                    />   
                                </span> 
                            </span>
                        </li> 
                    </ul>
                    i += 1;
                
                <div class="ui-grid-solo"> 
                    <div class="ui-block-a" style="float:right; width:30%;">   
                        <input id="btnSaveEquipHours2" data-mini="true" data-theme="b" type="submit" value="Save Hours" />  
                    </div>  
                </div> 
            
        

我提交 FormB 的 Action 如下:

[HttpPost] 
public ActionResult ActionBName (string idNumber, string fName, List<EquipmentModel> equipList)

 //do work to save to database    

现在,当用户提交 FormA 时,我需要有效地提交 FormB。对我来说棘手的部分是设备列表,它是一个模型属性,它是另一个模型的列表。

我该怎么做?我尝试了以下 jquery:

$(function () 
    $('#FormA').submit(function ()                
       $.post('@Url.Action("ActionBName", "ControllerName")', $("#FormB").serialize())             
    );
);

这适用于我的 Safari 和 Chrome 桌面,但不适用于 iPad。

有人有什么想法吗?任何帮助表示赞赏。谢谢。

【问题讨论】:

【参考方案1】:

由于AJAX post是异步的,FormB的AJAX post和FormA的提交之间有可能存在竞争条件;并且有时(例如在 iPad 上)FormA 在 FormB 之前提交。

尝试像这样按顺序执行它们...

$(function () 
    var isFormBSubmitted = false;

    $('#FormA').submit(function (e)    
       if (!isFormBSubmitted) 
           e.preventDefault(); // stop FormA from submitting
           $.post('@Url.Action("ActionBName", "ControllerName")', $("#FormB").serialize())
               .done(function () 
                   isFormBSubmitted = true;
                   $('#FormA').submit(); // submit FormA
               );
                                
    );
);

【讨论】:

这解决了这个问题。好决定。谢谢@AnthonyChu。

以上是关于使用 jquery 从视图提交包含输入和 List<Model> 的表单到操作的主要内容,如果未能解决你的问题,请参考以下文章

提交包含文本输入和文件输入的表单

使用 jQuery Mobile 1.4.2 远程自动完成列表视图提交表单?

从 PHP (jQuery/AJAX) 插入 MySQL

jQuery 移动列表视图和面板

使用 jQuery 和 ASP.NET MVC 异步上传文件,无需表单提交和异步

提交后如何禁用输入字段