Change the title of groub column in kendo mvc grid - kendo-ui

I have a grid , and i am grouping the data on date column like this :
.Group(g => g.Add(c => c.EmployeeId)).Group(g => g.Add(c => c.CheckInTime.Day))
and it works fine, but the problem is the title is CheckInTime.Day .
my question is how can i change this title ?
Thanks

If you have a column field that matches the group field then you can set the bound fields Title to whatever you want to display. However, I don't think you can have a different title for the column and group header.
columns.Bound(c => c.CheckInTime.Day).Width(100).Title("This will in column header and group header");
If you do not have a bound column that matches a group field then you might be able to get away with something like:
columns.Bound(c => c.CheckInTime.Day).Title("Group Title")
.HtmlAttributes(new { style = "visibility:hidden;" })
.HeaderHtmlAttributes(new { style = "visibility:hidden;" })
.ClientGroupFooterTemplate(new { style = "visibility:hidden;" })
.FooterHtmlAttributes(new { style = "visibility:hidden;" })
However, using the above hack adds a ui inconsistency on the first column. There may be a more elegant way to have a group field without a bound column display a different title using js, have not found it yet.

Related

How to show aggregated value in ClientGroupHeaderTemplate in Kendo Grid

I am using UI for ASP.NET MVC to build a grid. I want to group rows by the Name column and show sum of the Cost column in the group header.
Here is my grid
#(Html.Kendo().Grid<GridModel>()
.Name("myGrid")
.Columns(col =>
{
col.Bound(p => p.Name).Width(300);
col.Bound(p => p.Year).Width(100);
col.Bound(p => p.Cost).Width(100)
.ClientGroupHeaderTemplate("Total: #: sum #");
})
.AutoBind(true)
.DataSource(dataSource => dataSource
.Ajax()
.Aggregates(aggregates =>
{
aggregates.Add(p => p.Cost).Sum();
})
.Group(groups => groups.Add(p => p.Name))
.Read(read => read
.Action("GetData", "Home", new { ID = Model.ID }))
.ServerOperation(false))
)
The grid above does not show or render sum in group header.
The demo here shows how to do it, however it showing aggregated values in group footer. I want to show sum in group header.
In above grid if i replace ClientGroupHeaderTemplate with ClientGroupFooterTemplate then i see sum in group footer, but i want to show sum in group header.
What i am missing here
Update 1
Also as per the documentation aggregates object is available in ClientGroupHeaderTemplate which provides access to all available aggregates
aggregates - provides access to all available aggregates, e.g.
aggregates.fieldName1.sum or aggregates.fieldName2.average
so i tried
col.Bound(p => p.Cost).Width(100)
.ClientGroupHeaderTemplate("Total: #= aggregates.Cost.sum #");
but this did not work either.
It looks like ClientGroupHeaderTemplate only works if the column is a part of group.
In my case I am grouping by Name column so Cost column is not part of Group
aggregates will not work for older versions of kendo
Without grouping
Try putting this in javascript
var aggregates;
$(function(){
// get aggregates from datasource. Access to all aggregates
aggregates = $("#grid").data("kendoGrid").dataSource.aggregates();
})
Along with this in view
col.Bound(p => p.Cost).Width(100).ClientGroupHeaderTemplate("Total: #= aggregates.Cost.sum #");

Kendo UI DropDownListFor Set SelectedValue

