How to Insert to Master-detail tables in ASP.NET MVC 5

16,812

I think you should use Ajax.

In your view you have the grid section, each time you add a record you have to post the values to the server using Ajax post form:

@using (Ajax.BeginForm("AddDetails", new AjaxOptions { UpdateTargetId = "gridContainerElementId" }))
{
  @Html.HiddenFor(m => m.folio)
  @Html.HiddenFor(m => m.product)
  @Html.TextBox(m => m.price)
  @Html.TextBox(m => m.quantity)
  <input type = "submit" value = "Save"/>
}

Note: put your grid in 'gridContainerElementId' div like:

<div id="gridContainerElementId">
  @Html.Action("DetailsGridPartial", new { OrderId = Model.folio })
</div>

In your controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddDetails(OrdersDetail orderDetails)
{
   if (ModelState.IsValid)
   {
      db.OrdersDetail.Add(orderDetails);
      db.SaveChanges();

      return RedirectToAction("DetailsGridPartial", new { OrderId =  orderDetails.folio });
   }
   return View(order);
}

public ActionResult DetailsGridPartial(int OrderId)
{
      var orderDetails = db.OrdersDetail.Where(w => w.folio == OrderId);
      return PartialView(orderDetails);
}

You need to create new view to show the grid:

@model IEnumerable<OrdersDetail>
@Html.YourHelper.Grid(model).Html() @*or however you build the grid*@

In this case you will not need to fill the grid manually by the new record, the grid will be refreshed automatically.

I hope this helps

Share:
16,812
Mr_LinDowsMac
Author by

Mr_LinDowsMac

Like: Programming, Music, Astronomy. Also like: Pizza, Soda and "Steam Hams".

Updated on June 29, 2022

Comments

  • Mr_LinDowsMac
    Mr_LinDowsMac almost 2 years

    I have Orders table and OrderDetails table in DB. With Entity Framework 6 I have obtained a model so I have classes generated from it. I also generated controllers and views from the Orders table.

    Orders
    folio (PK)
    date
    customer (FK)
    
    OrdersDetail
    folio (FK) -- to the Orders table
    product (FK)
    price
    quantity 
    

    The generated Create Post action is the following:

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include = "folio,date,customer")] Orders order)
            {
    
                if (ModelState.IsValid)
                {
                    db.Orders.Add(order);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
    
                ViewBag.cliente = new SelectList(db.CATCTES, "COD_CTE", "NOM_CTE", order.cliente);
    
                return View(order);
            }
    

    That's okay, but I would need to Insert to the other entity/table too! I already changed the Create.cshtml form, with the fields required for Orders table and including some kind of grid for OrdersDetail. Each row is a new entry for OrdersDetail table.

    enter image description here

    The problem, is I don't know how to properly save to the other table in the Create action at Orders controller. If this is not the right approach, tell me your comments.

    Another concern is about POSTing, How should I name the inputs to be properly grouped and use submitted values at controller? Each row is generated by this script when I click a "+" button on the form:

    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
        <script>
            function add_row() {
                var detalle = $('#detalle');
                var newRow = '<tr>' + 
                                '<td data-title="Product">' +
                                  '<div class="input-group">' +
                                    '<span class="input-group-addon"></span>' +
                                      '<input class="form-control" type="number" aria-label="Product" name="detail_array[].product" step="0.001" min="0.000" onchange="cambiar_importe(this)" required="true">' +
                                  '</div>' +
                                '</td>' +
                                '<td data-title="Price" >' +
                                  '<div class="input-group">' +
                                    '<span class="input-group-addon">$</span>' +
                                      '<input type="number" class="form-control" aria-label="Price" name="detail_array[].price" onchange="cambiar_importe(this)" step="0.001" min="0.000" required="true">' +
                                  '</div>' +
                                '</td>' +
                                '<td data-title="Quantity">' +
                                  '<div class="input-group">' +
                                    '<span class="input-group-addon">$</span>' +
                                      '<input type="text" class="importe form-control" aria-label="Quantity" name="detail_array[].quantity" step="0.001" min="0.000" readonly="true" >' +
                                  '</div>' +
                                '</td>' +
                                '<td data-title=""><button type="button" class="btn btn-danger btn-sm" onclick="borrar_renglon(this)">Cancelar</button></td>' +
                              '</tr>';
    
                detalle.append(newRow);
            }
    
        </script>
    }