Olaoluwa
Olaoluwa

Reputation: 76

manually Set Kendo asp.net mvc grid row to update

My grid is edited in inline mode. apparently when kendo doesnt detect a change to d row, the update event will not be fired. i need to cause the update event to fire even when no change has been made on the row because the change will be handled in d controller.

i found this post Manual row change but i dont know how to hook that up . im using kendo mvc not the kendo js.

my view

@(Html.Kendo().Grid<OrderViewModel>()
        .Name("orders")
                .HtmlAttributes(new { style = "height: 700px; border: 0;" })
        .Scrollable()
        .Columns(columns =>
        {
            columns.Template(t => { })
                .ClientTemplate("#=OrderID#")
                .Title("ORDER ID")
                .Width(120);
            columns.Bound(f => f.OrderDate)
               .Title("ORDER DATE")
               .Format("{0:d}")
               .Width(150);
            columns.Bound(f => f.RequiredDate)
               .Title("REQUIRED DATE")
               .Format("{0:d}")
               .Width(150);
            columns.ForeignKey(f => f.CustomerID, (System.Collections.IEnumerable)ViewData["customers"], "CustomerID", "CompanyName")
                .Title("REQUEST BRANCH")
                .Width(200);
            columns.ForeignKey(f => f.ShipVia, (System.Collections.IEnumerable)ViewData["shippers"], "ShipperID", "CompanyName")
                .Title("CMU")
                .Width(150); ;
            columns.ForeignKey(f => f.EmployeeID, (System.Collections.IEnumerable)ViewData["employees"], "EmployeeID", "EmployeeName")
                .Title("REQUESTED BY")
                .Width(250);
            columns.Bound(f => f.ShipCountry)
                .Title("ORDER STATUS")
                .ClientTemplate("<div class='country #=ShipCountry#'></div>#=ShipCountry#")
                .Width(150);
            columns.Command(commands =>
            {
                commands.Edit()
                .Text("Approve Order")
                 .UpdateText("Approve")
                 .CancelText("Cancel");

            }).Width(200);
        })
        .Editable(e => e.Mode(GridEditMode.InLine))
        .Events(e => e
            .DataBound("onDataBound")
        )
        .Pageable(pageable => pageable.Refresh(true))
        .Sortable()
        .Selectable()
        .Navigatable()
        .Filterable()
        .ClientDetailTemplateId("Order_DetailTemplate")
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(20)
            .Model(m =>
            {
                m.Id(f => f.OrderID);
                m.Field(f => f.OrderID).DefaultValue(-42); 
                m.Field(f => f.OrderID).Editable(false);
                m.Field(f => f.OrderDate).Editable(false);
                m.Field(f => f.CustomerID).Editable(false);
                m.Field(f => f.EmployeeID).Editable(false);
                m.Field(f => f.ShipCountry).Editable(false);
                    
                m.Field(f => f.ShipVia).Editable(false);
                    
                
            })
            .Events(e => e.Error(@<text>
                function (e) {
                onError(e, "orders");
                }
            </text>))
                                    .Sort(s => s.Add(f => f.OrderDate).Descending())
                                    .Read("Orders_Read", "Orders")

                                    .Update("Orders_Approve", "Orders")
                                    
                                )
    )
    @{
        Func<object, object> errorEvent = @<text>
            function(e) {
            if (e.errors) {
            onError(e, "order_details#=OrderID#");
            }
            }
        </text>;
    }
    <script id="Order_DetailTemplate" type="text/x-kendo-tmpl">
        <h4>Details for order \\##=OrderID# </h4>
        @(Html.Kendo().TabStrip()
        .Name("order_details_tabstrip_#=OrderID#")
        .Items(items =>
        {
            items.Add()
                .Text("CURRENCIES")
                .Selected(true)
                .Content(@<text>
                    @(Html.Kendo().Grid<OrderDetailViewModel>()
                    .Name("order_details#=OrderID#")
                    
                    .Columns(columns =>
                    {
                        columns.ForeignKey(f => f.ProductID, (System.Collections.IEnumerable)ViewData["products"], "ProductID", "ProductName")
                            .Title("CURRENCY NAME")
                            .EditorTemplateName("CustomGridForeignKey");
                        columns.Bound(f => f.UnitPrice)
                            .Format("{0:c}")
                            .Title("UNIT PRICE")
                            .Width(220);
                        columns.Bound(f => f.Quantity)
                            .Title("AMOUNT")
                            .Width(220)
                            .ClientFooterTemplate("Grand total:");
                        columns.Template(f => new { })
                            .Title("TOTAL")
                            .ClientTemplate("\\#=kendo.toString(GetOrderItemPrice(data), \"c\")\\#")
                            .ClientFooterTemplate("<span name='sum'></span>").Width(120);

                    })
                    .Events(e =>
                    {
                        e.DataBound("onOrderDetailsDataBound");
                        e.DetailInit("onDetailInit");
                        e.Edit("onOrderDetailsEdit");
                    })
                    .Selectable()
                    .Pageable(pageable => pageable.Refresh(true))
                    .Navigatable()
                    .ClientDetailTemplateId("Product_DetailTemplate")
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .Model(model =>
                        {
                            model.Id(detail => detail.OrderDetailID);
                        })
                        .Events(e => e.Error(errorEvent))
                        .Read("OrderDetails_Read", "OrderDetails", new { OrderID = "#=OrderID#" })
                        
                    ).ToClientTemplate()
                    )</text>);
            items.Add()
                .Text("MOVEMENT DETAILS")
                .Content(@<text>
                    <div class='shipping-details'>
                        <ul>
                            <li><label>Name:</label>#= ShipName #</li>
                            <li><label>OrderStatus:</label>#= ShipCountry #</li>
                            <li><label>City:</label>#= ShipCity #</li>
                            <li><label>Address:</label>#= ShipAddress #</li>
                            <li><label>Postal Code:</label>#= ShipPostalCode #</li>
                        </ul>
                    </div>
                </text>);
        })
                                                                        .ToClientTemplate()
        )
    </script>

