SlickGrid
SlickGrid copied to clipboard
When the grid is hidden and redisplayed, the grid style does not appear properly
I found a problem. At the beginning, the grid was hidden. After displaying the grid through jquery show, the grid style was abnormal, the position of the left panel was offset, and the scroll bar was also abnormal.Here is a screenshot of my question:
90% of the time, when this happens it's a custom style you've applied. I'd recommend starting with one of the example pages and trying to reproduce the behaviour with the most minimal changes possible.
90% of the time you'll work out what the problem is while you're putting the sample together, and if not then you have a simple example we can reproduce here.
This is only a problem if the grid is not visible at the beginning and is later set to be visible, but not if the grid is visible at the beginning
We still need a way to reproduce the problem locally. Also, specify the browser and see if it happens in other browsers.
This happen when you create the grid inside a container that is hidden. SlickGrid doesn't resize properly when its container is not visible because it cannot calculate the viewport size properly. That was mentioned a few times on Stack Overflow
@ghiscoding Yes, as you said, this happens when creating grids in hidden containers, but I tested with official examples and found no problem. The official example is the relative positioning of containers. If there is no relative positioning, there will be this problem, but the relative positioning in my local environment also has this problem.
Are you re-rendering on showing the grid? I reiterate: I'd recommend starting with one of the example pages and trying to reproduce the behaviour with the most minimal changes possible. Also, specify the browser and see if it happens in other browsers.
This is the only reliable way we can assist with this.
The grid container is initially hidden, then through a button click, the grid's resizeCanvas method is invoked, and when the grid container is displayed, the grid style is distorted
I'm sorry, but you're not following my advice. If you can reproduce the problem with a minimal number of changes to an official example, please post it and I'll take a look.
The above screenshot is that I used the official example and made a small change to reproduce this problem. Do I need to re-publish this problem?
The fact that you are hiding the grid at first is probably the problem. SlickGrid requires the grid to be shown so that it can calculate the viewport size, if it's hidden it cannot calculate the correct size and you end up with a distorted grid (like you shown).
Screen shot are not a reproducible code sample that we can troubleshoot.
My system is a multi-label single page application, where one label page dynamically refreshes the grid in other labels, while the other labels are hidden at this time. The grid style in this application scenario is abnormal.
I'm trying to show the grid before refreshing it, but that adds complexity to business development.
Like I said earlier, SlickGrid has problem calculating the viewport when the grid is in a hidden container. In your code, try to call the resizeCanvas
after the grid is shown, not before.
So try
- grid show
- resizeCanvas
You can see this SO answer as a reference.
Have you seen http://6pac.github.io/SlickGrid/examples/example-dynamic-with-jquery-tabs.html ?
Also, it's worth mentioning the internal functions cacheCssForHiddenInit()
and restoreCssFromHiddenInit
. You could probably use those if you need to resize while hidden. They are what the grid uses as a workaround when initialising the grid while hidden - the same logic would apply to resizeCanvas.
Perhaps they should be exposed via the API, or perhaps an option on 'ResizeCanvas' could trigger their use.
http://6pac.github.io/SlickGrid/examples/example-dynamic-with-jquery-tabs.html I took a look at this example, initializing the grid in a hidden container also works fine, does slickgrid have jquery tabs handled internally? How does this work?
The grid uses the internal functions cacheCssForHiddenInit()
and restoreCssFromHiddenInit
for hidden init, as just mentioned. This modifies the page CSS so that the init works properly, then puts it back the way it was afterwards. Try copying the code and putting it before and after your resizeCanvas call and we'll see if that fixes it. If so, I can make them available for external use.
There is no special allowance for jQuery tabs, anything should work.
A little better than before. But it doesn't render properly
I'm still willing to help out with this, but you need to provide the test file you are using. Please make sure it works in the example folder of the repo, then drag and drop it to the bottom area of your post.
I had to deal with hidden grid today and the best solution is to preset the grid container to opacity: 0
, which is basically making the grid invisible (but not hidden) and once you're ready to make it visible then you can change to opacity: 1
which will make it visible. Playing with the Opacity has the advantage of creating the grid with proper size and everything without altering the canvas/viewport size calculations.
We should probably close this issue and just tell users to use opacity
instead of display
I think visibility: hidden
has the same effect. However they still consume space on the page, it's just rendered as empty space.
That's exactly what I wanted... to consume the space. My grid has auto-resize enabled and when I was showing the grid (with display
) it was kinda making the grid jump because for a fraction of a second while was resizing and that was bothering me, however with opacity
, it's even resized before I'm ready to show it and doesn't have a jumping side effect. So yeah "consume the space" is what I actually wanted :)
... and you're right, the visibility
has the same effect, I'll use that instead. Thx
And I'm still not sure why cacheCssForHiddenInit()
doesn't work. It saves hidden parent element styles, and then sets them to position: absolute
, visibility: hidden
, display: block
while the Init
process happens. This is essentially exactly what you are suggesting, @ghiscoding (although - last comment - without the position: absolute
).
Here's the code:
var cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };
function cacheCssForHiddenInit() {
// handle display:none on container or container parents
$hiddenParents = $container.parents().addBack().not(':visible');
$hiddenParents.each(function() {
var old = {};
for ( var name in cssShow ) {
old[ name ] = this.style[ name ];
this.style[ name ] = cssShow[ name ];
}
oldProps.push(old);
});
}
function restoreCssFromHiddenInit() {
// finish handle display:none on container or container parents
// - put values back the way they were
$hiddenParents.each(function(i) {
var old = oldProps[i];
for ( var name in cssShow ) {
this.style[ name ] = old[ name ];
}
});
}
It might be worth stepping through the code and seeing what parent elements are being acted upon - it's possible that evolving HTML has mucked this up.
@songjiqiang I still don't know what browser and OS you are using. Looks like Chrome? Version? Windows? Version?
Sounds like it might be worth a setting to specify the startup behaviour around this.
It might be because these position: absolute
, display: block
might not be what everyone have as their default?! Is that the <div>
container that we associate the Grid with? If so, mine has the display: block
but has a different position: relative
而且我仍然不确定为什么
cacheCssForHiddenInit()
不起作用。它节省了隐藏父元素的样式,然后将它们设置为position: absolute
,visibility: hidden
,display: block
而Init
过程发生。本质上,这正是您所建议的@ghiscoding(尽管-最后一个注释-没有position: absolute
)。这是代码:
var cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' }; function cacheCssForHiddenInit() { // handle display:none on container or container parents $hiddenParents = $container.parents().addBack().not(':visible'); $hiddenParents.each(function() { var old = {}; for ( var name in cssShow ) { old[ name ] = this.style[ name ]; this.style[ name ] = cssShow[ name ]; } oldProps.push(old); }); } function restoreCssFromHiddenInit() { // finish handle display:none on container or container parents // - put values back the way they were $hiddenParents.each(function(i) { var old = oldProps[i]; for ( var name in cssShow ) { this.style[ name ] = old[ name ]; } }); }
可能值得单步执行代码并查看将要作用于哪些父元素-不断发展的HTML可能将这一点搞砸了。
@songjiqiang我仍然不知道您正在使用什么浏览器和操作系统。看起来像Chrome?版?视窗?版?
This has nothing to do with browser. I tested several browsers, all of which have this problem. The screenshot above is Firefox. Windows 10
@ghiscoding by saving the existing CSS props and then making position: absolute
, visibility: hidden
, display: block
, the code ensures that the grid is not hidden (display: block
), not visible (visibility: hidden
), but doesn't consume space in the flow (position: absolute
). If the container is initially hidden (display: none
), it will remain invisible, in this new way, through the Init() process, and then be restored to its initial settings.
@songjiqiang thanks, I'll have a look on the weekend.
a lot has changed since this issue was opened, we dropped jQueryUI, then jQuery, we migrated to TypeScript and we have a new Alpine Theme... so considering how old this issue is and all the changes since then, I think it's fair to close it. Please provide more details if it is still happening