Custom Max aggregate on a Date column in kendo grid - kendo-grid

I am trying to perform a custom max aggregate on a date column in a kendo grid and display it using the ClientFooterTemplate at the bottom of the column. I want to calculate the max aggregate only when all dates under the date column have values.
#(Html.Kendo().Grid<InstallerWrapper>().Name(#"InstallerTable")
.DataSource(dataSource => dataSource
.Ajax()
.Model(m => m.Id(o => o.InstallerId))
.Read(read => read
.Action("GetInstaller", "DataProvider", new { orderId = Model.OrderId })
.Type(HttpVerbs.Post))
.Aggregates(aggregates =>
{
aggregates.Add(o => o.SurveyReceivedDate).Max();
})
.PageSize(20)
)
.Columns(columns =>
{
columns.Bound(o => o.InstallerId).Title("Installer")
.ClientTemplate("#=VendorName#")
.Filterable(false).Width(225)
.ClientFooterTemplate("All")
.Sortable(false);
columns.Bound(o => o.SurveyReceivedDate).Title("Survey Received")
.HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" })
.Filterable(false)
.ClientTemplate("#=SurveyReceivedDate#")
.ClientFooterTemplate("#=kendo.toString(kendo.parseDate(max),'MM/dd/yyyy')#")
.Sortable(false);
})
.Selectable()
.Sortable()
.Filterable()
.Pageable(p => p.Refresh(true)))

Use a function in the ClientFooterTemplate for the column to get this.
columns.Bound(o => o.SurveyReceivedDate).Title("Survey Received").HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" }).Filterable(false)
.ClientTemplate("#=SurveyReceivedDate#")
.ClientFooterTemplate("#if (getMaxDateText()){# #} else{# #=kendo.toString(kendo.parseDate(max),'MM/dd/yyyy')# #} #")
.FooterHtmlAttributes(new { style =" color: red "})
.Sortable(false);
Javascript Function:
<script>
function getMaxDateText() {
var surveyReceivedArray = [];
var data = $("#InstallerTable").data("kendoGrid").dataSource._data;
for (var i = 0; i < data.length; i++) {
surveyReceivedArray.push(data[i].SurveyReceivedDate);
}
var isAtLeastOneNull = surveyReceivedArray.some(function (o) { return o === null; });
if (isAtLeastOneNull) {
return true;
}
else {
return false;
}
}
</script>

Related

How to hide one column based on condition in kendo grid

