I have a Telerik/Kendo MVC Grid and I have some fields which the users should fill in, and some which are calculated.
I calculate the values for the calculated columns Server Side and I don't feel like replicating complex financial calculations in Javascript as well. :)
So here's the simple requirement:
Grid has 3 columns, A, B & C.
User specifies A and B.
Controller gets the object populated with A and B (Maybe also an old value for C) and calculates C again.
The updated object with the new value for C is saved to the Database AND is passed in the JSon result BACK to the Client.
The Grid should now update and show the new calculated value for C.
Currently C is not updated but if i Refresh the grid manually then the new value for C is shown.
I've checked the Chrome deb
Here is some mockup of what I've got currently. I've tried many different things, but don't seem to be getting anywhere.
I've tried adding the event.RequestEnd from other samples I've found on your forums, but as soon as i add any events, then the inline editing breaks completely.
@(Html.Kendo().Grid((IEnumerable<emscredit.Models.Invoice>)Model.Invoices)
.Name("grid")
.Columns(columns =>
{
columns.Select().HeaderHtmlAttributes(new { style = "width:25px" }).HtmlAttributes(new { style = "width:25px" });
columns.Bound(p => p.A).Format("{0:R#,##0.00}");
columns.Bound(p => p.B).Format("{0:R#,##0.00}");
columns.Bound(p => p.C).Format("{0:R#,##0.00}");
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable(pageable => pageable.ButtonCount(5))
.Sortable(sortable => sortable.AllowUnsort(false))
.Scrollable()
.Filterable()
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
//.Events(events =>
//{
// events.Error("error_handler");
// events.RequestEnd("request_end");
//})
.AutoSync(true)
.Model(model => model.Id(i => i.Id))
.Read(read => read.Action("Index", "InvoiceGrid"))
.Update(update => update.Action("UpdateGrid", "InvoiceGrid"))
.Create(create => create.Action("AddToGrid", "InvoiceGrid"))
)
)
Some example from the controller for clarity. Obviously calculation code removed etc.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateGrid([DataSourceRequest] DataSourceRequest request, emscredit.Models.Invoice invoice)
{
if (invoice != null && ModelState.IsValid)
{
var entity = db.InvoiceModels.FirstOrDefault(i => i.Id == invoice.Id);
entity.A = invoice.A;
entity.B = invoice.B;
invoice.C = entity.C = invoice.A * invoice.B; // For clarification purposes only
db.SaveChanges();
}
return Json(invoice);
//.ToDataSourceResult was removed as it only caters for a list, not a single object
}
Like I said, i checked the network tab in Chrome and it shows the updated value for C coming back. So Controller seems fine. Just need to configure the grid to update the new calculated value without having to refresh the entire page.
Thanks!
Bruce
I have a grid that has
.Excel(excel => excel
.FileName("Global Agenda Dashboard Grid.xlsx")
.Filterable(true)
.ProxyURL(Url.Action("Export", "Excel"))
.AllPages(true)
I have a Excel controller and in there a method
[HttpPost]
public ActionResult Export(string contentType, string base64, string fileName)
{
var fileContents = Convert.FromBase64String(base64);
return File(fileContents, contentType, fileName);
}
But as far as I can tell this function is not getting called, but the export is happening. Ideas?
I'm experiencing the issue described in this thread:
https://github.com/telerik/kendo-ui-core/issues/3793
In other words, I've downloaded Telerik.UI.for.AspNet.Mvc5 (v2019.1.220) from NuGet and my project won't build unless I open the .csproj file and set MvcBuildViews to false. Obviously, this is not ideal as it means changing that flag every time I want to build. The only other workaround I know of is to remove the offending template files, but this would break some of the controls, as mentioned in the thread.
Do you know of any other workarounds?
Hello,
I understand that ClientTemplate does not work within A server bound grid, I was curious as to how would you be able to create a conditional statement such as
.ClientTemplate(
"# if (tmpIsActive && Active == 1) { # " +
"Sales" +
" # } else if (tmpIsActive && Active == 2) { # " +
"Corp" +
"# } #"
)
to be used on a server bound grid.
Thanks,
Joel

Hi, I've a page with 2 grids. Both of them has buttons to add elements, moreover I can pass data from one to the other. The problem that I've is that the grids data it's not reloaded. Once I try to reload the grids get empty and the function to load the data in the controller it's not called, also the code is showing I'm passing throught the dataSource.read(), the console.logs() are printed correctly. This was working 5 days ago, since then any change has been done on the cshtml and on the controller files.
Any help will be appreciated.
Thanks in advance.
These are my functions to reload the grids (javascript)
**************************************************************************************************
function reloadOrigenDestino(reloadALL = false) {
if (esOrigen == true || esOrigen == 'True' || reloadALL ) reload(true);
if (esOrigen == false || esOrigen == 'False' || reloadALL ) reload(false);
}
function reload(_esOrigen) {
if (_esOrigen) {
console.log('**** reload es origen');
$("#listaOrigen").data("kendoGrid").dataSource.read();
}
else {
console.log('*** reload es destino');
$("#listaDestino").data("kendoGrid").dataSource.read();
}
}
**************************************************************************************************
This is my html whith the 2 grids (both of them with different ids)
*************************************************************************************************
<!-- ************** GRID ORIGEN************** -->
<div class="bt_col_4">
<h3>@Estudios.labelForOrigen</h3>
@(Html.Kendo().Grid<Bogem.Areas.Estudios.Models.EstudiosOrigenDestinoVM>()
.Name("listaOrigen")
.Columns(columns =>
{
columns.Bound(c => c.IdOrigenDestino).Hidden(true);
columns.Bound(c => c.EsOrigen).Hidden(true);
columns.Bound(c => c.CodigoPostal).Visible(true);
columns.Bound(c => c.Poblacion).Visible(true);
columns.Bound(c => c.Alias).Visible(true);
columns.Bound(c => c.Punto).Visible(true);
columns.Bound(o => o.IdOrigenDestino).Title(Resources.Editar).Width(45).MinResizableWidth(45).Sortable(false).Filterable(false)
.ClientTemplate("<a href='javascript:(showAddEditOrigenDestino(#= IdOrigenDestino #, #= EsOrigen #));'><i class='k-icon k-i-edit k-icon-22'></i></a>")
.HtmlAttributes(new { style = "text-align: center" })
.Visible((bool)ViewData["canEdit"]).ToString();
columns.Bound(o => o.IdOrigenDestino).Title(Resources.Eliminar).Width(45).MinResizableWidth(45).Sortable(false).Filterable(false)
.ClientTemplate("<a href='javascript:(showDialogDeleteOrigenDestino(#= IdOrigenDestino #, #= EsOrigen #));'><i class='k-icon k-i-trash k-icon-22'></i></a>")
.HtmlAttributes(new { style = "text-align: center" })
.Visible((bool)ViewData["canDelete"]).ToString();
})
.ToolBar(toolbar =>
{
if ((bool)ViewData["canAdd"]) toolbar.Custom().IconClass("k-icon k-i-add k-icon-22").Text(Estudios.titleForAddOrigen).Url("#").HtmlAttributes(new { onclick = "showAddEditOrigenDestino(-1, '" + true + "');" });
})
.HtmlAttributes(new { style = "text-align: right" })
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.MultipleColumn);
})
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains(Resources.filtroContains)
.IsEqualTo(Resources.filtroEqualTo)
.IsNotEqualTo(Resources.filtroNotEqualTo)
)
)
)
.Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.Editable(edit => edit.Mode(GridEditMode.PopUp))
.Scrollable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.IdOrigenDestino))
.Read(read => read.Action("CargaListadoNuevo", "OrigenDestino", new { esOrigen = true }))
)
)
</div>
<!-- ************** GRID DESTINO ************** -->
<div class="bt_col_4">
<h3>@Estudios.labelForDestino</h3>
@(Html.Kendo().Grid<Bogem.Areas.Estudios.Models.EstudiosOrigenDestinoVM>()
.Name("listaDestino")
.Columns(columns =>
{
columns.Bound(c => c.IdOrigenDestino).Visible(false);
columns.Bound(c => c.EsOrigen).Visible(false);
columns.Bound(c => c.CodigoPostal).Visible(true);
columns.Bound(c => c.Poblacion).Visible(true);
columns.Bound(c => c.Alias).Visible(true);
columns.Bound(c => c.Punto).Visible(true);
columns.Bound(o => o.IdOrigenDestino).Title(Resources.Editar).Width(45).MinResizableWidth(45).Sortable(false).Filterable(false)
.ClientTemplate("<a href='javascript:(showAddEditOrigenDestino(#= IdOrigenDestino #, #= EsOrigen #));'><i class='k-icon k-i-edit k-icon-22'></i></a>")
.HtmlAttributes(new { style = "text-align: center" })
.Visible((bool)ViewData["canEdit"]).ToString();
columns.Bound(o => o.IdOrigenDestino).Title(Resources.Eliminar).Width(45).MinResizableWidth(45).Sortable(false).Filterable(false)
.ClientTemplate("<a href='javascript:(showDialogDeleteOrigenDestino(#= IdOrigenDestino #, #= EsOrigen #));'><i class='k-icon k-i-trash k-icon-22'></i></a>")
.HtmlAttributes(new { style = "text-align: center" })
.Visible((bool)ViewData["canDelete"]).ToString();
})
.ToolBar(toolbar =>
{
if ((bool)ViewData["canAdd"]) toolbar.Custom().IconClass("k-icon k-i-add k-icon-22").Text(Estudios.titleForAddOrigen).Url("#").HtmlAttributes(new { onclick = "showAddEditOrigenDestino(-1, '" + false + "');" });
})
.HtmlAttributes(new { style = "text-align: right" })
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.MultipleColumn);
})
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains(Resources.filtroContains)
.IsEqualTo(Resources.filtroEqualTo)
.IsNotEqualTo(Resources.filtroNotEqualTo)
)
)
)
.Editable(edit => edit.Mode(GridEditMode.PopUp))
.Scrollable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.IdOrigenDestino))
.Read(read => read.Action("CargaListadoNuevo", "OrigenDestino", new { esOrigen = false }))
)
)
</div>
**************************************************************************************************
My read function from server
*************************************************************************************************
[BogemAuthorization(Option = OpcionesModulo.ESTU_G_ORGDEST, NivelAcceso = new TipoAcceso[] { TipoAcceso.Lectura })]
public ActionResult CargaListado([DataSourceRequest]DataSourceRequest request, bool esOrigen)
{
List<EstudiosOrigenDestinoBO> estudios = new List<EstudiosOrigenDestinoBO>();
if (esOrigen) estudios = _origenDestinoBL.GetOrigenes(GetCurrentEstudio()).ToList().Where(x => x.IdSysState == (int)SystemState.Active).ToList();
else estudios = _origenDestinoBL.GetDestinos(GetCurrentEstudio()).ToList().Where(x => x.IdSysState == (int)SystemState.Active).ToList();
foreach (EstudiosOrigenDestinoBO item in estudios)
{
item.Poblacion = _poblacionBL.GetPoblacion(item.IdPoblacion).Poblacion;
item.CodigoPostal = _codigoPostalBL.GetCodigoPostal(item.IdCP).CP;
}
DataSourceResult result = estudios.ToDataSourceResult(request, _estudios => new
{
IdOrigenDestino = _estudios.IdOrigenDestino,
IdEstudio = _estudios.IdEstudio,
EsOrigen = _estudios.EsOrigen,
IdCP = _estudios.IdCP,
IdPoblacion = _estudios.IdPoblacion,
Alias = _estudios.Alias,
Punto = _estudios.Punto,
IdSysState = _estudios.IdSysState,
CodigoPostal = _estudios.CodigoPostal,
Poblacion = _estudios.Poblacion
});
return Json(result);
}
Currently I have a grid that uses a helper to specify the attributes:
.Filterable(f => f
.Extra(false)
.Operators(o => o
.ForString(str => str
.Clear()
.Contains("Contains")
.StartsWith("Starts with")
.IsEqualTo("Is equal to")
.IsNotEqualTo("Is not equal to")
)
.ForNumber(num => num
.Clear()
.IsEqualTo("Is equal to")
.IsGreaterThan("Is greater than")
.IsLessThan("Is less than")
)
)
)
The filterable data in the grid is encoded, s. o 'a b' is stored as 'a%20b'. I would like to build a custom filter using the helpers that allows the user to filter on 'a b'?
Serverbound grid
Noticed that when we create an item in the Scheduler and check the All Day checkbox the resulting Recurrence Rule adds an extra day. This leads to an extra day showing up in the Scheduler interface. We don't set any specific timezone on the scheduler, we actually hide all the timezone options in the interface as it just confuses our users:
//hide the timezone selections
e.container.find("[data-role=timezoneeditor]").hide();
e.container.find("[data-role=timezoneeditor]").parent('div').hide();
$('label[for="StartTimezone"]').hide();
$('label[for="StartTimezone"]').parent('div').hide();
e.container.find("label[for='EndTimezone']").hide();
e.container.find("label[for='EndTimezone']").parent('div').hide();
For example I create an event that starts on March 28, 2019, repeats daily and ends on Mar 30 3019 and check "All Day" checkbox - the resulting recurrence rule is saved as FREQ=DAILY;UNTIL=20190331T025959Z. In the scheduler we see the event on the 31st of March.
I can send you the code we have for the CustomEditortemplate.cshtml. The clocks moved forward an hour this month (now Atlantic Daylight Time ADT) if that provides a clue, can't be assured if this was happening before the time change or not though...
Also start and end times are saved as 2019-03-28 00:00:00.000 - zeros for the time portion in our SQL Server - when I look at the models in EventSchedule_Create([DataSourceRequest] DataSourceRequest request, IEnumerable<EventScheduleViewModel> models) the start time and end time are 12:00:00 AM so this might be Entity Framework or SQL server ?
I have a Kendo ListBox that I need to set a single item selected through a JavaScript function. I know both the text and value that I want to set, but can't figure out how. Any help appreciated!
Steve.