Problem adding a DatePicker in a ClientRowTemplate

7 posts, 0 answers
  1. Andrew
    Andrew avatar
    5 posts
    Member since:
    Sep 2013

    Posted 24 Sep 2013 Link to this post

    Hello, fellow developers.

    I'm new to Kendo UI and I am trying to create a grid in which each row actually consists of two lines: one long description above and the detail columns below. The only way I found to achieve this was with a ClientRowTemplate. My problem is that I am unable to add Kendo's widgets when using this template. Even more: I wasn't able to even find the controls inside the template with my jQuery selectors. Here's some sample code:

    @(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
        .Name("grid")
        .HtmlAttributes(new { style = "width: 1100px;height:500px" })
        .Columns(columns =>
        {
            columns.Template(e => { }).Width(25);
            //columns.Bound(e => e.ProductName);
            columns.Bound(e => e.ProductFamily).Width(150);
            columns.Bound(e => e.ProductCode).Width(200);
            columns.Bound(e => e.Dimensions).Width(100);
            columns.Bound(e => e.Date.EditorTemplateName("DatePicker");
            columns.Bound(e => e.Unit).Width(80);
            columns.Bound(e => e.Quantity).Width(80);
            columns.Template(e => { }).Width(30);
        })
        .ClientRowTemplate(@"
        <tr class='line1'>
            <td style='font-size:larger'><div class='favorite'>*</div></td>
            <td colspan=13>#: ProductName #</td>
        </tr>
        <tr class='line2'>
            <td />
            <td class='details'>
                <span class='description'>#: ProductFamily #</span>
            </td>
            <td class='details'>
                <span>#: ProductCode #</span>
            </td>
            <td class='details'>
                <span>#: Dimensions #</span>
            </td>
            <td class='details'>
                <div class='dateControl'></div>
                <input type='text' class='datepicker' />
            </td>
            <td class='details'>
                <select>
                    <option label='Mts' value='1' />
                    <option label='Kgs' value='2' />
                    <option label='Lts' value='3' />
                </select>
            </td>
            <td class='details'>
                <input type='text' size='1'/>
            </td>
            <td class='details'>
                <a href='javascript:void();' style='text-decoration:none'>
                    <div>+</div>
                </a>
            </td>
       </tr>"
       )
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("RowTemplate_Read", "Grid"))
            .Update(update => update.Action("RowTemplate_Update", "Grid"))
        )       
        .Scrollable()
    )
     
    @section HeadContent {
          <style>          
            .title {
                display: block;
                font-size: 1.6em;
            }
            .description {
                display: block;
                padding-top: 1.6em;
            }
            .line1 {
                border-top:thick !important;
                border-top-style:solid !important;
                border-top-color:red !important;
                border-bottom:none !important;
                margin-top:10px !important;
                background: linear-gradient(to bottom, rgba(0,0,0,0.05), rgba(0,0,0,0.10));
            }
            .line2 {
                grid-row:start !important;
                border-top:none !important;
                border-bottom:thick !important;
                margin-bottom:10px !important;
                background: linear-gradient(to bottom, rgba(0,0,0,0.10), rgba(0,0,0,0.15) 99% , rgba(0,0,0,0.8) 100%);
            }
        </style>
    }
     
        <script id="dateTemplate" type="text/x-kendo-template">
            @(Html.Kendo().DatePicker().Name("dpDate").ToClientTemplate())
        </script>
        <script>
            $(function () {
                $(".datepicker").datepicker();
            });
     
            $(document).ready(function () {
                var tpl = kendo.template($("#dateTemplate").html());
                $(".dateControl").html(tpl({}));
            });
        </script>
    A few comments about the code, what I need and what I tried:

    • The first line of the row has the product name and the second line its details. I had to remove the "product name" column from the Columns method in order to obtain my desired layout. It would be great if there is a way of including that column in the header, but this would mean there should be two column lines there, and I don't know if that's possible. This is a quick mockup I made with Excel so you get the picture. <datePicker> is of course where I want the widget to be.
    • I tried using an EditorTemplate in "e.Date.EditorTemplateName("DatePicker")" without luck either. Does this work if I use the ClientRowTemplate? Even if I remove the template call, this editor doesn't work. Just in case, this is the code I have in DatePicker.cshtml:
    @model  Kendo.Mvc.Examples.Models.ProductViewModel
     
    @(Html.Kendo().DatePicker()
                    .Name("Date")
                    .Value(Model == null ? DateTime.Now : Model.Date)
                    .Format("d/M/yyyy")
    )

    • I tried adding the DatePicker by selecting the class "dateControl" and using the "dateTemplate" at the bottom, as I found in some example, but it didn't work.
    • I also tried creating a standard jQuery date picker in the "datepicker" input, but it only works outside the grid, not in the template. This is why I noticed my jQuery selectors were not working.
    • The first column will have a star image and it will be used to tag/untag the product as favorite, so it will need some jQuery attached.
    • The plus sign in the last column adds the product to the shopping cart, so it will need some jQuery attached as well.
    • Regarding the style, I also tried setting the borders in order to make both lines look as one, but it seems my styles are getting overridden by Kendo's CSS, I guess. The way I was able to do it was by playing with the background gradients in classes line1 and line2, which doesn't look like the best option, but I was too worried about the calendar to try to optimize this.
    I hope it is not too much to ask two more questions:
    • Could I do this using the server "RowTemplate" method instead? Yet again, I tried but couldn't do it.
    • For the sake of tidiness, can I place the template in a tag like <script id="rowTemplate" type="text/x-kendo-tmpl"> and then reference it from the ClientRowTemplate line?
    I'm using current Kendo UI version 2013.2.918, MVC version with Razor in Visual Studio 2012.
    Windows 7 Professional and IE10 (sorry, my client uses this!).

    Really thanks a lot for reading my whole post. I've spent countless hours trying to do all this without much success.

    Andrew
  2. Andrew
    Andrew avatar
    5 posts
    Member since:
    Sep 2013

    Posted 26 Sep 2013 Link to this post

    I managed to avoid using ClientRowTemplate, so I think it can be done. This is what I did to create the doble row and I also found how to add another row in the column headers:

    Here is the double row template:
    .Columns(columns =>
    {
        columns.Template(e => { }).Width(25).ClientTemplate("<a href='javascript:void(0);' style='text-decoration:none'><img ID='favorite#: ProductId #' src=" + @Url.Content("~/Content/StarFav.png") + " border='0' /></a><td colspan='8' class='#= toggleStyle() #'>#: ProductName #</td></tr><tr class='#= toggleStyle(true) #'><td>").HtmlAttributes(new { @class = "#= toggleStyle() #" });
        ...
    I had to use that toggleStyle function in order to properly color even and odd rows. It has a dummy clickable favorite star, you can ignore that.

    Then I also used these styles to override Kendo's and for the first column header line:
    .k-header {
        border-left-style: none;
    }
     
    .pre-header {
        background-image: none;
        background-color: rgb(246, 246, 246);
    }
     
    .k-grid td {
        border-left-style: none;
    }

    And these are the Javascript functions to add the first line in the column headers and to toggle the row style:
    var styleId = 0;
     
    $(document).ready(function () {
        var list = $("#grid");
        list.find("thead").first().prepend("<tr class='pre-header'><th /><th class='k-header pre-header' scope='col' colspan='7'>Product Name</th><th class='pre-header' /></tr>");
     
    });
     
    function toggleStyle(toggle) {
        var classString;
     
        if (styleId == 1)
            classString = "k-alt";
        else
            classString = "";
     
        if (toggle) {
            styleId = 1 - styleId ;
        }
     
        return classString;
    }

    Anyway, things have changed and now I've been told that we have to create our own table (styling must be very precise) only adding the specific controls where necessary, so it seems I won't continue working with this grid... I hope these ideas help somebody at some point in the future. :)

    Thanks and regards,

    Andrew
  3. Andrew
    Andrew avatar
    5 posts
    Member since:
    Sep 2013

    Posted 02 Oct 2013 Link to this post

    Despite the fact that I don't need to solve this anymore, I think it would be great if a solution to the original request is posted in this thread. It might be useful for somebody else in the future. :)

    Thanks and regards,

    Andrew
  4. Andrew
    Andrew avatar
    5 posts
    Member since:
    Sep 2013

    Posted 16 Oct 2013 Link to this post

    Ok, my trial is about to expire and still I haven't received one response. So I guess this just can't be done. :(
  5. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 18 Oct 2013 Link to this post

    Hi Andres,

     The problem with your original implementation was that the datepicker elements were not initialized when you called $(".datepicker").datepicker();. The grid binds asynchronously and you need to use its DataBound event to initialize any widgets inside the template. Here is a live demo which shows how this can be done: http://jsbin.com/IpiKiYo/1/edit

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Andrew
    Andrew avatar
    5 posts
    Member since:
    Sep 2013

    Posted 18 Oct 2013 Link to this post

    Thanks a lot, Atanas.

    Another question: is it ok to select by class instead of by ID? I have noticed that when I instantiate a Kendo widget by class, my div turns into several spans, and the class is then assigned to at least two of them, so afterwards I can't use the same selector to interact with the widget (not both spans are the "real" widget).
    For example:
    $(".datePicker").data("kendoDatePicker").value()
    This will fail when it comes the turn of the "wrong" span.
  7. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 21 Oct 2013 Link to this post

    Hi Andres,

     $(".datePicker").data("kendoDatePicker").value() will return the value of the first datepicker of all. The $(".datePicker") selector will find all datepickers but then .data("kendoDatePicker") will get only the first instance. You need to find a way to differentiate between datepickers. For example you can use .eq() to get a specific datepicker e.g.:

    $(".datePicker").eq(1).data("kendoDatePicker").value() will get you the second datepicker (with index 1).

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Back to Top