I'm working with Kendo UI on an MVC application. We have a grid and when the user opens the row for editing we have a dropDownList that holds company names. I'm trying to get the DDL to default to the company name that's pertinent to the row.
Here's the column code:
columns.Bound(e => e.company_business_name).Width(220).Title("Company")
.EditorTemplateName("CompanyName");
and here's the editorTemplate code:
#model string
#(Html.Kendo().DropDownListFor(m => m)
.DataTextField("Text")
.DataValueField("Value")
.BindTo((System.Collections.IEnumerable)ViewData["Companies"])
)
and the method that fills the DDL:
private void PopulateCompanies()
{
var companyList = new List<SelectListItem>();
if (!string.IsNullOrEmpty(Session["Companies"] as string))
{
companyList = (List<SelectListItem>)Session["Companies"];
}
else
{
companyList = new DataAccess().GetCompanies(CurrentSettings.getUser().userId);
CacheCompanies(companyList);
}
ViewData["Companies"] = companyList;
}
EDIT:
Updated the code. The DDL still populates but I'm still not getting the selected value when I click "edit" on the grid row. Feel like I'm close here, help!
The problem is that your Editor Template's model is your entire model, not the company_business_name property (Very bad name for a property, by the way. You need to follow the standard naming conventions).
You don't even need to fill the drop down list.
Your Editor Template should be something like this:
#model string
#(Html.Kendo().DropDownListFor(m => m)
.DataTextField("Text")
.DataValueField("Value")
.DataSource(x =>
x.Read(read => read.Action("GetCompanies", "AddEntry"))
)
)

Kendo UI ASP.Net MVC ForeignKey column DataSource in InCell Edit mode

I have Kendo Grid and a ForeignKey column on a page. ForeignKey column is populated using ViewData as described below.
column.ForeignKey(x => x.ProductID, (List<Product>)ViewData["products"], "ID", "ProdName");
The Grid is editable in batch(InCell) mode as show below...
.Editable(editable => editable.Mode(GridEditMode.InCell)
I want to modify collection of ProductID column in the grid after page is loaded based on value selected on other drop-down defined outside of the Grid.
How can I achieve that? Can I do it using jQuery?
Similar example I found here...
http://www.telerik.com/community/forums/aspnet-mvc/grid/cascading-dropdowns-in-grid-edit---foreignkey-columns.aspx
Thanks.
I figured out how to filter the Product drop-down using an EditorTemplate for the foreign key column.
Here is my column definition for the Product.
c.ForeignKey(x => x.ProductID, (List<Product>)ViewData["products"], "ID", "ProdName").EditorTemplateName("ProductIDEditor");
Here is the editor template for Product, ProductIDEditor.cshtml
#using Kendo.Mvc.UI
#(Html.Kendo().DropDownListFor(m => m)
.AutoBind(false)
.OptionLabel("Select a value...")
.DataTextField("ProdName")
.DataValueField("ID")
.DataSource(dataSource =>
{
dataSource.Read(read => read.Action("FilterProducts", "Home").Data("filterProducts"))
.ServerFiltering(true);
})
)
#Html.ValidationMessageFor(m => m)
In my main VIEW Index.cshtml, I added filterProducts JavaScript handler, that passes JSON object for productID to controller.
function filterChargeTypes()
{
return {
productID: $("#ProductID").val()
};
}
Here is the controller that listens to filtering event...
public ActionResult FilterProducts(string productID)
{
// do your filtereing based on productID.
}
FilterProducts will be called every time when user hits the drop-down to get filtered value.
You don't need the Editor Template. It will bind to a dropdown without it. You can use this, like you had, just minus the template:
c.ForeignKey(x => x.ProductID, (List<Product>)ViewData["products"], "ID", "ProdName")
or
c.ForeignKey(x => x.ProductID, (System.Collections.IEnumerable)ViewData["products"], dataFieldValue: "ID", dataFieldText: "ProdName")
And for filtering, you can just invoke .Filterable() on the grid.

Loop through IEnumerable in #Html.DropDownListFor (MVC3)

I have a collection of models that I am passing to my view and I want to display each model.property in the dropdownlist. The problem is there is a bug in my code where it shows two duplicate items.
#model IEnumerable<UserManager.Models.vw_UserManager_Model>
#Html.Label("BRAD Module:")&nbsp
#Html.DropDownListFor(model => model.FirstOrDefault().module_name, Model.Select(x => new SelectListItem { Text = x.module_name, Value = x.module_name }), new { id = "ddlSelectedBrad", onchange = "chkSelection()" })
I am currently using FirstOrDefault() to access the module name for each model in my collection of models. But by doing this I have a duplicate value.
See screenshots below:
MARKET:LEISURE is showing twice
Intelligence is showing twice. If I change this dropdown value and return to this screen it will show two duplicate values.
Summary
Does anyone know a better way of writing the LINQ query?
Thanks.
Instead of
Model.Select(x => new SelectListItem { Text = x.module_name, Value = x.module_name })
Try
Model.GroupBy(x => x.module_name).Select(x => new SelectListItem { Text = x.First().module_name, Value = x.First().module_name })
This should filter the duplicate records.

