Grid not showing data in template window if another grid was selected first

8 posts, 1 answers
  1. Dwayne
    Dwayne avatar
    2 posts
    Member since:
    Jul 2013

    Posted 09 Dec 2013 Link to this post

    Greetings,

    First, I'll start with the layout...  I'm using nested controls and windows on a form inside of MVC 4 partials.  The page the issue resides on is actually a partial inside of a panelbar->tabstrip.  That partial has a nesting hierarchy that goes like this: 
        PanelBar
                       Grid
                              Child Template
                                                        3 Grids with custom (Template) button in the toolbar

    The "3 Grids with custom button" level is where I see the issue.  Each Grid's button loads a kendo window with a partial view.  Each partial view contains two grids (association pair).

    Yes, I know, "complicated", but this is what I needed.

    When I first click on a grid's custom "associate button", the window pops up and the grids load / initialize correctly.  The problem occurs if I click on a different grid's button.  The window pops up, the partial loads, I see the read request and response in Fiddler, but the grids don't populate visually.  If I go back to the initial grid's button and click it, the correct result is presented.   Now, I can refresh the page and click the second grid button and it will show, but the first grid has the problem... Basically, its whomever came first wins.  I have to refresh the page in order to bring up a different window.   I've checked the Ids and Names to make sure I didn't have any weird duplicates and I don't. 

    Template Script: (3 grids)

    <script id="template" type="text/kendo-tmpl">
            <h3>Servers</h3>
            @(Html.Kendo().Grid<Company.Web.AMDB.Models.ServerViewModel>
        ()
        .Name("ServerGrid_#=Id#")
        .Columns(columns =>
        {
            columns.Bound(serv => serv.Name).Width(150);
            columns.Bound(serv => serv.Description);
            columns.Bound(serv => serv.OS).Width(150);
            columns.Bound(serv => serv.Version).Width(150);
        })
     
        .ToolBar(toolbar =>
        {
            toolbar.Template(@<text>
            <div class="toolbar">
                <button class="k-button" id="cmdUpdateServers_#=Id#" title="Update Related Servers" onclick="prepDnsServerWindow('#=Id#', @Model.Id)"><span class="k-icon k-edit"></span>Update Related Servers</button>
            </div></text>);
        })
        .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model =>
        {
            model.Id(a => a.Id);
        })
                .Read(read => read.Action("ReadDNSServers", "DNS", new { dnsId = "#=Id#" }))
        )               
        .Pageable()
        .Sortable()
        .ToClientTemplate()
            )
            <hr />
     
            <h3>Permissions</h3>
            @(Html.Kendo().Grid<Company.Web.AMDB.Models.PermissionViewModel>
        ()
        .Name("PermissionGrid_#=Id#")
        .Columns(columns =>
        {
            columns.Bound(p => p.Description).Width(150);
            columns.ForeignKey(
                    a => a.AccessTypeId,
                    (System.Collections.IEnumerable)ViewData["accessTypes"],
                    "Id", "Name").Title("Access Type").Width(125);
            columns.ForeignKey(
                   a => a.AuthAccountId,
                   (System.Collections.IEnumerable)ViewData["authAccounts"],
                   "Id", "Name").Title("Auth Account").Width(125);
        })
     
        .ToolBar(toolbar =>
        {
            toolbar.Template(@<text>
                <div class="toolbar">
                    <button class="k-button" id="cmdUpdatePermissions_#=Id#" title="Update Related Permissions" onclick="prepDnsPermissionWindow('#=Id#', @Model.Id)"><span class="k-icon k-edit"></span>Update Related Permissions</button>
                </div></text>);
        })
        .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model =>
        {
            model.Id(a => a.Id);
        })
                .Read(read => read.Action("ReadDNSPermissions", "DNS", new { dnsId = "#=Id#" }))
        )
        .Pageable()
        .Sortable()
        .ToClientTemplate()
        )
     
        <hr />
     
        <h3>Dependencies</h3>
        @(Html.Kendo().Grid<Company.Web.AMDB.Models.DependencyViewModel>
        ()
        .Name("DependencyGrid_#=Id#")
        .Columns(columns =>
        {
            columns.Bound(d => d.Name).Width(200);
            columns.Bound(d => d.Description);
            columns.Bound(d => d.Version).Width(200);
        })
     
        .ToolBar(toolbar =>
        {
            toolbar.Template(@<text>
                <div class="toolbar">
                    <button class="k-button" id="cmdUpdateDependencies_#=Id#" title="Update Related Dependencies" onclick="prepDnsDependencyWindow('#=Id#', @Model.Id)"><span class="k-icon k-edit"></span>Update Related Dependencies</button>
                </div></text>);
        })
        .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model =>
        {
            model.Id(a => a.Id);
        })
                .Read(read => read.Action("ReadDNSDependencies", "DNS", new { dnsId = "#=Id#" }))
     
        )
        .Pageable()
        .Sortable()
        .ToClientTemplate()
        )
     
    </script>

    The kendoWindow divs:

    <div id="dnsServerWindow"></div>
    <div id="dnsPermissionWindow"></div>
    <div id="dnsDependencyWindow"></div>

    The script to get the partials for the windows:

    <script>
     var dnsServerWindow;
     var dnsPermissionWindow;
     var dnsDependencyWindow;
     
     function onServerWindowClose(id) {
     //alert("closed: " + id);
     $("#ServerGrid_" + id).data("kendoGrid").datasource.read();
     }
     
     function prepDnsServerWindow(id, envId) {
     if (!dnsServerWindow.data("kendoWindow")) {
     dnsServerWindow.kendoWindow({
     width: 1100,
     height: 600,
     visible: false,
     //close: onServerWindowClose(id)
     });
     }
     
     dnsServerWindow.kendoWindow({
     content: {
     url: "/DNS/GetServerPartial",
     data: { environmentId: envId, dnsId: id }
     },
     modal: true
     
     });
     
     dnsServerWindow.data("kendoWindow")
     .title("Edit Server Association");
     
    dnsServerWindow.data("kendoWindow").center().open();
     
     return true;
     }
     
     function prepDnsDependencyWindow(id, envId) {
     if (!dnsDependencyWindow.data("kendoWindow")) {
     dnsDependencyWindow.kendoWindow({
     width: 1100,
     height: 600,
     visible: false,
     //close: onServerWindowClose(id)
     });
     }
     
     dnsDependencyWindow.kendoWindow({
     content: {
     url: "/DNS/GetDependencyPartial",
     data: { dnsId: id, environmentId: envId }
     },
     modal: true
     
     });
     
     dnsDependencyWindow.data("kendoWindow")
     .title("Edit Dependency Association");
     
     dnsDependencyWindow.data("kendoWindow").center().open();
     
     return true;
     }
     
    function prepDnsPermissionWindow(id, envId) {
     if (!dnsPermissionWindow.data("kendoWindow")) {
     dnsPermissionWindow.kendoWindow({
    width: 1200,
     height: 600,
     visible: false,
     //close: onServerWindowClose(id)
     });
     }
     
     dnsPermissionWindow.kendoWindow({
     content: {
     url: "/DNS/GetPermissionPartial",
     data: { permDnsId: id, permEnvironmentId: envId }
     },
     modal: true
     
     });
     
     dnsPermissionWindow.data("kendoWindow")
     .title("Edit Permission Association");
     
     
     
     dnsPermissionWindow.data("kendoWindow").center().open();
     
     
     return true;
     }
     $(document).ready(function () {
     var foo = $("#environmentPanelbar_@Model.Id").kendoPanelBar({ expandMode: "single" }).data("kendoPanelBar"); // - before data - .css({ marginRight: "220px" })
     
     //if (foo)
     // foo.destroy();
     dnsServerWindow = $("#dnsServerWindow");
     dnsPermissionWindow = $("#dnsPermissionWindow");
     dnsDependencyWindow = $("#dnsDependencyWindow");
     
     //$("[name^=DNSGrid_]").find(".k-grid-content").height(535);
     //$("[name^=DNSGrid_]").data("kendoGrid").refresh();
     })
     </script>



    Example Partial

    (all three are very similar, but all the names of elements/functions were changed to  reflect the particular window.  "server","permission","dependency")

    <h2>@Model.Name Server Association</h2>
     
     <script>
     
     function addServer(e) {
     var foo = this.select();
     var dataItem = this.dataItem(foo[0]);
     //debugger;
     
     var dnsDataSource = $("#AssociatedGrid").data('kendoGrid').dataSource;
     //dataSource.add({Name:"foo", OS:"Bar"});
     dnsDataSource.add(dataItem);
     
    var availDataSource = $("#AvailableGrid").data('kendoGrid').dataSource;
     availDataSource.remove(dataItem);
     
     $.post("../../DNS/AddServer", { dnsId:@Model.Id, environmentId:@Model.EnvironmentId, serverId:dataItem.Id})
     .done(function(data){
     window.parent.$("#ServerGrid_@Model.Id").data("kendoGrid").dataSource.read();
     });
     
    return true;
     }
     
     function removeServer() {
     var foo = this.select();
     var dataItem = this.dataItem(foo[0]);
     //debugger;
     
     var dnsDataSource = $("#AssociatedGrid").data('kendoGrid').dataSource;
     //dataSource.add({Name:"foo", OS:"Bar"});
     dnsDataSource.remove(dataItem);
     
     var availDataSource = $("#AvailableGrid").data('kendoGrid').dataSource;
     availDataSource.add(dataItem);
     
     $.post("../../DNS/RemoveServer", { dnsId:@Model.Id, serverId:dataItem.Id})
     .done(function(data){
     window.parent.$("#ServerGrid_@Model.Id").data("kendoGrid").dataSource.read();
     });
     
     return true;
     }
     </script>
     
     <table>
     <tr>
     <td><h3>Available Servers</h3></td>
     <td></td>
     <td><h3>Associated Servers</h3></td>
     </tr>
     <tr>
     <td>
     @(Html.Kendo().Grid<Company.Web.AMDB.Models.ServerViewModel>()
     .Name("AvailableGrid")
     .Columns(columns =>
     {
     columns.Bound(s => s.Name).Width(150);
     columns.Bound(s => s.OS);
     columns.Bound(s => s.Version);
     columns.Command(command => command.Custom("Add").HtmlAttributes(new { @class = "k-i-arrow-e" }).Click("addServer")).Width(80);
     })
     .Sortable()
     .Pageable()
     .Selectable()
     .Scrollable()
     .Filterable()
     .HtmlAttributes(new { style = "height:425px;" })
     .DataSource(dataSource => dataSource
     .Ajax()
     .Read(read => read.Action("GetAvailableServers", "DNS", new { dnsId = Model.Id }))
     )
     
     )
     </td>
     <td> </td>
     <td>
     @(Html.Kendo().Grid<Company.Web.AMDB.Models.ServerViewModel>()
     .Name("AssociatedGrid")
     .Columns(columns =>
     {
     columns.Bound(s => s.Name).Width(150);
     columns.Bound(s => s.OS);
     columns.Bound(s => s.Version);
     columns.Command(command => command.Custom("Remove").HtmlAttributes(new { @class = "k-i-arrow-w" }).Click("removeServer")).Width(80);
     })
     .Sortable()
     .Pageable()
     .Selectable()
     .Scrollable()
     .Filterable()
     .HtmlAttributes(new { style = "height:425px;" })
     .DataSource(dataSource => dataSource
     .Ajax()
     .Read(read => read.Action("ReadDNSServers", "DNS", new { dnsId = Model.Id }))
     )
     
     )
     </td>
     </tr>
     </table>



    Thanks in advance for the help on this.... I've been fighting it for a couple of days.

    Bonus question... when setting the height of a Grid via style, why does the data in the grid step outside the bounds?  Meaning, the grid contents extend further than the containing div.

  2. Daniel
    Admin
    Daniel avatar
    2214 posts

    Posted 12 Dec 2013 Link to this post

    Hello,

    If all Grids have different names then the problem could be caused by initializing the window multiple times. You should use the refresh method to reload the content from a different URL or with different query string parameters instead of initializing the window again  e.g.
    function prepDnsPermissionWindow(id, envId) {
        if (!dnsPermissionWindow.data("kendoWindow")) {
            dnsPermissionWindow.kendoWindow({
                width: 1200,
                height: 600,
                visible: false,
                modal: true           
            });
        }
     
        var wnd = dnsPermissionWindow.data("kendoWindow");
        wnd.refresh({
            url: "/DNS/GetPermissionPartial",
            data: {
                permDnsId: id,
                permEnvironmentId: envId
            }
        });
     
        wnd.title("Edit Permission Association");
        wnd.center().open();
     
        return true;
    }
    As for your question about the Grid height - you should also enable scrolling when setting the height. Otherwise, the table will expand to fit its content and could extend further than the wrapper.


    Regards,
    Daniel
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Dwayne
    Dwayne avatar
    2 posts
    Member since:
    Jul 2013

    Posted 12 Dec 2013 Link to this post

    Daniel,

    Thank you for your response.   Unfortunately, when I use the refresh method, the result is the same.   I matched your example below:
    function prepDnsDependencyWindow(id, envId) {
     
            if (!dnsDependencyWindow.data("kendoWindow")) {
                dnsDependencyWindow.kendoWindow({
                    width: 1100,
                    height: 600,
                    visible: false,
                    modal: true
                });
            }
     
            var wnd = dnsDependencyWindow.data("kendoWindow");
     
            wnd.refresh({           
                url: "/DNS/GetDependencyPartial",
                data: {
                    dnsId: id,
                    environmentId: envId
                }           
            });
             
            wnd.title("Edit Dependency Association");
            wnd.center().open();
     
            return true;
        }

    Also, each window is a different instance.   I've reused windows on a different page, and that has worked before, but for this scenario, each window I'm trying to view is different.:
    $(document).ready(function () {
            var foo = $("#environmentPanelbar_@Model.Id").kendoPanelBar({ expandMode: "single" }).data("kendoPanelBar");       
             
            dnsServerWindow = $("#dnsServerWindow");
            dnsPermissionWindow = $("#dnsPermissionWindow");
            dnsDependencyWindow = $("#dnsDependencyWindow");
        })
    (the window variables are defined outside the ready block)


    Also, as far as the grid expanding past the div bounds, I do have scrollable set:
    <li>
            Farms / DNS
            <div>
                @{Html.Kendo().Grid<Company.Web.AMDB.Models.DNSViewModel>()
                    .Name("DNSGrid_"+ @Model.Id)
                    .Columns(columns =>
                    {
                        columns.Bound(f => f.Name);
                        columns.Bound(f => f.Description).Width(300);
                        columns.Bound(f => f.PoolName);
                        columns.Bound(f => f.HostName);
     
                        columns.Command(command => { command.Edit(); command.Destroy(); }).Width(170);
                    })
                    .ToolBar(toolbar => toolbar.Create().Text("Add New Farm / DNS"))
                    .Editable(editable => editable.Mode(GridEditMode.InLine))
                    .Sortable()
                    .Pageable()
                    .Scrollable()
                    .Filterable()
                    .ClientDetailTemplateId("template")
                    .HtmlAttributes(new { style = "height:600px;" })
                    .ColumnMenu()
     
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .Model(model =>
                        {
                            model.Id(a => a.Id);
                        })
                        .Read(read => read.Action("ReadEnvironmentDNS", "DNS", new { environmentId = Model.Id }))
                     .Create(create => create.Action("CreateDNS", "DNS", new { envId = Model.Id }))
                     .Update(update => update.Action("UpdateDNS", "DNS"))
                     .Destroy(delete => delete.Action("DestroyDNS", "DNS"))
                    )
                    .Render();
                }
    </div>
        </li>
    I've attached a screenshot so you can see what its doing.

    Thank you for your help.




  4. Daniel
    Admin
    Daniel avatar
    2214 posts

    Posted 16 Dec 2013 Link to this post

    Hi again,

    I am not sure what else could be causing the problem. I attached a sample project which has a lot simpler setup but I believe demonstrates the same scenario - multiple Grids in a detail each with button in the toolbar that opens a separate window. Could you check it and let me know if I am missing something? If the setup is the same then could you provide a runnable sample that reproduces the problem or modify the attached project so that it replicates it?

    Regarding the problem when setting the height - it can occur when the height is set and the Grid is initialized in a hidden container because the content height cannot be calculated in this case. Please check if setting the content height with the Scrollable configuration instead:
    .Scrollable(s=>s.Height(600))
    or calling the refresh method after the container is visible(if it is in a tabstrip or panelbar in the activate event) resolves the problem.

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

    Posted 16 Dec 2013 Link to this post

    Daniel,

    Thank you very much for your response.  Setting the height value in the Scrollable property fixed the height issue I was having! 

    I have your example project running and it is similar to what I am doing, so I'm spending some time comparing the two to see what the differences are (besides mine having two grids instead of one, etc).  I'll post back with what I find.

    Thank you,
    Dwayne
  6. Dwayne
    Dwayne avatar
    2 posts
    Member since:
    Jul 2013

    Posted 17 Dec 2013 Link to this post

    Daniel,

    Thanks for the sample code.  It is very clean and easy to understand.  I tried several things with your example to try and reproduce the issue I was having to no avail.  So, I decided to take a clean look at what I was doing with the popup windows and partials and stumbled upon the issue!  

    The issue was that each partial used the same name for the grid.  Each partial view had a grid named "AvailableGrid" and "AssociatedGrid".  This naming should be ok, but I wondered if, somehow, they were stepping on each other in memory...  So, I added a type to the name  for each grid to reflect the data found in the partial it was in (eg. "AvailableServerGrid" & "AssociatedServersGrid" for the server partial,  "AvailablePermissionsGrid" etc for the permissions partial).  And the popup windows worked as expected.

    Is the issue I ran into expected?  Meaning, is there some basic UI coding premise I missed?  Or is this some bug/behavior associated with the Kendo controls?

    Thank you,

    Dwayne
  7. Answer
    Dwayne
    Dwayne avatar
    2 posts
    Member since:
    Jul 2013

    Posted 18 Dec 2013 Link to this post

    Hi Dwayne,

    The problem is expected when using different Windows to show partial views that have the Grids with same names. The HTML content of the first opened window will not be cleared and so the initialization script for the Grid in the second window will not find the correct element.

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

    Posted 18 Dec 2013 Link to this post

    Daniel,

    Thank you for the clarification and for your assistance with this! 

    May you and your family have a very Merry Christmas and a Happy New Year!

    Dwayne
Back to Top