asp.net-mvc ASP.NET MVC 主详细信息输入表单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4646340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:42:10  来源:igfitidea点击:

ASP.NET MVC Master Detail Entry Form

asp.net-mvcformsmaster-detaildata-entry

提问by Emad

I'm trying to implement an order entry form using ASP.NET MVC but facing a lot of difficulties. All the samples that I found are related to viewing master detail forms, and none for adding or editing.

我正在尝试使用 ASP.NET MVC 实现订单输入表单,但遇到了很多困难。我发现的所有示例都与查看主详细信息表单有关,没有用于添加或编辑的示例。

Suppose I have two tables: Order and OrderLines that are related to each others with one-to-many relationship. In the main view I had a “New” button when clicked it should show a new order view composed of the order fields, a grid that shows the order lines, and a “Save” button that when clicked will persist the whole order along with its lines into a database. The grid should have three buttons: “Add Line”, “Edit Line”, and “Delete Line”. When the “Add Line” is clicked a new view should be shown that allows the user to add the line to the order view grid lines –at this stage the database is not affected-. When the user clicks “Edit Line” a view will be shown that allows the user to edit the selected line and when done update the order grid lines.

假设我有两个表:Order 和 OrderLines,它们以一对多的关系相互关联。在主视图中,我点击了一个“新建”按钮,它应该显示一个由订单字段组成的新订单视图,一个显示订单行的网格,以及一个“保存”按钮,单击该按钮时将保留整个订单以及其行进入数据库。网格应该有三个按钮:“添加行”、“编辑行”和“删除行”。单击“添加行”时,应显示一个新视图,允许用户将行添加到订单视图网格线中——在此阶段,数据库不受影响——。当用户单击“编辑行”时,将显示一个视图,允许用户编辑所选行并在完成后更新订单网格线。

The most difficult problems are:

最困难的问题是:

How to pass the order and its lines collection between the order view and the order line views?

如何在订单视图和订单行视图之间传递订单及其行集合?

How to update the order view based on changes in the order line view?

如何根据订单行视图的变化更新订单视图?

And how to persist changes between views without the database being involved?

以及如何在不涉及数据库的情况下保持视图之间的更改?

Is there a concrete example that shows how to implement this using MVC?

有没有一个具体的例子来说明如何使用 MVC 来实现这一点?

Views

观看次数

Your help and feedback is appreciated.

感谢您的帮助和反馈。

回答by Muhammad Adeel Zahid

Pleas have a look at my blog poston creating master detail form in asp.net mvc. it also contains demo project that you can download

请查看我关于在 asp.net mvc 中创建主详细信息表单的博客文章。它还包含您可以下载的演示项目

回答by Sourav Mondal

Step 1: Create view model

第 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;}
}

Step 2: Add javascript for add order lines

第 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>

Step 3: Create an action for save data

第 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} };
    }

you can download source codeand video tutorial

你可以下载源代码视频教程

回答by Tom Clarkson

Unlike WebForms, ASP.NET MVC does not try to hide the stateless nature of HTTP. To work with a complex object across multiple forms you have a couple of options:

与 WebForms 不同,ASP.NET MVC 不会试图隐藏 HTTP 的无状态特性。要跨多个表单处理复杂对象,您有几个选择:

  • Save the object on the server with each change so that the updated object is available using only an id
  • Use jquery to populate the order line form and save details to the main form
  • 每次更改时将对象保存在服务器上,以便仅使用 id 即可使用更新的对象
  • 使用 jquery 填充订单行表单并将详细信息保存到主表单

I usually go with the client side option myself, with the main form having hidden fields for the data that will be edited in the subform. You may find the server side option easier though - if you really don't want to involve the database you can keep your partially updated object in the session.

我通常自己使用客户端选项,主表单具有将在子表单中编辑的数据的隐藏字段。您可能会发现服务器端选项更容易 - 如果您真的不想涉及数据库,您可以将部分更新的对象保留在会话中。

回答by WestDiscGolf

Just off the top of my head (a kind of brain dump)...

就在我的头顶上(一种脑残)......

  • You could have a main grid part of the form. This would be full view loaded from an action (either with an order number or not depending on loading an existing one or not).

  • When clicking an event (new or edit) this could open a partial view in a "lightbox" style. This would then pass back a json object back to the main form.

  • The passed json object would then be rendered using templating to the bottom of the table (for a new one) or update an existing record. This could also be saved back to the server in the same ajax call. Or just update the client side and need the user to click a save button.

  • An isDirty flag will be needed so any changes set it to true and the when the browser tries to leave or close etc. then you can prompt the user to save or not.

  • 您可以拥有表单的主网格部分。这将是从动作加载的完整视图(是否带有订单号,取决于是否加载现有订单号)。

  • 单击事件(新建或编辑)时,这可能会以“灯箱”样式打开部分视图。然后这会将一个 json 对象传回主表单。

  • 然后将使用模板将传递的 json 对象呈现到表的底部(对于新的)或更新现有记录。这也可以在同一个 ajax 调用中保存回服务器。或者只是更新客户端并需要用户单击保存按钮。

  • 将需要一个 isDirty 标志,以便任何更改将其设置为 true 以及当浏览器尝试离开或关闭等时,您可以提示用户是否保存。

Hope this helps.

希望这可以帮助。

edit

编辑

Not tried this but could be interesting with the none db aspect of your question click

没有尝试过这个,但你的问题点击的无数据库方面可能会很有趣

回答by ozz

You could try Telericks free MVC grid control...

您可以尝试 Telericks 免费 MVC 网格控制...

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

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

回答by Prakash

Step 3: Create an action for save data. [HttpPost]

第 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 } };

    }