Define a custom Html.Kendo extension helper

12 posts, 1 answers
  1. Eric
    Eric avatar
    15 posts
    Member since:
    Jun 2012

    Posted 21 Jan 2013 Link to this post

    I would like to create a custom Html helper for a Kendo grid. We have a particular view-model combination which will be used across multiple controllers. I would like to be able to create a custom help method for display a grid of these models. It would basically be a short cut to use in all the views so we wouldn't have to maintain the same code in many different files. I would like to call it like this:

    @Html.Kendo().ConfigruationGrid();
    @* or *@
    @Html.ConfigurationKendoGrid();
    And have it output all the bells and whistles of a full grid declaration, like this:
    @(Html.Kendo().Grid(@Model)
        .Name("KnockoutQuestions")
        .DataSource(datasource => datasource
            .Ajax()
            .Model(model =>
                {
                    model.Id(k => k.Id);
                    model.Field(k => k.Id).Editable(false);
                    model.Field(k => k.Enabled).DefaultValue(true);
                })
            .Events(events => events.Error("Error"))
            .Create(create => create.Action("Create", "KnockOutQuestion"))
            .Read(read => read.Action("Read", "KnockOutQuestion"))
            .Update(update => update.Action("Update", "KnockOutQuestion"))
        )
        .Columns(columns => {
            columns.ForeignKey(k => k.AdminLeadType,
                new SelectList(from pair in BaseKnockOutQuestionModel.EnumLeadTypes select new { text = pair.Value, value = pair.Key },
                       "value", "text"));
            columns.ForeignKey(k => k.QuestionTypeId,
                new SelectList(from pair in BaseKnockOutQuestionModel.QuestionTypes select new { text = pair.Value, value = pair.Key },
                       "value", "text"));
            columns.Bound(k => k.QuestionText);
            columns.Bound(k => k.Answer1Text);
            columns.Bound(k => k.Answer2Text);
            columns.Bound(k => k.Price);
            columns.Bound(k => k.Enabled);
            columns.Command(command => command.Edit());
        })
        .ToolBar(toolbar => { toolbar.Create(); })
        .Editable(editable => editable.Mode(GridEditMode.PopUp))
        .Pageable()
        .Sortable()
        .Filterable()
        )
    I know how to do custom Html helper methods, but I haven't found any examples of how to do a shortcut like this. It's probably something simple like using the "this HtmlHelper helper" param to execute and return the output of the Kendo().Grid() function. I wanted to ask anyways so I could hopefully avoid common mistakes/pitfalls.
  2. Answer
    Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 23 Jan 2013 Link to this post

    Hello Eric,

    You can easily create and use a shortcut like this:

    @helper MyGridShortCut()
    {
        Html.Kendo().Grid()
            .Name("Grid")
            .Columns(columns =>
            {
                /* ...  */
            })
             /*  ...   */
            .Render();
    }
     
    @MyGridShortCut()

    If you need a custom HtmlHelper that can accept additional configuration options, then you should use the following approach:

    C# Version
    =========

    Class

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Kendo.Mvc.UI;
     
    namespace MyNamespace
    {
        public static class MyHtmlHelperExtensions
        {
            public static Kendo.Mvc.UI.Fluent.GridBuilder<T> MyGrid<T>(this HtmlHelper helper, string name)
                where T : class
            {
                return helper.Kendo().Grid<T>()
                    .Name(name)
                    .Groupable()
                    .Pageable()
                    .Sortable()
                    .Scrollable()
                    .Filterable()
                    .Pageable();
            }
        }
    }


    View

    @model IEnumerable<Kendo.Mvc.Examples.Models.ProductViewModel>
    @using MyNamespace
     
    @(Html.MyGrid<Kendo.Mvc.Examples.Models.ProductViewModel>("Grid1")
        .BindTo(Model)
        .Columns(columns =>
        {
            columns.Bound(p => p.ProductID).Groupable(false);
            columns.Bound(p => p.ProductName);
            columns.Bound(p => p.UnitPrice);
            columns.Bound(p => p.UnitsInStock);
        })
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("Products_Read", "Grid"))
        )
    )


    VB version
    =========

    web.config

    <add namespace="Kendo.Mvc.UI" />
    <add namespace="MyProject.MyHtmlHelpers" />


    Class

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Web
    Imports System.Web.Mvc
    Imports Kendo.Mvc.UI
     
    Imports System.Runtime.CompilerServices
     
    Namespace MyHtmlHelpers
     
        Public Module HtmlHelperExtensions
     
            <Extension()> _
            Public Function MyGrid(Of T As Class)(
                ByVal helper As HtmlHelper, _
                ByVal name As String) As Kendo.Mvc.UI.Fluent.GridBuilder(Of T)
     
                Return helper.Kendo().Grid(Of T)().Name(name).Groupable().Pageable().Sortable().Scrollable().Filterable()
     
            End Function
     
        End Module
     
    End Namespace

    View

    @Code
    Html.MyGrid(Of KendoUIMvcVB.Person)("Grid1") _
        .Columns(Sub(c)
                         c.Bound(Function(p) p.PersonID)
                         c.Bound(Function(p) p.PersonName)
                         c.Bound(Function(p) p.PersonBirthDate)
                         c.Template(Sub()
                                    @<text>server template</text>
                                    End Sub).Title("Template column").ClientTemplate("client template")
                 End Sub) _
        .DataSource(Function(d)
                            d.Ajax().Read(Function(read) read.Action("Person_Read", "Home"))
                    End Function) _
    .Render()
    End Code



    Regards,
    Dimo
    the Telerik team
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Eric
    Eric avatar
    15 posts
    Member since:
    Jun 2012

    Posted 23 Jan 2013 Link to this post

    This was easier than I anticipated. You just make a regular helper method signature and return the regular Kendo HtmlHelper extension method. Like this:

    public static IHtmlString CustomKendoGrid(this HtmlHelper htmlHelper,
        IEnumerable<Model> models,
        String gridName,
        String otherOptions
    )
    {
        return htmlHelper.Kendo().Grid(properties)
                    .Name(gridName)
                    // more options here
                    ;
    }
    Then you invoke it like a normal html helper method
    @(Html.ConfigurationKendoGrid(
                         (IEnumerable<ConfigPropertyModel>)ViewData["reportBack"],
                         "ReportBack",
                         "LccConfig"))
    And viola!
  5. Eric
    Eric avatar
    15 posts
    Member since:
    Jun 2012

    Posted 23 Jan 2013 Link to this post

    I can't believe I double posted with Dimo... I will try out the options splitting capability you provided. I can anticipate at least one situation where that would be very useful.

    Thanks!
  6. menaheme
    menaheme avatar
    8 posts
    Member since:
    Jul 2011

    Posted 29 Jan 2014 in reply to Dimo Link to this post

    Hi Dimo,

    I found this post very helpful, though i have a question:
    how do i pass an array of buttons to be rendered in the grid`s toolbar? 

    when i use the regular fluent html helper directly in the view it`s simple, but i cant get it to work in the grid Html helper that you show here.

    Thanks,
    Menahem
  7. Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 31 Jan 2014 Link to this post

    Hi Menahem,

    The Toolbar() configuration syntax should be the same in the regular Kendo UI Grid and your custom Helper. What exactly seems to be the problem? Can you show your code?

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  8. menaheme
    menaheme avatar
    8 posts
    Member since:
    Jul 2011

    Posted 02 Feb 2014 in reply to Dimo Link to this post

    Hi Dimo,
    i used the overload that takes 'Action' , and no buttons got rendered. 
    now im using the overload that takes string, and do something like this
    StringBuilder.Append(helper.xxx.ToHtmlString())
    to build the output.
    this works, but i would like to not use this method.

    my code that didnt work look something like:
    ...Template.( () => { helper.ButtonHelper.RenderButton(operation); } 
    •  in Telerik`s samples of toolbar templates in razor views there`s always a @<text> tag there, and i get the feeling this is the missing link for me.

      Thanks,
      Menahem


  9. Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 03 Feb 2014 Link to this post

    Hi Menahem,

    You don't need a template to add multiple buttons to the Grid toolbar. You can use the syntax, which is demonstrated in our demos, e.g.

    http://demos.telerik.com/kendo-ui/web/grid/editing.html

    Custom buttons require you to attach an event handler to make them work:

    .ToolBar(toolBar =>
        {
            toolBar.Create();
            toolBar.Save();
            toolBar.Custom().Name("myname").Text("mytext");
        })


    $(".k-grid-myname").click(function(e){
       // do someting...
    });


    When using templates, you see several overloads in Visual Studio:

    + string - can be used in both the Razor and WebForms view engines
    + Action - () => { ... } - can be used in WebForms only
    + Func - @<text>...</text> - can be used in Razor only

    I hope this makes things clear.

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  10. menaheme
    menaheme avatar
    8 posts
    Member since:
    Jul 2011

    Posted 03 Feb 2014 in reply to Dimo Link to this post

    Hi Dimo,

    your answer really cleares things up for me , thank you.

    in my case i am also rendering other kendo ui widgets to the toolbar , like kendo buttons , dropdowns and so on.

    is there another way to do that other than a template ?
    Menahem
  11. Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 03 Feb 2014 Link to this post

    Hello Menahem,

    No, there isn't. A template is the most flexible way, which allows you to insert any content.

    http://docs.telerik.com/kendo-ui/getting-started/using-kendo-with/aspnet-mvc/fundamentals#client-templates

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  12. Shoeb
    Shoeb   avatar
    7 posts
    Member since:
    Feb 2015

    Posted 09 Aug in reply to Dimo Link to this post

    Can you please help me for below question.

    How to create custom strongly typed html helper method for kendo DatePicker?

    Thanks,

    Shoeb.

     

  13. Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 10 Aug Link to this post

    Hello Shoeb,

    Please check the second code snippet in the second post in this thread:

    http://www.telerik.com/forums/define-a-custom-html-kendo-extension-helper#XL7GVFpsXU2CcCIxxKHNBg

    Regards,
    Dimo
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready