web-dev-qa-db-ja.com

ASP.NETMVCマスター詳細入力フォーム

ASP.NET MVCを使用して注文入力フォームを実装しようとしていますが、多くの問題に直面しています。私が見つけたすべてのサンプルは、マスター詳細フォームの表示に関連しており、追加または編集用のものはありません。

1対多の関係で相互に関連しているOrderとOrderLinesの2つのテーブルがあるとします。メインビューでは、クリックすると「新規」ボタンが表示され、注文フィールドで構成される新しい注文ビュー、注文ラインを表示するグリッド、クリックすると注文全体が保持される「保存」ボタンが表示されます。データベースへのその行。グリッドには、「行の追加」、「行の編集」、「行の削除」の3つのボタンが必要です。 「行の追加」をクリックすると、ユーザーが注文ビューのグリッド線に線を追加できる新しいビューが表示されます。この段階では、データベースは影響を受けません。ユーザーが「ラインの編集」をクリックすると、ユーザーが選択したラインを編集できるビューが表示され、完了したらオーダーグリッドラインを更新します。

最も難しい問題は次のとおりです。

注文ビューと注文ラインビューの間で注文とそのラインコレクションを渡す方法は?

オーダーラインビューの変更に基づいてオーダービューを更新するにはどうすればよいですか?

また、データベースを使用せずにビュー間で変更を永続化するにはどうすればよいですか?

MVCを使用してこれを実装する方法を示す具体的な例はありますか?

Views

あなたの助けとフィードバックは大歓迎です。

20
Emad

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() != '' &amp;&amp; !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() != '' &amp;&amp; !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('&lt;span style="color:red;"&gt;Please add order items&lt;/span&gt;');
                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 &gt; 0) {
                var $table = $('&lt;table/&gt;');
                $table.append('&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Item&lt;/th&gt;&lt;th&gt;Quantity&lt;/th&gt;&lt;th&gt;Rate&lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;');
                var $tbody = $('&lt;tbody/&gt;');
                $.each(orderItems, function (i, val) {
                    var $row = $('&lt;tr/&gt;');
                    $row.append($('&lt;td/&gt;').html(val.ItemName));
                    $row.append($('&lt;td/&gt;').html(val.Quantity));
                    $row.append($('&lt;td/&gt;').html(val.Rate));
                    $row.append($('&lt;td/&gt;').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} };
    }

ソースコードのダウンロード および ビデオチュートリアル

2
Sourav Mondal

WebFormsとは異なり、ASP.NETMVCはHTTPのステートレスな性質を隠そうとしません。複数のフォームにまたがる複雑なオブジェクトを操作するには、いくつかのオプションがあります。

  • IDのみを使用して更新されたオブジェクトを使用できるように、変更のたびにオブジェクトをサーバーに保存します
  • Jqueryを使用して注文明細フォームに入力し、詳細をメインフォームに保存します

私は通常、クライアント側のオプションを自分で使用します。メインフォームには、サブフォームで編集されるデータの非表示フィールドがあります。ただし、サーバー側のオプションの方が簡単な場合があります。データベースを本当に関与させたくない場合は、部分的に更新されたオブジェクトをセッションに保持できます。

2
Tom Clarkson

頭のてっぺんから(一種の脳のダンプ)...

  • フォームのメイングリッド部分を持つことができます。これは、アクションからロードされたフルビューになります(既存の注文番号をロードするかどうかに応じて、注文番号を使用するかどうかに関係なく)。

  • イベント(新規または編集)をクリックすると、「ライトボックス」スタイルで部分ビューが開く可能性があります。これにより、jsonオブジェクトがメインフォームに戻されます。

  • 渡されたjsonオブジェクトは、テーブルの下部にテンプレートを使用してレンダリングされるか(新しいオブジェクトの場合)、既存のレコードを更新します。これは、同じajax呼び出しでサーバーに保存して戻すこともできます。または、クライアント側を更新して、ユーザーに保存ボタンをクリックするように要求します。

  • IsDirtyフラグが必要になるので、変更を加えるとtrueに設定され、ブラウザが終了または閉じようとしたときなどに、ユーザーに保存するかどうかを確認できます。

お役に立てれば。

編集

これを試していませんが、質問の非dbの側面で興味深いかもしれません クリック

1
WestDiscGolf

Telericksの無料MVCグリッドコントロールを試すことができます...

http://demos.telerik.com/aspnet-mvc/grid/hierarchyserverside

1
ozz

手順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 } };

    }
0
Prakash