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.