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.