This is a migrated thread and some comments may be shown as answers.

ASP.Net Core Razor Grid Selecting a row using a templated link

5 Answers 1422 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Giles
Top achievements
Rank 1
Giles asked on 11 Mar 2019, 10:48 AM

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 !

5 Answers, 1 is accepted

Sort by
0
Tsvetomir
Telerik team
answered on 13 Mar 2019, 10:47 AM
Hi Christopher,

Thanks for sharing your findings and approach with our community.

The reason why the row was not selected when the user clicks on the link is that it consumes the click event. It does not propagate to the row, hence, it does not get selected. There are different approaches on how to select the row, here are a few:

function SelectRow(e) {
    var grid = $("#grid").data("kendoGrid");
    var row = e.closest("tr"); // target the row on which the link was clicked
  
    // option 1
    grid.select(row); 
     
    // option 2:
    row.click();
 
    // option 3:
    $(row).addClass("k-state-selected");
  
    // obtain the data item
    var dataItem = grid.dataItem(row);
     
}


The first approach uses the Kendo UI Grid API to select the row. When a row is selected a "k-state-selected" class is added to the row so you can add it programmatically. And the last approach is to trigger the click event of the row which will select it. 

And the data item can be obtained via the API as well, simply pass the reference of the row element to the dataItem() method

With that said, in the provided code you are sending a jQuery ajax request when the custom button is clicked. Is there a functionality other that selecting the row you have in mind?


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Giles
Top achievements
Rank 1
answered on 14 Mar 2019, 08:58 AM

Hi Tsvetomir

Thanks for the response, some of your options are cleaner I agree, my problem was, I believe, assuming that the link object 'e' would be passed automatically into the script as it is in the pre-defined command objects.

There was some processing being undertaken in the Razor page code behind hence the Ajax call.Having got it to work I have now modified the Ajax call to re-direct on success.

My overall problem was the sparsity of documentation surrounding processing in Asp.Net core when using a templated custom command (the example in the documentation represents very basic usage)

Regards

0
Tsvetomir
Telerik team
answered on 15 Mar 2019, 03:00 PM
Hi Christopher,

It is correct that the row is obtained based on the passed reference to of the template button. Therefore, I have used the exact same grid declaration as the one that you have provided in the very beginning of the communication. 

As per the documentation, we are have streamed our effort into a direction of improving the documentation both for the ASP.NET MVC and ASP.NET Core wrappers. Major enhacements will be observed in the foreseeable future. 


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Danny
Top achievements
Rank 1
Iron
Veteran
Iron
answered on 28 Oct 2020, 01:40 AM

hello Tsvetomir's

I use a dataTable to load the data, com model in dynamic:

@(Html.Kendo().Grid<dynamic>()
          .Name("rgvListado")
          //.HtmlAttributes(new { style = "height: 600px;" })
          .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 =>
            {
              model.Id("Codigo");
              foreach (System.Data.DataColumn column in Model.Columns)
              {
                var field = model.Field(column.ColumnName, column.DataType);
              }
            })
            .Read(read => read.Action("ReadTable", "General"))
            .ServerOperation(false)
          )
          .Scrollable(s => s.Height("550px"))
          .Events(events => events
            .Change("onChangeBuscar"))
          )

 

js:

function onChangeBuscar(arg) {
  var selected = $.map(this.select(), function (item) {
    return $(item).text();
  });
  alert(selected);
}

This works, it shows me what is selected, but it shows me a single text, joining the columns that are displayed in the grid, without any separator and thus exhausting the possibilities of converting to an array, as I obtain the values of the columns separately.

thank you very much.

 

0
Viktor Tachev
Telerik team
answered on 29 Oct 2020, 04:12 PM

Hi Danny,

 

The grid select() method will return the table row element that is selected. Thus the text() method is called for the tr element and not the individual cells in it. This is why the content is returned without delimiters. If you would like to merge the values from the selected Grid row I suggest modifying the change handler like this:

 

function onChangeBuscar(arg) {
	var selected = $.map(this.select().find("td"), function (item) {
		return $(item).text();
	});
		
	alert(selected);
}

 

Regards,
Viktor Tachev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Grid
Asked by
Giles
Top achievements
Rank 1
Answers by
Tsvetomir
Telerik team
Giles
Top achievements
Rank 1
Danny
Top achievements
Rank 1
Iron
Veteran
Iron
Viktor Tachev
Telerik team
Share this question
or