and my controller :

public ActionResult Orders_Approve([DataSourceRequest]DataSourceRequest request, OrderViewModel order)
        {
            if (ModelState.IsValid)
            {
                using (var northwind = new NCashEntities())
                {
                    var entity = northwind.ORDERS.FirstOrDefault(o => o.ORDERID == order.OrderID);
                    if (entity == null)
                    {
                        string errorMessage = string.Format("Cannot update record with OrderID:{0} as it's not available.", order.OrderID);
                        ModelState.AddModelError("", errorMessage);
                    }
                    else
                    {
                        entity.CUSTOMERID = order.CustomerID;
                        entity.EMPLOYEEID = order.EmployeeID;
                        entity.ORDERDATE = order.OrderDate;
                        entity.SHIPCOUNTRY = "Approved";
                        entity.SHIPVIA = order.ShipVia;
                        entity.SHIPPEDDATE = order.ShippedDate;
                        entity.SHIPNAME = order.ShipName;
                        entity.SHIPADDRESS = order.ShipAddress;
                        entity.SHIPCITY = order.ShipCity;
                        entity.SHIPPOSTALCODE = order.ShipPostalCode;

                        northwind.ORDERS.Attach(entity);
                        northwind.Entry(entity).State = System.Data.Entity.EntityState.Modified;
                        northwind.SaveChanges();
                    }
                }
            }
            return Json(new[] { order }.ToDataSourceResult(request, ModelState));
        }

Upvotes: 0

Views: 2479

Answers (1)

David Shorthose
David Shorthose

Reputation: 4497

Ok here is one way of potentially doing what you want to do.

If you add an event handler to the edit event by adding

this to your grid (adding to the existing event you have for error)

e.Edit("onEdit"); 

then adding a javascript function like this:

function onEdit(e){
 e.model.dirty= true;
}

this should set the dirty flag for you and allow you to update the model.

Although this can be done. I would personally think you would be better binding this "approve" action to a button or making it selectable. Just in case someone accidently approves one of your orders when you don't want it to be approved. But that is just the way I would think about this type of "business logic".

Any issues let me know and I will adjust the code accordingly.

Upvotes: 3

Related Questions