C#と.NET Framework 4.5.1を使用してASP.NET MVC 5 Webを開発しています。
form
ファイルに次のcshtml
があります。
@model MyProduct.Web.API.Models.ConnectBatchProductViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create</title>
</head>
<body>
@if (@Model != null)
{
<h4>Producto: @Model.Product.ProductCode, Cantidad: @Model.ExternalCodesForThisProduct</h4>
using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post))
{
@Html.HiddenFor(model => model.Product.Id, new { @id = "productId", @Name = "productId" });
<div>
<table id ="batchTable" class="order-list">
<thead>
<tr>
<td>Cantidad</td>
<td>Lote</td>
</tr>
</thead>
<tbody>
<tr>
<td>@Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].Quantity")</td>
<td>@Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].BatchName")</td>
<td><a class="deleteRow"></a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<input type="button" id="addrow" value="Add Row" />
</td>
</tr>
</tfoot>
</table>
</div>
<p><input type="submit" value="Seleccionar" /></p>
}
}
else
{
<div>Error.</div>
}
<script src="~/Scripts/jquery-2.1.3.min.js"></script>
<script src="~/js/createBatches.js"></script> <!-- Resource jQuery -->
</body>
</html>
そしてこれはアクションメソッドです:
[HttpPost]
public ActionResult Save(FormCollection form)
{
return null;
}
そして、2つのViewModel
:
public class BatchProductViewModel
{
public int Quantity { get; set; }
public string BatchName { get; set; }
}
public class ConnectBatchProductViewModel
{
public Models.Products Product { get; set; }
public int ExternalCodesForThisProduct { get; set; }
public IEnumerable<BatchProductViewModel> BatchProducts { get; set; }
}
しかし、私はこれをFormCollection form
var:
しかし、私はIEnumerable<BatchProductViewModel> model
:
public ActionResult Save(int productId, IEnumerable<BatchProductViewModel> model);
上記のメソッドシグネチャを使用すると、両方のパラメータがnullになります。
ユーザーがjQueryを使用して動的に行を追加するため、IEnumerable
が必要です。
これはjQuery
スクリプトです:
jQuery(document).ready(function ($) {
var counter = 0;
$("#addrow").on("click", function () {
counter = $('#batchTable tr').length - 2;
var newRow = $("<tr>");
var cols = "";
var quantity = 'ConnectBatchProductViewModel.BatchProducts[0].Quantity'.replace(/\[.{1}\]/, '[' + counter + ']');
var batchName = 'ConnectBatchProductViewModel.BatchProducts[0].BatchName'.replace(/\[.{1}\]/, '[' + counter + ']');
cols += '<td><input type="text" name="' + quantity + '"/></td>';
cols += '<td><input type="text" name="' + batchName + '"/></td>';
cols += '<td><input type="button" class="ibtnDel" value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function (event) {
$(this).closest("tr").remove();
counter -= 1
$('#addrow').attr('disabled', false).prop('value', "Add Row");
});
});
何か案が?
コレクションのコントロールをfor
ループで生成して、インデクサーで正しく名前が付けられるようにする必要があります(プロパティBatchProducts
はIList<BatchProductViewModel>
@using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post))
{
....
<table>
....
@for(int i = 0; i < Model.BatchProducts.Count; i++)
{
<tr>
<td>@Html.TextBoxFor(m => m.BatchProducts[i].Quantity)</td>
<td>@Html.TextBoxFor(m => m.BatchProducts[i].BatchName)</td>
<td>
// add the following to allow for dynamically deleting items in the view
<input type="hidden" name="BatchProducts.Index" value="@i" />
<a class="deleteRow"></a>
</td>
</tr>
}
....
</table>
....
}
次に、POSTメソッドは
public ActionResult Save(ConnectBatchProductViewModel model)
{
....
}
編集
注:編集に加えて、ビューでBatchProductViewModel
アイテムを動的に追加および削除する場合は、BeginCollectionItem
ヘルパーまたはHTMLテンプレートを使用する必要があります この回答
新しいアイテムを動的に追加するためのテンプレートは
<div id="NewBatchProduct" style="display:none">
<tr>
<td><input type="text" name="BatchProducts[#].Quantity" value /></td>
<td><input type="text" name="BatchProducts[#].BatchName" value /></td>
<td>
<input type="hidden" name="BatchProducts.Index" value ="%"/>
<a class="deleteRow"></a>
</td>
</tr>
</div>
ダミーインデクサーと非表示入力の一致しない値により、このテンプレートがポストバックされないことに注意してください。
次に、新しいBatchProducts
を追加するスクリプトは次のようになります。
$("#addrow").click(function() {
var index = (new Date()).getTime(); // unique indexer
var clone = $('#NewBatchProduct').clone(); // clone the BatchProducts item
// Update the index of the clone
clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
clone.html($(clone).html().replace(/"%"/g, '"' + index + '"'));
$("table.order-list").append(clone.html());
});
DRYの原則に従って、その目的のために1つのEditorTemplateを作成できます。手順:
1- [ビュー]> [共有]>(EditorTemplates)という名前の新しいフォルダを作成
2-新しく作成したEditorTemplatesフォルダー内にビューを作成します。ビューのモデルは、OPの例に従ってBatchProductViewModelである必要があります。エディタービュー内にコードを配置します。ループやインデックスは必要ありません。
EditorTemplateは、すべての子エンティティのPartialViewと同様に動作しますが、より一般的な方法です。
3-親エンティティのビューで、エディターを呼び出します。@ Html.EditorFor(m => m.BatchProducts)
これにより、より整理されたビューが提供されるだけでなく、同じエディターを他のビューでも再利用できるようになります。
この記事 にアクセスして、完全なソースコードを ビデオチュートリアル で確認できます。
まず、オブジェクトのリストを渡すことができるアクションを作成する必要があります
[HttpGet]
public ActionResult Index()
{
List<Contact> model = new List<Contact>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
model = dc.Contacts.ToList();
}
return View(model);
}
次に、そのアクションのビューを作成する必要があります
@model List<UpdateMultiRecord.Contact>
@{
ViewBag.Title = "Update multiple row at once Using MVC 4 and EF ";
}
@using (@Html.BeginForm("Index","Home", FormMethod.Post))
{
<table>
<tr>
<th></th>
<th>Contact Person</th>
<th>Contact No</th>
<th>Email ID</th>
</tr>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
<td> @Html.HiddenFor(model => model[i].ContactID)</td>
<td>@Html.EditorFor(model => model[i].ContactPerson)</td>
<td>@Html.EditorFor(model => model[i].Contactno)</td>
<td>@Html.EditorFor(model => model[i].EmailID)</td>
</tr>
}
</table>
<p><input type="submit" value="Save" /></p>
<p style="color:green; font-size:12px;">
@ViewBag.Message
</p>
}
@section Scripts{
@Scripts.Render("~/bundles/jqueryval")
}
次に、オブジェクトのリストをデータベースに保存するためのコードを記述する必要があります
[HttpPost]
public ActionResult Index(List<Contact> list)
{
if (ModelState.IsValid)
{
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
foreach (var i in list)
{
var c = dc.Contacts.Where(a =>a.ContactID.Equals(i.ContactID)).FirstOrDefault();
if (c != null)
{
c.ContactPerson = i.ContactPerson;
c.Contactno = i.Contactno;
c.EmailID = i.EmailID;
}
}
dc.SaveChanges();
}
ViewBag.Message = "Successfully Updated.";
return View(list);
}
else
{
ViewBag.Message = "Failed ! Please try again.";
return View(list);
}
}
using(Html.BeginForm())
{
// code here
}
フォームデータを投稿する場合は、すべてのタグをフォームタグに含める必要があります。
Post Methodeでは、パラメーターとして「MyProduct.Web.API.Models.ConnectBatchProductViewModel」を受け取ります。
既存のモデルをPostメソッドに使用します。
モデルからIEnumerableが必要なのはなぜですか?モデルにIDを含めて1つしかありません。