Below is my kendo grid in this grid I need to hide Case Number column conditionally that means if(admin == true) I need to show this column or else I need to hide this column how can I do this
#(Html.Kendo().Grid(Model.GiIncidentReportList)
.Name("IRGrid").Columns(columns => {
columns.Bound(r => r.IncidentReport).Title("Case Number");
columns.Bound(r => r.IncidentCreatedByName).Title("Created By");
columns.Bound(r => r.IncidentCreatedDateTime).Title("Created Date");
columns.Bound(r => r.IncidentUpdatedByName).Title("Updated By");
columns.Bound(r => r.IncidentUpdatedDateTime).Title("Updated Date");
columns.Template(p =>
#Html.ActionLink("Delete","DeleteIncidentReport","IncidentReport",
new { incidentReportId = p.IncidentReport.IR_IncidentID, dlLogId = p.IncidentReport.DL_LogID, incidentType = p.IncidentReport.IT_IncidentType },
new { #class = "k-button k-button-icontext", onclick = "return confirm('Are you sure you wish to delete this report?')" }).ToHtmlString()
);
})
)
What I tried
if(admin == true){
var grdView = $('#IRGrid').data('kendoGrid');
grdView.hideColumn("IncidentReport"); //By Using Columns Name.
}
It is working but I want to handle the show and hide at columns.bound only instead of using if condition.
Have your admin property in your model and use .Hidden(#Model.admin) property to show hide the column
#(Html.Kendo().Grid(Model.GiIncidentReportList)
.Name("IRGrid").Columns(columns => {
columns.Bound(r => r.IncidentReport).Title("Case Number").Hidden(#Model.admin);
columns.Bound(r => r.IncidentCreatedByName).Title("Created By");
columns.Bound(r => r.IncidentCreatedDateTime).Title("Created Date");
columns.Bound(r => r.IncidentUpdatedByName).Title("Updated By");
columns.Bound(r => r.IncidentUpdatedDateTime).Title("Updated Date");
columns.Template(p =>
#Html.ActionLink("Delete","DeleteIncidentReport","IncidentReport",
new { incidentReportId = p.IncidentReport.IR_IncidentID, dlLogId = p.IncidentReport.DL_LogID, incidentType = p.IncidentReport.IT_IncidentType },
new { #class = "k-button k-button-icontext", onclick = "return confirm('Are you sure you wish to delete this report?')" }).ToHtmlString()
);
})
)
You can pass the Value through #Viewbag and give the condition like this
#(Html.Kendo().Grid(Model.GiIncidentReportList)
.Name("IRGrid").Columns(columns => {
if (#ViewBag.admin == "True")
{
columns.Bound(r => r.IncidentReport).Title("Case Number");
}
columns.Bound(r => r.IncidentCreatedByName).Title("Created By");
columns.Bound(r => r.IncidentCreatedDateTime).Title("Created Date");
columns.Bound(r => r.IncidentUpdatedByName).Title("Updated By");
columns.Bound(r => r.IncidentUpdatedDateTime).Title("Updated Date");
columns.Template(p =>
#Html.ActionLink("Delete","DeleteIncidentReport","IncidentReport",
new { incidentReportId = p.IncidentReport.IR_IncidentID, dlLogId = p.IncidentReport.DL_LogID, incidentType = p.IncidentReport.IT_IncidentType },
new { #class = "k-button k-button-icontext", onclick = "return confirm('Are you sure you wish to delete this report?')" }).ToHtmlString()
);
})
)

How to pass object as parameter to kendo grid read method

I have kendo grid as follow.
#(Html.Kendo().Grid<ManualInputDetail>()
.Name("gManualInputDetail")
.Columns(columns =>
{
columns.Bound(c => c.Id).Hidden(true);
columns.Bound(c => c.Month).Title("Month");
columns.Bound(c => c.Value).Title("Value");
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Navigatable()
.Selectable(selectable =>
{
selectable.Mode(GridSelectionMode.Single);
selectable.Type(GridSelectionType.Row);
})
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.MultipleColumn);
})
.DataSource(dataSource => dataSource
.WebApi()
.Model(model => model.Id(p => p.Id))
.PageSize(12)
.Read(read => read.Url(Url.HttpRouteUrl("ActionApi", new { controller = "ManualInputDetails", action = "GetManualInputDetails" })).Data("getFilterData"))
)
.Pageable(p => p.Refresh(true))
)
using getFilterData function I want to pass object parameter to read method. getFilterData function as follow
function getFilterData() {
var header= {
SectorId: 1,
BrandId: 2,
LocationId: 1,
DataElementId:2
}
return {
header: header
};
}
GetManualInputDataElements method as follow
[ActionName("GetManualInputDetails")]
public DataSourceResult GetManualInputDetails([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request,ManualInputHeader header)
{
var model = new DataElementMgt().GetAll(header).Select(x => new DataElement()
{
Id = x.Id,
DataElementTypeId = x.DataElementTypeId,
Name = x.Name,
Descriptionn = x.Descriptionn
}).ToList().ToDataSourceResult(request);
return model;
}
In here header value always gives as null. What is the reason for that. Is any thing wrong? Please help..
change the getFilterData method to this
function getFilterData() {
var _header= {
SectorId: 1,
BrandId: 2,
LocationId: 1,
DataElementId:2
}
return {
header: _header
};
}
and it should work. dont use the same name for what you return and declare.

Populating ASP.NET MVC Kendo Grid Via Ajax Call

I have an MVC Kendo Grid and I want to fill it via a jQuery Ajax Call. I used jQuery 'each' method to do it like this :
function FillRowsByRequest(reqRow) {
var readDataUrl = '#Url.Action("GetGoodsByReq")';
var targetGrid = $("#storeReceiptRowsGrid").data("kendoGrid");
$.get(readDataUrl, { reqseq: reqRow }, function (d, t, j) {
var counter = 0;
targetGrid.cancelChanges();
$(d).each(function (i, e) {
targetGrid.dataSource.insert(counter++, {
GOOD_ID: e.GOOD_ID,
GOOD_CODE: e.GOOD_CODE,
GOOD_CODE_DESC: e.GOOD_CODE_DESC,
GOOD_DESC: e.GOOD_DESC
});
});
});
}
I can see my Kendo Grid that is filled with data ( not completely ) but the thing is that when I click on the Save button, it does not trigger the Save Action Method and consequently nothing is inserted in the table and Grid contains nothing after it is refreshed.
#(Html.Kendo()
.Grid<Tpph.Models.STORE_RECEIPT_ROW>()
.Name("storeReceiptRowsGrid")
.Columns(columns =>
{
columns.Bound(o => o.GOOD_ID).Title("Good ID").HtmlAttributes(new { #class = "goodid" }).Visible(false);
columns.Bound(o => o.GOOD_CODE).Title("Good Code").HtmlAttributes(new { #class = "goodcode" }).Width(100);
columns.Bound(o => o.GOOD_CODE_DESC).Title("Good Code Desc").HtmlAttributes(new { #class = "goodcodedesc" }).Width(100);
columns.Bound(o => o.GOOD_DESC).Title("Good Desc").HtmlAttributes(new { #class = "gooddesc" }).Width(155);
})
.ToolBar(toolbar =>
{
toolbar.Create().Text("New Row").HtmlAttributes(new { #class = "k-primary", style = "background-color: #e6ffe6; border-color: #10c4b2; min-width: 100px; color: black;" });
toolbar.Save().Text("Save").SaveText("Save").CancelText("Cancel").HtmlAttributes(new { #class = "k-primary", style = "background-color: #e6ffe6; border-color: #10c4b2; min-width: 100px; color: black;" });
})
.ColumnMenu()
.Selectable(s => s.Type(GridSelectionType.Row))
.Sortable()
.Editable(editable => editable.Mode(GridEditMode.InCell).DisplayDeleteConfirmation("Delete?"))
.Filterable()
.Groupable()
.Scrollable()
.Pageable(p => p.Refresh(true))
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Events(ev => ev.RequestEnd("storeReceiptRowsGridOnRequestEnd"))
.Batch(true)
.ServerOperation(true)
.Model(model =>
{
model.Id(p => p.GOOD_ID);
})
.Read(read => read.Action("StoreReceiptRowsRead", "StorageForms"))
.Update(u => u.Action("StoreReceiptRowsEdit", "StorageForms"))
.Create(c => c.Action("StoreReceiptRowsCreate", "StorageForms"))
.Destroy(de => de.Action("StoreReceiptRowsDestory", "StorageForms")))
.Events(ev =>
{
ev.DataBound("storeReceiptRowsGridOnBound");
})
)
How can I do this ?
After lots of struggling with this issue, I finally found out that the Kendo Grid triggers the CRUD Action Methods only when the "dirty" attribute of a row is set to true. ( dirty flag is a tiny little red triangle which appears in the corner of a cell when you edit that cell ). So the solution to this issue is setting dirty flag of each row to true like this :
.set("dirty", true);
So my final JavaScript Code is like this :
function FillRowsByRequest(reqRow) {
var readDataUrl = '#Url.Action("GetGoodsByReq")';
var targetGrid = $("#storeReceiptRowsGrid").data("kendoGrid");
$.get(readDataUrl, { reqseq: reqRow }, function (d, t, j) {
var counter = 0;
targetGrid.cancelChanges();
$(d).each(function (i, e) {
targetGrid.dataSource.insert(counter++, {
GOOD_ID: e.GOOD_ID,
GOOD_CODE: e.GOOD_CODE,
GOOD_CODE_DESC: e.GOOD_CODE_DESC,
GOOD_DESC: e.GOOD_DESC
}).set("dirty", true);
});
});
}

Error event handling causes Read to not be called

Below is my PartialView for a Kendo Grid. As of now, my Parts_Read action is NOT called. But, if I comment out
.Events(events => events.Error("error_handler"))
Then everything works fine. Any ideas of why this is happening?
#using Kendo.Mvc.UI;
#using eRPortalDashboard.Models
#model PMPartsViewModel
#{
int PMNumber = Model.PMNumber;
string uniqueName = Model.PartsGrid.ID;//Regex.Replace(Guid.NewGuid().ToString(), "[^A-Za-z]+", "");
bool enableToolbar = Model.PartsGrid.EnableToolbar;
bool enablePageable = Model.PartsGrid.Pageable;
bool enableSortable = Model.PartsGrid.Sortable;
bool enableColumnMenu = Model.PartsGrid.EnableColumnMenu;
bool enableGroupable = Model.PartsGrid.Groupable;
bool enableColumnResizing = Model.PartsGrid.AllowColumnResizing;
bool enableScrolling = Model.PartsGrid.Scrollable;
bool enableSelection = Model.PartsGrid.Selectable;
}
#(Html.Kendo().Grid<PartViewModel>()
.Name(uniqueName)
.Columns(columns =>
{
columns.Bound(c => c.ItemNumber);
columns.Bound(c => c.Description);
})
.ToolBar(toolBar =>
{
toolBar.Custom().Text("Test Button").Url("#").HtmlAttributes(new { id = "testButton" });
})
.Pageable(pager => pager
.Input(false) //Using pageable.numeric and pageable.input at the same time is not recommended.
.Numeric(true)
.Info(true)
.PreviousNext(true)
.Refresh(true)
.PageSizes(new object[] { 5, 10, 20, 50, "all" })
.Enabled(enablePageable)
)
.Selectable(s => s.Mode(mode: GridSelectionMode.Multiple).Enabled(enableSelection))
.AllowCopy(enableSelection) //selectable needs to be enabled and set to multiple
.Sortable(s => s.SortMode(GridSortMode.MultipleColumn).Enabled(enableSortable))
.ColumnMenu(c => c.Enabled(enableColumnMenu))
.Groupable(g => g.Enabled(enableGroupable))
.Scrollable(s => s.Height("auto").Enabled(enableScrolling))
.Resizable(resize => resize.Columns(enableColumnResizing))
//.Events(events => events.DataBound(uniqueName + "_updateGrid").Change(uniqueName + "_updateGrid"))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.Events(events => events.Error("error_handler"))
.Read("Parts_Read", "PM", new { PMNumber = PMNumber })
)
)
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
The main crux of my issue was the fact that error_handler was declared after my MVC code, thereby making it unable to bind to the method.
Apparently, with Kendo (maybe others), when using Partial Views, the javascript function must be declared BEFORE it is used in Razor syntax for that view.
see also: telerik forum post

How to pass selected row of Kendo grid data to controller

I've got a kendo grid with an image near it that will act like a button. When pressed, it will call a controller method. I want to send the selected row data to that method.
VIEW
<a href="#" id="ic_open" class="tooltip2" title="Abrir">
<span title="">
<img class="toolbar-icons" src="../../Images/open.png"/>
</span>
</a>
...
<div id="datagrid">
#(Html.Kendo().Grid(Model)
.Name("datagrid_Concessoes")
.Columns(columns =>
{
columns.Bound(c => c.Id).Width(70);
columns.Bound(c => c.Code);
columns.Bound(c => c.Description);
columns.Bound(c => c.CreationDate);
columns.Bound(c => c.CreationUser);
})
.HtmlAttributes(new { style = "height: 534px;" })
.Scrollable()
.Sortable()
.Selectable()
.Pageable(pageable => pageable
.Refresh(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(15)
.Read(read => read.Action("GetConcessoes", "MasterData"))
)
)
</div>
And the script:
<script type="text/javascript">
$(function () {
$('.tooltip2').click(function () {
var id = this.id;
$.get('#Url.Content("GetPartialView")',
{ "id": id },
function (data) {
$('#div-for-partial').html(data);
});
});
});
</script>
This script sends the link's id (ic_open) to the controller successfully. I want to send the selected row data, via this same function or some other (doesn't matter), to the controller so I can manipulate that info.
EDIT
Controller method
public ActionResult GetPartialView(string id)
{
switch (id)
{
case "":
return PartialView("_Concessoes");
case "tab1":
return PartialView("_Concessoes");
case "tab2":
return PartialView("_AutoEstradas");
case "ic_open":
return PartialView("_NovaConcessao");
}
return RedirectToAction("Index");
}
Your Script should be as below:
<script type="text/javascript">
$(function () {
$('.tooltip2').click(function () {
var id = this.id;
var concessoesGrid = $("#datagrid_Concessoes").data("kendoGrid");
var row = concessoesGrid.select();
$.get('#Url.Content("GetPartialView")',
{ "id": id, "modelData":row },
function (data) {
$('#div-for-partial').html(data);
});
});
});
</script>
Now there will be change on your controller side also:
public ActionResult GetPartialView(string id, ModelClass modelData)
{
//here you can access the modelData Object which will have the value of Selcted row of Grid
switch (id)
{
case "":
return PartialView("_Concessoes");
case "tab1":
return PartialView("_Concessoes");
case "tab2":
return PartialView("_AutoEstradas");
case "ic_open":
return PartialView("_NovaConcessao");
}
return RedirectToAction("Index");
}
NOTE: if you want to pass multiple selected grid records to controller then you will need to change the controller argument to accept List of objects.
I am using KendoJS but I believe this would also work on your side too:
var grid = $("yourgrid's id or class");
var selectedRow;
grid.change = function()
{
grid.select().each(function () {
var dataItem = grid.dataItem($(this));
selectedRow = dataItem;
});
}
I also found this for Kendo ASP.NET MVC:
#(Html.Kendo().Grid(Model)
.Name("grid")
.Events(e => e
.DataBound(#<text>
function() {
//Handle the dataBound event inline
}
</text>)
.Change(#<text>
var selectedRow;
function() {
var grid = this;
grid.select().each(function () {
var dataItem = grid.dataItem($(this));
selectedRow = dataItem;
});
}
</text>)
)
)
After getting the selected row, the rest is easy. Just send the value you want into your hidden value element on your cshtml page or just call the ajax method for your controller right over on your JavaScript code.