Hi,
I have a very simple grid that binds to a object List collection property of my model:
@(Html.Kendo().Grid<ObjectBO>()
.Name("ObjectGrid")
.BindTo(Model.ObjectBOList)
.Columns(columns =>
{
columns.Select().Width(40);
columns.Bound(obj => obj.Id).Hidden();
columns.Bound(obj => obj.Description);
})
Whilst it displays and binds fine, the SELECT column only shows the "SELECT" checkbox in the column header (i.e. to select all rows) it does not show the individual checkboxes on the rows themselves against the items.
It works fine if I use the datasource property of the grid (rather than "BindTo")and get the same data via a datasource request, but this isn't really my preferred method because it will involve another DB call. I'd rather use the model collection,
Any ideas why this is happening?
Not sure if it's relevant, but the grid is displayed inside a Kendo Window shown modally.
Many thanks!
Hi!
I want to create a kendo grid with expandable detail grids, ie each master row will have an expand button which will create a detail row containing a new kendo grid with aligned columns. For this I use ClientDetailTemplateId. However, my problem is that the detail grids are always empty!
The view model used for each master row:
public
int
CountryId { get; set; }
public
string CountryName { get; set; }
public
IEnumerable<StateViewModel> StateList { get; set; }
StateList should be used to initiate the detail grids. My template looks like this
<
script
id
=
"template_StateList"
type
=
"text/kendo-tmpl"
>
<
p
style
=
"margin:1rem"
>The country has #=data.StateList.length# states.</
p
>
@(Html.Kendo().Grid<
StateViewModel
>()
.Name("grid_#=CountryId#")
.Columns(columns =>
{
columns.Bound(c => c.StateId).Width(265).Title("Id");
columns.Bound(c => c.StateName).Width(85).Title("Name");
})
.DataSource("#= StateList #")
.Sortable()
.ToClientTemplate())
</
script
>
I have found others with a similar problem that have solved this by using read.Action(), but I would really prefer it if I could pass the data through my view model instead. Thanks for your time!
Hello,
Anyone have any idea how to handle translation when you want to use data persistence?
Here, template helper + template kendo + kendo grid
@* ===================================== HELPER and Template ===================================== *@
@* =============== Toolbar =============== *@
@helper ToolbarTemplate()
{
<
div
>
<
a
class
=
"k-button k-button-icontext k-grid-excel"
href
=
"\#"
>@Tools.GetStringRessource("AllList_ExportToExcel", "Download To Excel")</
a
>
</
div
>
}
<
script
type
=
"text/x-kendo-template"
id
=
"toolbarTemplate"
>
@Html.Raw(@ToolbarTemplate().ToHtmlString().Replace("#", "\\#").Replace("</
scr
", "<\\/scr"))
</script>
@* =============== ColumnAction =============== *@
@helper ColumnActionTemplate(bool canEdit, bool canDelete)
{
@* Voir page CableDrum_Customer pour les différentes recherches *@
@* VERSION 2: Solution bricolé - href généré avec Url.Action (encode les params mais sera décodé dans le js pour retrouver #= #) *@
var hrefEdit = Url.Action("CableDrumEdit_Site", new { idCustomer = @ViewContext.RouteData.Values["idCustomer"], idSite = @ViewContext.RouteData.Values["idSite"], idCableDrum = "#=Id#" });
var edit = $"<
a
class=\"btn icon bg-white tooltip-bottom\" href=\"{@hrefEdit}\" title = \"{Tools.GetStringRessource("AllList_EditItem", "Edit")}\" >#=library.getKendoTemplate(data,'IconCreateTemplate')#</
a
>";
var resultEdit = Convert.ToBoolean(canEdit) ? edit : "";
var resultDelete = Convert.ToBoolean(canDelete) ? "#=library.getKendoTemplate(data,'DeleteTemplate')#" : "";
<
div
class
=
"action"
>
<
span
>
@Html.Raw(@resultEdit)
</
span
>
<
span
>
@Html.Raw(@resultDelete)
</
span
>
</
div
>
}
<
script
type
=
"text/x-kendo-template"
id
=
"columnActionTemplate"
>
@Html.Raw(@ColumnActionTemplate(ViewBag.CanEdit, ViewBag.CanDelete).ToHtmlString())
</
script
>
@* =============== Header =============== *@
@helper HeaderTemplate()
{
<
span
class
=
"k-link"
>
@Tools.GetStringRessource("AllList_EditBtn", "Action")
</
span
>
}
<
script
type
=
"text/x-kendo-template"
id
=
"headerTemplate"
>
@Html.Raw(@HeaderTemplate().ToHtmlString())
</
script
>
@* ===================================== FIN HELPER and Template ===================================== *@
@(Html.Kendo().Grid<
CableDrumUIDto
>()
.Name("CableDrumGrid")
.ToolBar(tools =>
{
tools.Template(@<
text
>@ToolbarTemplate()</
text
>);
})
.Excel(excel => excel
.FileName(Tools.GetStringRessource("ExportToExcel_CableDrums", "siteDrum.xlsx"))
.Filterable(true)
.AllPages(true)
)
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Read(read => read.Action("CableDrumInfo_Read", "CableDrums").Data("CableDrumLib.getAdditionalData").Type(HttpVerbs.Post))
)
.Events(e => e
.DataBound(@<
text
>function(e){ CableDrumLib.gridDataBound(); library.dataBound(); }</
text
>)
.ExcelExport("onExcelExport")
)
.Columns(columns =>
{
columns.Bound(p => p.ProductName).Title(Tools.GetStringRessource("CableDrum_ProductName", "PRODUCT NAME"));
columns.Bound(p => p.ProductRef).Title(Tools.GetStringRessource("CableDrum_ProductRef", "REFERENCE"));
columns.Bound(p => p.ProductRefCustomer).Title(Tools.GetStringRessource("CableDrum_ProductRefClient", "REFERENCE CUSTOMER"));
columns.Bound(p => p.LabelProductSerialNumber).Title(Tools.GetStringRessource("CableDrum_Identifier", "DRUM"));
columns.Bound(p => p.Location).Title(Tools.GetStringRessource("CableDrumEdit_DetailsTab_Location", "LOCATION"));
if (ViewBag.DisplayLengthInFeets.Equals(true))
{
columns.Bound(p => p.CurrentLengthInM).Title(Tools.GetStringRessource("CableDrum_ProductLengthInF", "LENGTH"));
}
if (ViewBag.DisplayLengthInMeters.Equals(true))
{
columns.Bound(p => p.CurrentLengthInM).Title(Tools.GetStringRessource("CableDrum_ProductLengthInM", "LENGTH"));
}
/**/
columns.Bound(p => p.CF_CustomerDrumNumber).Title(Tools.GetStringRessource("Generic_CF_CustomerDrumNumber", "Customer Drum Number")).Hidden();
columns.Bound(p => p.CF_CustomerShipmentDate).ClientTemplate("#= (CF_CustomerShipmentDate !== null) ? kendo.toString(CF_CustomerShipmentDate,'d') : '' #").Title(Tools.GetStringRessource("Generic_CF_CustomerShipmentDate", "Customer Shipment Date")).Hidden();
columns.Bound(p => p.CF_SaleOrderNumber).Title(Tools.GetStringRessource("Generic_CF_SaleOrderNumber", "Sale Order Number")).Hidden();
columns.Bound(p => p.CF_LineOrderNumber).Title(Tools.GetStringRessource("Generic_CF_LineOrderNumber", "Line Order Number")).Hidden();
columns.Bound(p => p.CF_CustomerPurchaseOrderNumber).Title(Tools.GetStringRessource("Generic_CF_CustomerPurchaseOrderNumber", "Customer Purchase Order Number")).Hidden();
columns.Bound(p => p.CF_CustomerLineOrderNumber).Title(Tools.GetStringRessource("Generic_CF_CustomerLineOrderNumber", "Customer Line Order Number")).Hidden();
columns.Bound(p => p.CF_ProductionOrderNumber).Title(Tools.GetStringRessource("Generic_CF_ProductionOrderNumber", "Production Order Number")).Hidden();
columns
.Template(@<
text
></
text
>)
.Title(@Tools.GetStringRessource("AllList_EditBtn", "Action"))
.HeaderTemplate(HeaderTemplate().ToHtmlString())
.Width(90)
.ClientTemplate(ColumnActionTemplate(ViewBag.CanEdit, ViewBag.CanDelete).ToHtmlString());
})
.NoRecords(Tools.GetStringRessource("Grid_NoRecords", "No Data"))
.ColumnMenu()
.Sortable(s => s.SortMode(GridSortMode.MultipleColumn))
.Reorderable(r => r.Columns(true))
.Resizable(r => r.Columns(true))
.Scrollable(sc => sc.Height("auto"))
.Pageable(page => page
.Input(true)
.Numeric(false)
.Info(true)
.PreviousNext(true)
.Messages(message => message
.Display(ViewBag.Title + " {0}-{1}/{2}")
.Empty(Tools.GetStringRessource("Grid_NoRecords", "No Data"))
.Of("/{0}")
.Page(string.Empty)
)
)
Here, i save grid option
window.onbeforeunload =
function
() {
var
elGrid = $(GRID_CABLEDRUM);
if
(elGrid !==
null
)
{
var
grid = elGrid.data(
"kendoGrid"
);
if
(grid !==
null
&& grid.element.length > 0)
{
var
fullOptions = grid.getOptions();
// Récupération uniquement des informations qui m'intéresse (affichage des colonnes, tri, filtre, taille colonnes)
var
options = {
columns: fullOptions.columns,
dataSource: fullOptions.dataSource
}
localStorage.setItem(`_kendoGridCookie_${grid.element[0].id}`, kendo.stringify(options));
}
}
}
Here i add my template toolbar + template header + i manually apply the translations.
var
gridElement = $(
this
);
var
gridId = gridElement[0].id;
var
kendoGrid = $(`
#${gridId}`).data("kendoGrid");
// Récupération des préférences utilisateurs de la grille dans le localStorage
var
kendoGridOptions = localStorage.getItem(`_kendoGridCookie_${gridId}`);
if
(kendoGridOptions && kendoGridOptions !==
null
) {
var
kendoGridOptionsParse = JSON.parse(kendoGridOptions);
// Ajout du template présent dans le toolbar https://github.com/telerik/ui-for-aspnet-mvc-examples/blob/master/grid/grid-preserve-server-toolbar-template-after-set-options/GridPerserveToolbarServerTemplate/Views/Home/Index.cshtml
var
templateToolbar = $(
"#toolbarTemplate"
).html();
if
(templateToolbar !== undefined) {
kendoGridOptionsParse.toolbar = [
{ template: templateToolbar }
];
}
//Récupération de la colonne Action. J'ai pas beaucoup de moyen pour l'identifier donc je me base sur qu'elle est la propriété template
var
colAction = kendoGridOptionsParse.columns.find(c => c.template !== undefined)
//Template header colonne action
var
templateHeader = $(
"#headerTemplate"
).html();
if
(templateHeader !== undefined) {
colAction.headerTemplate = templateHeader;
}
// Template colonne action
var
templateAction = $(
"#columnActionTemplate"
).html();
if
(templateAction !== undefined) {
var
action = decodeURIComponent(templateAction);
colAction.template = action;
}
//Récupération des traductions des entêtes des colonnes
if
(kendoGridOptionsParse !==
null
&& kendoGrid !==
null
&& kendoGridOptionsParse.columns !==
null
&& kendoGrid.columns !==
null
&& kendoGridOptionsParse.columns.length === kendoGrid.columns.length) {
for
(let indice = 0; indice < kendoGridOptionsParse.columns.length; indice++) {
var
kendoGridOptionsColCurrent = kendoGridOptionsParse.columns[indice]
var
listCorrespondanceColonne;
var
titleCurrent =
""
;
// Soit colonne lié à des champs
if
(kendoGridOptionsColCurrent.field !== undefined) {
listCorrespondanceColonne = kendoGrid.columns.filter(c => c.field !== undefined && c.field === kendoGridOptionsColCurrent.field);
}
else
{
// Soit colonne template
listCorrespondanceColonne = kendoGrid.columns.filter(c => c.field === undefined && c.template !== undefined);
}
if
(listCorrespondanceColonne.length === 1) {
titleCurrent = listCorrespondanceColonne[0].title;
}
kendoGridOptionsColCurrent.title = titleCurrent;
}
}
//Rechargement option https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/setoptions
kendoGrid.setOptions(kendoGridOptionsParse);
}
I see that the operation is not solid and I would like to find a more standard solution for the translation of the columns.
Thank you for your time.
I'm using the MVC Grid to allow users to search for items and add them to a BOM. The grid currently has three columns, ItemNumber, Description, and a column with a ClientTemplate that calls an Action method and passes it the ItemNumber.
I need to add a column that has an empty/unbound textbox that only accepts numbers so they can enter a quantity value that will also get passed to the Action method along with the ItemNumber.
Am I going about this the best way? Is there a better way? How can I add a numeric only textbox and capture the value entered and pass it to an Action method along with the ItemNumber?
My grid is defined as:
@(Html.Kendo().Grid<
AFLExternal.Models.afl_vw_OTS_Items
>()
.Name("OTSItemGrid")
.Columns(columns =>
{
columns.Bound(c => c.ITEMNMBR).Width(50).Title("")
.ClientTemplate(
"<
a
href='" +
Url.Action("AddItem", "OTSBOM") +
"?id=#= ITEMNMBR #'" +
"
class
=
'btn btn-success'
>#= ITEMNMBR #</
a
>"
);
columns.Bound(c => c.ITEMDESC).Title("Desc").Width(174).HtmlAttributes(new { style = "font-size: 12px;" });
})
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.AutoSync(false)
.Batch(true)
.Model(m =>
{
m.Field(p => p.ITEMNMBR).Editable(false);
m.Field(p => p.ITEMDESC).Editable(false);
})
.Read(read => read.Action("OTSItem_Read", "OTSBOM"))
.ServerOperation(true)
.Events(events => events.Error("error_handler"))
)
.ToolBar(toolBar =>
{
toolBar.Search();
})
.Height(400)
.Sortable()
.Navigatable()
.Search(srch =>
{
srch.Field(f => f.ITEMNMBR);
srch.Field(f => f.ITEMDESC);
})
)
Having spent may frustrating hours trying to solve this and now having found a solution, I thought that I would post my findings for the benefit of others.
Grid:
@(Html.Kendo().Grid<Models.Data.Database>
()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Name).Title(language.TranslateSchema(Enums.Schema.ImportData_Database));
columns.Bound(p => p.Legacy).Title(language.TranslateSchema(Enums.Schema.ImportData_Legacy)).Width(100);
columns.Bound(p => p.TableCount).Title(language.TranslateSchema(Enums.Schema.ImportData_TableCount)).Width(100);
columns.Command(c => c.Custom("Select").TemplateId("SelectTemplate")).Width(75);
})
.HtmlAttributes(new { style = "height: 450px; font-size: 12px" })
.Scrollable()
.Selectable(s => s
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(model => model.Id(m => m.Name))
.Read(read => read.Action("Utility", "Index", new { handler = "DatabaseRead" }).Data("AntiForgeryToken"))
)
)
Template:
<script type="text/x-kendo-template" id="SelectTemplate">
<a class="btn btn-s-primary"
onclick="SelectRow(this)"
data-toggle="tooltip"
data-trigger="hover"
data-delay="{ show: 1000,hide: 0}"
data-placement="bottom"
role="button"
title="@language.Translate(Enums.Tooltip.Question_Text)">
<span class='glyphicon glyphicon-ok'></span>
</a>
</script>
Script:
<script type="text/javascript">
function SelectRow(e) {
var grid = $("#grid").data("kendoGrid");
var item = grid.dataItem($(e).closest("tr")[0]);
if (item != null && item != "undefined") {
$.ajax({
url: "/Utility/Index?handler=SelectDatabase&name=" + item.Name,
datatype: "json",
type: "GET"
});
}
}
</script>
Findings:
I scoured the web and tried many solutions based around 'grid.select()' to no avail. The main problem and the moment of enlightenment came when I clicked on the row before clicking the custom link. When you click on the row - that row is selected - when you only click on the custom link the row is not selected !
I believe that the Template and script is self explanatory but please note that the script passes an instance of the clicked link to the script (onclick="SelectRow(this)") and further when locating the data the use of the 0 index ($(e).closest("tr")[0])
I could not find any reference to this problem and only found the solution through many attempts and breakpoints !
I am sure that there is a better solution, and I would be really grateful if Support would comment and enlighten me !
Greetings Telerik
I have the following Grid which I fill from a DataTable, everything works fine but when I add .Events (events => events .Change ("onChange")) it doesn't load anything, could you please help me, thank you very much in advance.
@model System.Data.DataTable
@(Html.Kendo().Grid<dynamic>
()
.Name("rgvListado")
.HtmlAttributes(new { style = "height: 650px;" })
.Scrollable()
.ToolBar(t => t.Search())
.Columns(columns =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
var c = columns.Bound(column.ColumnName);
}
})
.Sortable()
.Groupable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
var field = model.Field(column.ColumnName, column.DataType);
}
})
.Read(read => read.Action("ReadTable", "General"))
.ServerOperation(false)
)
.Events(events => events
.Change("onChange"))
)
Hi,
How to expand the detail template automatically when ClientRowTemplate is used? Here is the code I have. Not sure what is missing.
@(Html.Kendo().Grid<
Models.ResViewModel
>()
.Name("grid")
.HtmlAttributes(new { style = "height:550px; width:100%;" })
.ClientRowTemplate(
"<
tr
data-uid
=
'#: uid #'
class
=
'k-master-row'
role
=
'row'
><
td
class
=
'k-hierarchy-cell'
aria-expanded
=
'true'
><
a
class
=
'k-icon k-i-collapse'
href
=
'\\#'
aria-label
=
'Collapse'
tabindex
=
'-1'
></
a
></
td
>" +
"<
td
>" +
"<
div
><
span
><
b
>Name :</
b
></
span
> #: FullName# </
div
>" +
"<
div
>Contact Info/Comments : #: Comments# </
div
>" +
"<
div
>State : #: State# </
div
>" +
"<
div
>SRID : #: SRID# </
div
>" +
"</
td
>" +
"</
tr
>"
)
.ClientDetailTemplateId("questionTemplate")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(1)
.Model(model => model.Id(p => p.SID))
.Read(read => read.Action("GetResponses", "SUser"))
)
.Events(events => events.DataBound("dataBound"))
.Scrollable()
.Pageable(pageable => pageable
.Refresh(false)
.ButtonCount(5))
)
<
script
id
=
"questionTemplate"
type
=
"text/kendo-tmpl"
>
@(Html.Kendo().Grid<
Models.SQViewModel
>()
.Name("grid_#=State#")
.Columns(columns =>
{
columns.Bound(o => o.SortOrder);
columns.Bound(o => o.QuestionText);
})
.Pageable()
// .AutoBind(true)
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Read(read => read.Action("DetailTemplate_HierarchyBinding_Questions", "SUser", new { surveyID = "#=SID#" }))
)
.Events(events => events.DataBound("dataBound"))
.ToClientTemplate()
)
</
script
>
<
script
>
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
this.expandRow(this.tbody.find("tr.k-detail-row").first());
}
</
script
>
Greetings, I am wanting to fill a grid, with a json result, I do not use a model since this table is going to be loaded from data that its structure is not known, because it will be a general data window, I am trying to do the following but I can't show the content.
@(Html.Kendo().Grid<dynamic>()
.Name("rgvListado")
.HtmlAttributes(new {style = "height: 650px;"})
.Scrollable()
.ToolBar(t => t.Search())
.Sortable()
.Groupable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.DataSource(dataSource => dataSource
.Custom()
.Type("odata")
.Transport(transport =>
{
transport.Read(read =>
read.Url("https://demos.telerik.com/kendo-ui/service/products")
.DataType("jsonp")
);
}))
)
How do I display a content either in the DataSource property or from jquery?
How do I make the columns auto-generate?
thank you very much in advance, nice evening
I am using asp.net mvc kendo tools. I have a int property from my c# model side, see below:
public class MyModel
{
[Required]
public int MyIntField {get;set;
}
in the view side I am adding the column using Kendo Grid selector
...
.Columns(c => c.Bound(my=>my.MyIntField))
...
That field always shows with zero when an edit popup screen is called. How can I avoid that still keeping the automatic required UI validations and without messy changing the DOM directly using javascript?
I'm looking for a kendo selector solution or a c# attribute side solution. But maybe I am asking for too much.
thanks