0

This is probably an easy question for a CSS (or maybe a KoGrid) expert (which I am neither). The setting is a web page using Knockout and JQuery with one-to-many KoGrids. Only one is grid is "display:block" at a time. All the others are "display:hidden".

When a user resizes their browser window, the hidden grids get the widths of their kgTopPanel, kgViewport, and kgFooterPanel areas set to "0". Afterwards, when the user clicks a link to activate a previously hidden grid, it will not restore the widths and they must resize the browser window again to see things. After many long hours I figured out the hack below as a way to get around it but it is ugly.

Is there an elegant way to fix this without the hack? Can I prevent those widths from getting set to zero in the first place? I am not a CSS expert and I exhausted my knowledge long ago. I took a whole day searching the web, trying bunches of things, and ultimately found no answers.

In the code snippet below, "domPanel" is a div that contains ALL the grids. "domObject" is the one grid I want to switch on.

<div id='Grid1' data-bind="koGrid: g1.GridOptions"></div>
<div id='Grid2' data-bind="koGrid: g2.GridOptions"></div>
...
domTabPanel.children().css('display', 'none');
domObject.css('display', 'block');
// Hack to restore the widths.  If you resize the page
// when another tab is visible, all the widths will have been set to 0.
domObject.find(".kgTopPanel").css("width", "inherit");
domObject.find(".kgTopPanel").children().css("width", "inherit");
domObject.find(".kgViewport").css("width", "inherit");
domObject.find(".kgViewport").children().css("width", "inherit");
domObject.find(".kgFooterPanel").css("width", "inherit");
domObject.find(".kgFooterPanel").children().css("width", "inherit");

PS: The problem appears under both IE and Chrome so I assume all browsers are probably affected.

K Kimble
  • 249
  • 3
  • 8

1 Answers1

1

When an element receives display: none, retrieving it's size in JavaScript will result in zero width and height. There's probably some code (in koGrid) that is reading the width and height and doing something with it programmatically. However, the relevant code is not present in your post so it's hard to be more specific.

A possible fix would be to not use display: none, but to 'hide' the invisible grids by giving them an absolute position and offsetting them very far from the page. Do this by giving them a class that is styled somewhat like this:

.my-invisible-class {
    position: absolute;
    left: -9999px;
}

This way, they are hidden from view but in reality still intact. Their width and heights should remain stable.

Hans Roerdinkholder
  • 3,000
  • 1
  • 20
  • 30
  • I'll try it. It seems a little weird to me shoving it way off like that but I saw someone do it once in a menu system so it must be a pretty solid way of doing it. Thanks, I will let you know how that works. – K Kimble Nov 13 '13 at 12:36
  • That did solve the problem. Are there any gotchas to doing that? – K Kimble Nov 13 '13 at 12:55
  • I'm not entirely sure to be honest. One thing I can think of, is that the element is still considered to be in the DOM and can trigger a reflow, so performance-wise it's probably not as good as `display: none`. An alternative is to set the css property visibility, as such: `visibility: hidden` or `visibility: visible`. This keeps the element in the dom, sizes intact, just invisible. I don't think it will match your use case, because the element will still take up space. Maybe a combination of `visibility: hidden` and `position: absolute`? – Hans Roerdinkholder Nov 13 '13 at 13:27