Telerik Forums
UI for ASP.NET MVC Forum
11 answers
620 views

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!

 

Tsvetomir
Telerik team
 answered on 02 Nov 2020
1 answer
125 views

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!

Tsvetomir
Telerik team
 answered on 02 Nov 2020
3 answers
269 views

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);
 
            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;
                }
            }
 
            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.

Georgi Denchev
Telerik team
 answered on 30 Oct 2020
1 answer
293 views

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);
    })
    )
Neli
Telerik team
 answered on 30 Oct 2020
5 answers
1.7K+ views

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 !

Viktor Tachev
Telerik team
 answered on 29 Oct 2020
6 answers
257 views
 Hello All,
        I have a client detail template like this,
<script id="ItemsMoreTemplate" type="text/x-kendo-template">
<div class="form-group required">
        <div class="col-sm-2 control-label">
            @Html.LabelFor(x => x.Expire1Message)
        </div>
        <div class="col-sm-3">            
            @Html.Kendo().TextBoxFor(x => x.Expire1Message).HtmlAttributes(new { , required=true ,id = "Expire1Message_#=Id#", @class = "form-control", value = "#if(Expire1Message!=null){##=Expire1Message##}#" })
            
        </div>
    </div>
</script>

I am just expanding this template when I click the edit button (just expanding on edit event from grid) and the data are binding well. 
 I updated the post data source on Save event of kendo grid. Anyway the value is updating and getting saved.
 But my problem is the validation, original grid text boxes are validating well, but my client template text boxes are not validating, because no validation message or required attributes are added to the text box. 

Is there any way to do validate the client detail template text boxes??
Kindly advice me.
 


Chris
Top achievements
Rank 1
 answered on 29 Oct 2020
1 answer
391 views

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"))
          )

Eyup
Telerik team
 answered on 28 Oct 2020
6 answers
1.2K+ views
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>
KR
Top achievements
Rank 1
Veteran
 answered on 28 Oct 2020
4 answers
1.6K+ views

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

Ivan Danchev
Telerik team
 answered on 28 Oct 2020
1 answer
320 views

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

Martin
Telerik team
 answered on 27 Oct 2020
Narrow your results
Selected tags
Tags
+? more
Top users last month
Will
Top achievements
Rank 2
Iron
Motti
Top achievements
Rank 1
Iron
Hester
Top achievements
Rank 1
Iron
Bob
Top achievements
Rank 3
Iron
Iron
Veteran
Thomas
Top achievements
Rank 2
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Will
Top achievements
Rank 2
Iron
Motti
Top achievements
Rank 1
Iron
Hester
Top achievements
Rank 1
Iron
Bob
Top achievements
Rank 3
Iron
Iron
Veteran
Thomas
Top achievements
Rank 2
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?