WTableView with "loading" lines
Added by Sébastien D. almost 13 years ago
Hello,
we have a WTableView displayed with a WStandardItemModel holding the data.
we add data on the fly like this :
int row = m_pModel->rowCount();
m_pModel->insertRow(row);
m_pModel->setData(row, 0, data1);
m_pModel->setData(row, 1, data2);
m_pModel->setData(row, 2, data3);
m_pModel->setData(row, 3, data4);
m_pWapp->triggerUpdate();
the problem is that some times the lines in the table are not displayed, they are only showing "loading".
any clue on the origin of this problem?
btw that's wt 3.2.0
P.S.: A screenshot of an other table view wich has exactly the same problem: http://goo.gl/5i7Z5
it shows 2 lines correctly displayed, and a few others not loaded
Replies (24)
RE: WTableView with "loading" lines - Added by Greg Martin almost 13 years ago
Hi Sébastien,
Have you find a solution for your problem ?
In my WTableView, the third line is never displayed but if a new record is added, everything is fine.
The first and second are OK, it's just the third.
RE: WTableView with "loading" lines - Added by Wim Dumon almost 13 years ago
Hello,
We haven't seen this problem. Can you send us a small test case that demonstrates the issue?
Thank you,
Wim.
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
I have seen a similar problem with my tables - sometimes the tables display only the first few rows and then the "loading" graphic for the rest. If you scroll the table and then scroll back all is resolved.
We use server push and the table is sized by a layout manager. Perhaps one of those triggers the problem?
I noticed yesterday that I am getting a few errors reported like this:
[error] "WTableView: resize(): height cannot be a Percentage"
Is it possible that this error causes the behaviour?
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey,
I believe that very well may be involved. Do you resize the WTableView using percentage ? If it is placed in a layout manager then it should not be given a size at all ?
A small test case that reproduces it would be welcome !
Regards,
koen
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
We made some progress on this matter, and we have a (not satisfying) fix (see at the bottom of this post).
We made a small test app, and it does not show exactly the same symptoms, but it has a problem which in fact seems to be the same:
there is a button and a WTableView, when you click the button it adds a row to the table.
But for the first time it does not appear. Then if you click a second time on the button, the first line appears.
In our real application, the first line appears as "loading", when we add a second line, the first appears, and so on. Well it's pretty random but today it was doing this.
We looked at what's going on under the hood with firebug
what we see (I guess) is:
Test App:
<click>
> client sends Post request saying 'click on the button'
< server answers
> client sends Post request saying 'is there anything new for me?'
1< server answers 'nope'
> client sends Post request saying 'is there anything new for me?'
< request hangs and renew from time to time
<click>
> client sends Post request saying 'click on the button'
< server answers
> client sends Post request saying 'is there anything new for me?'
2< server answers 'Yes here is the line you added when you clicked the first time!'
> client sends Post request saying 'is there anything new for me?'
< request hangs and renew from time to time
first line appeared at this point (2)
In the real app it's pretty much the same except that the first time the server sends stuff (at point 1) similar to what it sends at point 2 but the data is not there, it's all empty.
===
The fix
===
Now what we did in the code (simplified version, I don't have the code with me atm):
void SomeClass::CalledWhenTheBtnIsClicked( void someData )
{
m_theWServer->post( m_sessionId, SomeFunctionWhichDoesTheActualWork );
}
with
void SomeClass::SomeFunctionWhichDoesTheActualWork( void someData )
{
int row = m_pModel->rowCount();
m_pModel->insertRow(row);
m_pModel->setData(row, 0, ...);
m_pModel->setData(row, 1, ...);
m_pModel->setData(row, 2, ...);
m_pModel->setData(row, 3, ...);
m_pWapp->triggerUpdate();
}
well, if we do "the actual work" directly in CalledWhenTheBtnIsClicked(), the problem is gone (at least in the test app, we didn't have time to try it in the real software).
But we did this on purpose because CalledWhenTheBtnIsClicked() is not only called when the button is clicked, but also by some other (non-ui related) code and we needed to avoid any locks.
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
I believe that very well may be involved. Do you resize the WTableView using percentage ?
I'd have to do some analysis on this as it's all buried in a framework. However, after a quick look through the code, I am confident that this occurs in a class that does the following (where "view" is sometimes a WTable):
Wt::WBoxLayout* layout = new Wt::WBoxLayout( Wt::WBoxLayout::LeftToRight );
...
view->resize( Wt::WLength( 100.0, Wt::WLength::Percentage ), Wt::WLength( 100.0, Wt::WLength::Percentage ) );
layout->addWidget( view, Wt::AlignTop | Wt::AlignLeft );
If it is placed in a layout manager then it should not be given a size at all
I think that this indeed the intention of the above code. Perhaps the call to resize() is unnecessary? I have a feeling that it was needed to get this class to work as we wanted, but perhaps that was due to misunderstanding Wt layout (this would be some of our earliest Wt code!) or maybe to workaround a bug. I will investigate this.
I just had a quick look at the WBoxLayout documentation and it seems that the above code is completely wrong. The signature of WBoxLayout::addWidget is as follows:
addWidget( WWidget* widget, int stretch = 0, WFlags< AlignmentFlag > alignment = 0 );
It seems that the alignment flag is being passed in as the stretch parameter due to an implicit conversion from WFlags to int! I will fix this and see if the problem with the table goes away.
Sébastien - the behaviour you are seeing seems correct. If you asynchronously update the table then you will need to push changes out to the browser via the server push feature.
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey Sébastien,
The problem is intriguing. Any chance you can share the test app with me so that I can pinpoint the problem ?
Regards,
koen
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
here it is: http://goo.gl/J0Pao
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey,
You don't seem to call enableUpdates() anywhere ? If I do this (e.g. from within your application constructor), then this runs fine.
Regards,
koen
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
Good catch!
Indeed the call to enableUpdates() is missing in the test app.
But it is present in the real software :/
A coworker of mine is working atm on reproducing the bug in the test app.
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
he's done it :)
here is a new test app featuring the bug: http://goo.gl/EWU8R
It is somewhat closer to the real software as it has a WStackedWidget holding the UI, the sending UI is in one tab, the WTableView in an other.
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
he's done it :)
here is a new test app featuring the bug: http://goo.gl/EWU8R
It is somewhat closer to the real software as it has a WStackedWidget holding the UI, the sending UI is in one tab, the WTableView in an other.
haha I forgot the link: http://goo.gl/EWU8R
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey Sebastien,
I tried your example with Wt git (which is not much different from wt-3.2.1-rc2), but could not reproduce the problem.
Could it be that this problem has been solved in 3.2.1, or if not, do you have specific hints on how to reproduce the problem (browser, wt config options, ...) ?
Regards,
koen
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
Sorry I should have mentioned, the target browser is IE8.
I tried in chrome and the bug is not present, although it is in the real software :/
Btw there is a weird behavior I never noticed before: with the test app, I need to hover the mouse over the lines of the table to make them appear, whether they show the data or "loading"
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
Daniel Paull wrote:
It seems that the alignment flag is being passed in as the stretch parameter due to an implicit conversion from WFlags to int!
I will fix this and see if the problem with the table goes away.
I fixed this and it made no difference, so the error reported seems to be innocuous.
However, I did find the source of the problem! In our code, the WTable has its size set as follows:
view->resize( Wt::WLength::Auto, 150 );
It is then put into a layout manager which changes the table height. The result is that the rows that would have been visible if the table were 150 pixels high are shown while the remainder display the "loading" graphics until you scroll the table. Perhaps the WTable needs to be layout-size-aware and push data as required when the size changed? Or am I doing something wrong? In this part of my application, the factory that generated the WTable is not aware that the table is going to be put inside a layout manager, so I am not sure how I would avoid the call to resize().
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey Daniel, Sebastien,
Daniel: you can remove the size with view->resize(WLength::Auto, WLenght::Auto) before you put the table in the layout manager, this will reset the size set by the factory ?
Sebastien: I now can reproduce the problem. It is a classical (albeit not trivial?) IE render/layout problem, although I couldn't find an easy workaround for it (yet).
However, if you also saw this with Chrome/Firefox that means there are actually two problems to solve ?
Regards,
koen
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
Koen Deforche wrote:
Daniel: you can remove the size with view->resize(WLength::Auto, WLenght::Auto) before you put the table in the layout manager, this will reset the size set by the factory ?
Good idea! I give that a try - I've run out of time today, but should be back on this later in the week.
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
Hello,
The bug does appear with firefox and the real software :/
This is weird because the test app works fine on firefox, while they exhibit the same symptoms.
Do you have any ideas or pointers to fix this?
I am going to try and find a fix because we need to ship asap, but I don't really know where to start.
Thanks for you help,
Sébastien
RE: WTableView with "loading" lines - Added by Koen Deforche almost 13 years ago
Hey Sebastien,
To me, this means there are two (possibly unrelated) problems.
I can imagine both need fixes, but which you want is priority ?
For the Firefox problem, I have no clue yet, I would imagine there is something wrong in the server-push/sync logic, but it seems hard to reproduce.
Two suggestions:
- can you see if using an (undecorated) WTreeView is a workaround which does not trigger the problem ?
- can I somehow get access to a running application ?
Regards,
koen
RE: WTableView with "loading" lines - Added by Sébastien D. almost 13 years ago
I've replaced the WTableView with a WTreeView and it eliminates the problem with the test app and IE!
I did it in the real software too and the problem is gone in both IE and chrome.
But not everything is working yet.
From what I've seen with a quick test:
- double-clicking a line no longer works (it was supposed to bring up some informations),
- an error is displayed when the page is first loaded (only on IE though),
- I made it crash by clicking the + next to a line. I guess I'll need to call setRootIsDecorated(false) or something alike.
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
Daniel Paull wrote:
Koen Deforche wrote:
> Daniel: you can remove the size with view->resize(WLength::Auto, WLenght::Auto) before you put the table in the layout manager, this will reset the size set by the factory ?Good idea! I give that a try - I've run out of time today, but should be back on this later in the week.
>
Ok, this approach worked, so my lists now display all rows initially.
However, a colleague of mine discovered an odd behaviour. If you make the browser window unusually tall - like extended over two monitors (the browser window height would be about 2000 pixels), we still see some lines missing which then get fixed up when you scroll. I'm not concerned with this at the moment though as users will likely never see it. It would be nice to know if all WTables behave like this though.
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Anonymous almost 13 years ago
Daniel Paull wrote:
Daniel Paull wrote:
> Koen Deforche wrote:
> > Daniel: you can remove the size with view->resize(WLength::Auto, WLenght::Auto) before you put the table in the layout manager, this will reset the size set by the factory ?
>
> Good idea! I give that a try - I've run out of time today, but should be back on this later in the week.
>Ok, this approach worked, so my lists now display all rows initially.
However, a colleague of mine discovered an odd behaviour. If you make the browser window unusually tall - like extended over two monitors (the browser window height would be about 2000 pixels), we still see some lines missing which then get fixed up when you scroll. I'm not concerned with this at the moment though as users will likely never see it. It would be nice to know if all WTables behave like this though.
Cheers,
Dan
Sorry, I spoke too soon. I had inadvertently left the call to resize( WLength::Auto, 150 ) commented out when testing this!
Calling resize( WLength::Auto, WLength::Auto ) before adding the WTableView to the layout manager seems to have no effect on this problem. Looking at the implementation of WTableView::resize(), the reason may be obvious:
void WTableView::resize(const WLength& width, const WLength& height)
{
if (ajaxMode()) {
if (height.unit() == WLength::Percentage) {
LOG_ERROR("resize(): height cannot be a Percentage");
return;
}
if (!height.isAuto()) {
viewportHeight_
= static_cast<int>(std::ceil((height.toPixels()
- headerHeight().toPixels())));
}
} else { // Plain HTML mode
if (!plainTable_) // Not yet rendered
return;
plainTable_->setWidth(width);
if (!height.isAuto()) {
if (impl_->count() < 2)
impl_->addWidget(createPageNavigationBar());
}
}
computeRenderedArea();
WCompositeWidget::resize(width, height);
scheduleRerender(NeedAdjustViewPort);
}
Notice that if the height is not auto then viewportHeight_ is set. Subsequently changing the height back to Auto does not change viewportHeight_ back to what it used to be (the default is 600). When computeRenderArea() is called, the hight used to determine the number of rows is dependant on viewportHeight_ as follows:
int top = std::min(viewportTop_,
static_cast<int>(canvas_->height().toPixels()));
int height = std::min(viewportHeight_,
static_cast<int>(canvas_->height().toPixels()));
From what I can gather by reading the code, this problem has always existed, it's just that the default for viewportHeight_ of 600 (from UNKNOWN_VIEWPORT_HEIGHT) has meant that it only gets seen when a table is initiall taller than most monitors!
Any thoughts on how to make this behave correctly?
Cheers,
Dan
RE: WTableView with "loading" lines - Added by Koen Deforche over 12 years ago
Hey Dan,
I guess the right solution would be to correct missing data as soon as the view knows its actual size.
For 3.2.1 I would simply propose to change the 600 in 1600.
Regards,
koen
RE: WTableView with "loading" lines - Added by Anonymous over 12 years ago
Hi Koen,
I'm not sure that changing the UNKNOWN_VIEWPORT_HEIGHT is necessary as more data than is visible through the viewport is actually sent to the client. The algorithm is something like viewportHeight_*2 + 5*rowHight(). So in the default case this is 1200px plus 5 rows. This seems sufficient as the default except in the case of a very tall table.
In the short term I think the most important change is to ensure that viewportHeight_ is set back to UNKNOWN_VIEWPORT_HEIGHT in resize() when the height is set to Auto. Longer term it would be good to make the WTableView layout-size-aware when its height is set to Auto.
In the interim, I can probably do the above in my code using a subclass of WTableView.
Just a final note - there maybe be a corresponding problem with width (ie, columns not displayed in the table) but I have not looked into this at all.
Cheers,
Dan