ASP.NET MVCを使用して注文入力フォームを実装しようとしていますが、多くの問題に直面しています。私が見つけたすべてのサンプルは、マスター詳細フォームの表示に関連しており、追加または編集用のものはありません。
1対多の関係で相互に関連しているOrderとOrderLinesの2つのテーブルがあるとします。メインビューでは、クリックすると「新規」ボタンが表示され、注文フィールドで構成される新しい注文ビュー、注文ラインを表示するグリッド、クリックすると注文全体が保持される「保存」ボタンが表示されます。データベースへのその行。グリッドには、「行の追加」、「行の編集」、「行の削除」の3つのボタンが必要です。 「行の追加」をクリックすると、ユーザーが注文ビューのグリッド線に線を追加できる新しいビューが表示されます。この段階では、データベースは影響を受けません。ユーザーが「ラインの編集」をクリックすると、ユーザーが選択したラインを編集できるビューが表示され、完了したらオーダーグリッドラインを更新します。
最も難しい問題は次のとおりです。
注文ビューと注文ラインビューの間で注文とそのラインコレクションを渡す方法は?
オーダーラインビューの変更に基づいてオーダービューを更新するにはどうすればよいですか?
また、データベースを使用せずにビュー間で変更を永続化するにはどうすればよいですか?
MVCを使用してこれを実装する方法を示す具体的な例はありますか?
あなたの助けとフィードバックは大歓迎です。
Asp.net mvcでマスター詳細フォームを作成する方法についての私の ブログ投稿 をご覧ください。ダウンロードできるデモプロジェクトも含まれています
ステップ1:ビューモデルを作成する
public class OrderVM
{
public string OrderNo { get; set; }
public DateTime OrderDate { get; set; }
public string Description { get; set; }
public List<OrderDetail> OrderDetails {get;set;}
}
ステップ2:注文行を追加するためのJavaScriptを追加する
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
$(function () {
$('#orderDate').datepicker({
dateFormat : 'mm-dd-yy'
});
});
$(document).ready(function () {
var orderItems = [];
//Add button click function
$('#add').click(function () {
//Check validation of order item
var isValidItem = true;
if ($('#itemName').val().trim() == '') {
isValidItem = false;
$('#itemName').siblings('span.error').css('visibility', 'visible');
}
else {
$('#itemName').siblings('span.error').css('visibility', 'hidden');
}
if (!($('#quantity').val().trim() != '' && !isNaN($('#quantity').val().trim()))) {
isValidItem = false;
$('#quantity').siblings('span.error').css('visibility', 'visible');
}
else {
$('#quantity').siblings('span.error').css('visibility', 'hidden');
}
if (!($('#rate').val().trim() != '' && !isNaN($('#rate').val().trim()))) {
isValidItem = false;
$('#rate').siblings('span.error').css('visibility', 'visible');
}
else {
$('#rate').siblings('span.error').css('visibility', 'hidden');
}
//Add item to list if valid
if (isValidItem) {
orderItems.Push({
ItemName: $('#itemName').val().trim(),
Quantity: parseInt($('#quantity').val().trim()),
Rate: parseFloat($('#rate').val().trim()),
TotalAmount: parseInt($('#quantity').val().trim()) * parseFloat($('#rate').val().trim())
});
//Clear fields
$('#itemName').val('').focus();
$('#quantity,#rate').val('');
}
//populate order items
GeneratedItemsTable();
});
//Save button click function
$('#submit').click(function () {
//validation of order
var isAllValid = true;
if (orderItems.length == 0) {
$('#orderItems').html('<span style="color:red;">Please add order items</span>');
isAllValid = false;
}
if ($('#orderNo').val().trim() == '') {
$('#orderNo').siblings('span.error').css('visibility', 'visible');
isAllValid = false;
}
else {
$('#orderNo').siblings('span.error').css('visibility', 'hidden');
}
if ($('#orderDate').val().trim() == '') {
$('#orderDate').siblings('span.error').css('visibility', 'visible');
isAllValid = false;
}
else {
$('#orderDate').siblings('span.error').css('visibility', 'hidden');
}
//Save if valid
if (isAllValid) {
var data = {
OrderNo: $('#orderNo').val().trim(),
OrderDate: $('#orderDate').val().trim(),
//Sorry forgot to add Description Field
Description : $('#description').val().trim(),
OrderDetails : orderItems
}
$(this).val('Please wait...');
$.ajax({
url: '/Home/SaveOrder',
type: "POST",
data: JSON.stringify(data),
dataType: "JSON",
contentType: "application/json",
success: function (d) {
//check is successfully save to database
if (d.status == true) {
//will send status from server side
alert('Successfully done.');
//clear form
orderItems = [];
$('#orderNo').val('');
$('#orderDate').val('');
$('#orderItems').empty();
}
else {
alert('Failed');
}
$('#submit').val('Save');
},
error: function () {
alert('Error. Please try again.');
$('#submit').val('Save');
}
});
}
});
//function for show added items in table
function GeneratedItemsTable() {
if (orderItems.length > 0) {
var $table = $('<table/>');
$table.append('<thead><tr><th>Item</th><th>Quantity</th><th>Rate</th><th>Total</th></tr></thead>');
var $tbody = $('<tbody/>');
$.each(orderItems, function (i, val) {
var $row = $('<tr/>');
$row.append($('<td/>').html(val.ItemName));
$row.append($('<td/>').html(val.Quantity));
$row.append($('<td/>').html(val.Rate));
$row.append($('<td/>').html(val.TotalAmount));
$tbody.append($row);
});
$table.append($tbody);
$('#orderItems').html($table);
}
}
});
</script>
ステップ3:データを保存するためのアクションを作成する
[HttpPost]
public JsonResult SaveOrder(OrderVM O)
{
bool status = false;
if (ModelState.IsValid)
{
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
Order order = new Order { OrderNo = O.OrderNo, OrderDate = O.OrderDate, Description = O.Description };
foreach (var i in O.OrderDetails)
{
//
// i.TotalAmount =
order.OrderDetails.Add(i);
}
dc.Orders.Add(order);
dc.SaveChanges();
status = true;
}
}
else
{
status = false;
}
return new JsonResult { Data = new { status = status} };
}
WebFormsとは異なり、ASP.NETMVCはHTTPのステートレスな性質を隠そうとしません。複数のフォームにまたがる複雑なオブジェクトを操作するには、いくつかのオプションがあります。
私は通常、クライアント側のオプションを自分で使用します。メインフォームには、サブフォームで編集されるデータの非表示フィールドがあります。ただし、サーバー側のオプションの方が簡単な場合があります。データベースを本当に関与させたくない場合は、部分的に更新されたオブジェクトをセッションに保持できます。
頭のてっぺんから(一種の脳のダンプ)...
フォームのメイングリッド部分を持つことができます。これは、アクションからロードされたフルビューになります(既存の注文番号をロードするかどうかに応じて、注文番号を使用するかどうかに関係なく)。
イベント(新規または編集)をクリックすると、「ライトボックス」スタイルで部分ビューが開く可能性があります。これにより、jsonオブジェクトがメインフォームに戻されます。
渡されたjsonオブジェクトは、テーブルの下部にテンプレートを使用してレンダリングされるか(新しいオブジェクトの場合)、既存のレコードを更新します。これは、同じajax呼び出しでサーバーに保存して戻すこともできます。または、クライアント側を更新して、ユーザーに保存ボタンをクリックするように要求します。
IsDirtyフラグが必要になるので、変更を加えるとtrueに設定され、ブラウザが終了または閉じようとしたときなどに、ユーザーに保存するかどうかを確認できます。
お役に立てれば。
編集
これを試していませんが、質問の非dbの側面で興味深いかもしれません クリック
Telericksの無料MVCグリッドコントロールを試すことができます...
http://demos.telerik.com/aspnet-mvc/grid/hierarchyserverside
手順3:データを保存するためのアクションを作成します。 [HttpPost]
public JsonResult SaveOrder(OrderVM O)
{
bool status = false;
if (ModelState.IsValid)
{
using (ManageMobileStoreWebContext dc = new ManageMobileStoreWebContext())
{
//Random rnd = new Random();
//OrderID = rnd.Next(),
Order order = new Order { OrderNo = O.OrderNo, OrderDate = O.OrderDate, Description = O.Description };
foreach (var i in O.OrderDetails)
{
if(order.OrderDetails == null)
{
order.OrderDetails = new List<OrderDetail>();
}
// i.TotalAmount =
order.OrderDetails.Add(i);
//dc.OrderDetails.Add(i);
}
dc.Orders.Add(order);
dc.SaveChanges();
status = true;
}
}
else
{
status = false;
}
return new JsonResult { Data = new { status = status } };
}