How can I display a non aggregate model value in a Telerik MVC Grid aggregate header?

My grid:
#( Html.Telerik().Grid<eGate.BackOffice.Core.Model.UI.EgateMenuRevisionViewData>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(c => c.ParentId)
.Aggregate(a => a.Count()).ClientGroupHeaderTemplate(Html.ActionLink("Create a Revision for This Menu", "Edit", "Thing", new { menuid = "<#= Key #>" }, null).ToString());
columns.Bound(c => c.ParentName);
columns.Bound(c => c.ThingName);
})
.Groupable(grouping => grouping.Groups(groups => {
groups.Add(c => c.EgateMenu.EgateMenuId);
}).Visible(false))
This works. But it gives me:
Create a revision for this menu
1 Parent 1 Thing 1.1
1 Parent 1 Thing 1.2
1 Parent 1 Thing 1.3
Create a revision for this menu
2 Parent 2 Thing 2.1
2 Parent 2 Thing 2.2
2 Parent 2 Thing 2.3
And while that works, I'd much rather something more intuitive like:
Create a thing for parent 1
Thing 1.1
Thing 1.2
Thing 1.3
Create a thing for parent 2
Thing 2.1
Thing 2.2
Thing 2.3
Problem 1:
Create a thing for... needs to pass the ParentId to the actionlink but it needs to display the ParentName for the client yet only one exists in the aggregate at a time.
Problem 2:
I want to group by the Id without displaying the Id column in the results. But setting the column to visible(false) supresses the clientgroupheadertemplate.
Adding Visible(false) to the column binding suppresses the whole column itself from even being rendered in the client html - hence the suppression of the ClientGroupHeaderTemplate.
I would either try adding ParentId as a data key - e.g.
.DataKeys(keys =>
{
keys.Add(k => k.ParentId);
}
I think this would only help if you were using the built in grid (AJAX or Server) DataBinding though (for Insert at least). With an ActionLink however... I don't have much experience with using mvc html helpers in client templates - but if you said the orignal example worked with it, shouldn't something like this work as well?
columns.Bound(c => c.ParentId).ClientTemplate("")
.Aggregate(a => a.Count()).ClientGroupHeaderTemplate(Html.ActionLink("Create a thing for \"<#= ParentName #>\"", "Edit", "Thing", new { menuid = "<#= Key #>" }, null).ToString());
I added a blank ClientTemplate, which I assume would work so that the ID is not displayed.
Have you tried hiding the unwanted columns?
#( Html.Telerik().Grid<eGate.BackOffice.Core.Model.UI.EgateMenuRevisionViewData>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(c => c.ParentId).Visible(false);
.Aggregate(a => a.Count()).ClientGroupHeaderTemplate(Html.ActionLink("Create a Revision for This Menu", "Edit", "Thing", new { menuid = "<#= Key #>" }, null).ToString());
columns.Bound(c => c.ParentName).Visible(false);
columns.Bound(c => c.ThingName);
})
According telerik :
You can specify now Aggregate property with following values: Sum, Min, Max, Last, First, Count, Avg & Custom for every GridBoundColumn and the grid will calculate these aggregates if ShowFooter is set to true. In case of Custom aggregate the grid will raise event OnCustomAggregate where you can set desired result using e.Result.
So try First, Last or Custom options for every GridBoundColumn and set ShowFooter property to false.
<telerik:GridBoundColumn Aggregate="First" DataField="CustomerID" DataType="System.String"
HeaderText="CustomerID" SortExpression="CustomerID" UniqueName="CustomerID">
</telerik:GridBoundColumn>

Resources