Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.ID_SOLICITUDSERVICIO).Visible(false);
columns.Command(command => command.Custom("custom").Text("").Click("MostrarSolicitud")).Title("N° de solicitud").Width(75);
columns.Bound(p => p.NUMEROSOLICITUD_FISICO).Title("N° reporte físico");
columns.Bound(p => p.NUMERO_SOLICITUDCLIENTE).Title("Ticket Cliente");
columns.Bound(p => p.MARCA).Title("Marca");
columns.Bound(p => p.MODELO).Title("Modelo");
columns.Bound(p => p.CODIGO_REPUESTO).Title("Código del repuesto");
columns.Bound(p => p.DETALLE_REPUESTO).Title("Detalle");
columns.Bound(p => p.CANTIDAD).Title("Cantidad");
columns.Bound(p => p.VALOR_UNITARIO).Title("Valor unit.");
columns.Bound(p => p.VALOR_TOTAL).Title("Valor total").ClientFooterTemplate("$ #=sum#");
columns.Bound(p => p.PROPIETARIO).Title("Propietario");
columns.Bound(p => p.ID_REPUESTOSERVICIO)
//.ClientTemplate("#= Texto_Factura(data) #")
.Title("N° factura");
//columns.Bound(p => p.ID_REPUESTOSERVICIO)
// .ClientTemplate("#= CheckDevoler(data) #")
// .Title("Devolver").Width(60)
//.Sortable(false).Groupable(false).Filterable(false);
})
.Filterable()
.Sortable()
.Pageable(m => m.PageSizes(new int[] { 10, 20, 50, 100, 500 }))
.Groupable()
.Events(e => e.DataBound("dataBound"))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("LeerExt_DevolucionRepuesto", "Consultas").Data("getParameter"))
.Model(model => { model.Id(p => p.ID_SOLICITUDSERVICIO); })
.Aggregates(aggregate =>
{
aggregate.Add(p => p.VALOR_TOTAL).Sum();
})
)
<script type=
"text/javascript"
>
function
Texto_Factura(item) {
var
texto =
"<label></label>"
;
var
urls =
"/Consultas/GetRepuestoServicioSinById"
;
var
idrepuesto = item.ID_REPUESTOSERVICIO;
var
factura =
""
;
$.ajax({
url: urls,
data: { id_repuestoservicio: idrepuesto },
type:
'GET'
,
success:
function
(data) {
if
(data.FACTURA_REPUESTOSERVICIO !=
null
) {
factura = data.FACTURA_REPUESTOSERVICIO;
alert(
"<label>"
+ kendo.htmlEncode(factura) +
"</label>"
);
return
texto =
"<label>"
+ kendo.htmlEncode(factura) +
"</label>"
;
}
},
error:
function
(resp) {
//alert(JSON.stringify(resp)); open it to alert the error if you want
alert(resp);
return
texto =
"<label>"
+ resp +
"</label>"
;
}
});
return texto;
}
</script>
I am missing something important regarding this example grid
http://demos.telerik.com/kendo-ui/web/grid/editing-custom.html?mvc
I based my shopProductAdmin view/controller closely on this example, making use of the custom editor used in the example for CategoryViewModel, for my priceStrategyViewModel.
Other differences from the reference,
I am using InLine editing instead of InCell.
I am not using Batch mode.
The read function has additional data it sends to get the products.
The read/update/delete functions all have role requirement hints for security, but i tested without these security hints and the behavior is the same.
There is something not right about the data being passed around though. Some binding somewhere must be amiss and I can't seem to spot it.
Bad behaviors I see..
a) the default priceStrategy, when no record exists in the database, the PriceStrategyViewData.priceStrategyID/name are populated with the 99_none and the proper index. That part works.
b) when I edit a field, the customEditor comes up.. good
c) the value of the priceStrategy changes from 99_none to the first value in the priceStrategies list -- bad!. it should still be 99_none. This is the first indication that some data is not being passed around properly.
d) when I update the record on the grid, the update function in the controller see's the new product and all fields are properly updated with the notable exception of the PriceStrategyViewModel.* fields.
One piece of code in the example that I haven't gleaned why it is there.. in the example that I found on the installation package.. (this isn't shown on the web version, as the entities are not part of the sample code there), the entity not only has a
public CategoryViewModel Category { get; set; }
member.. which I understand that. But it also has this member right after it.. which seems to have no function anywhere in the grid. Was this intentional? I included it in my model also only to be consistent, but I haven't decided why it is there. It seems like it isn't serving a purpose.
public int? CategoryID { get; set; }
Anyway, here is my grid in the Admin.cshtml
@(Html.Kendo().Grid<EveTools.WebUI.Models.shopProductsAdminViewModel>()
.Name("productsGrid")
.Columns(columns =>
{
columns.Bound(product => product.typeName).Width(200).Title("Shop");
columns.Bound(product => product.forSale).Title("ForSale?");
columns.Bound(product => product.PriceStrategy).ClientTemplate("#=PriceStrategy.name#").Width(150);
columns.Bound(product => product.markup).Title("markup").Width(50);
columns.Bound(product => product.price).Title("Price");
columns.Command(command => { command.Edit(); command.Destroy().Text("Clear"); }).Width(100);
})
.DataSource(dataBinding => dataBinding
.Ajax()
.ServerOperation(false)
.Model(model => model.Id(p => p.typeID))
.Read(read => read.Action("ProductListAdmin", "Shop").Data("additionalProductListData"))
.Destroy(update => update.Action("EditingInline_DeleteProduct", "Shop"))
.Update(update => update.Action("EditingInline_UpdateProduct", "Shop"))
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.typeID);
model.Field(p => p.typeName).Editable(false);
model.Field(p => p.price).Editable(false);
model.Field(p => p.PriceStrategy).DefaultValue(
ViewData["defaultPriceStrategy"] as EveTools.WebUI.Models.PriceStrategyViewModel);
})
)
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:480px;" })
And the critical controller functions.
This function returns the data to the grid when requested.. by means of another list control of categories.
public ActionResult ProductListAdmin([Kendo.Mvc.UI.DataSourceRequest]Kendo.Mvc.UI.DataSourceRequest request, int? categoryID)
{
// if there is no category, there are also no products
if (!categoryID.HasValue)
return null;
EveShop.Domain.Concrete.EFEveShopDbContext db = new EveShop.Domain.Concrete.EFEveShopDbContext();
PriceStrategyViewModel defaultPriceStrategy = GetDefaultPriceStrategy();
// extract data from db, and fill in shopProductsAdminViewModels
var products = (from t in db.invTypes
join p in db.shopProducts
on t.invTypeID equals p.shopProductID into output
from o in output.DefaultIfEmpty()
select new shopProductsAdminViewModel
{
typeID = t.invTypeID,
groupID = t.groupID,
typeName = t.typeName,
volume = t.volume,
basePrice = t.basePrice,
published = t.published,
marketGroupID = t.marketGroupID,
iconID = t.iconID,
markup = (t.shopProduct == null) ? 0 : t.shopProduct.markup,
forSale = (t.shopProduct == null) ? false : t.shopProduct.forSale,
price = (t.shopProduct == null) ? 0 : t.shopProduct.shopProductPrice.price,
// not sure why i am filling this one in.. it was included in the original example though.. no binding to the grid?
priceStrategyID = (t.shopProduct == null) ? defaultPriceStrategy.priceStrategyID : t.shopProduct.shopPriceStrategy.shopPriceStrategyID,
// the actual price strategy data.. this one gets bound to the grid
PriceStrategy = new PriceStrategyViewModel
{
priceStrategyID = (t.shopProduct == null) ? defaultPriceStrategy.priceStrategyID : t.shopProduct.shopPriceStrategy.shopPriceStrategyID,
name = (t.shopProduct == null) ? defaultPriceStrategy.name : t.shopProduct.shopPriceStrategy.name
}
}).Where(e => e.marketGroupID == categoryID && e.published != false)
.OrderBy(e => e.typeName)
return Json(products.ToDataSourceResult(request));
}
This function receives the update record callback
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditingInline_UpdateProduct([DataSourceRequest] DataSourceRequest request, shopProductsAdminViewModel product)
{
// do something with updated product
// product.priceStrategy.* is always the default value, not the edited value.
return Json(new[] { product }.ToDataSourceResult(request, ModelState));
}
The PriceStrategyViewModlEditor.cshtml
@model EveTools.WebUI.Models.PriceStrategyViewModel
@(Html.Kendo().DropDownListFor(m => m)
.Name("PriceStrategyViewModel")
.DataValueField("priceStrategyID")
.DataTextField("name")
.BindTo((System.Collections.IEnumerable)ViewData["priceStrategies"])
)