# Listbox with vflex, variable row height and autopaging flickering

JuliaZ
3 2

Hello,

we have a listbox (using vflex) with variable row height and try to use autopaging. When modifying the css that is applied to the cell content when autopaging is turned on to automatically apply the correct height to

.z-listbox-autopaging .z-listcell-content { height: auto; overflow: hidden; }

the table starts to flicker or the content "jumps" in some cases because the page size and the page count seems to be recalculated again and again.

We want to avoid setting the pagesize to a fixed value or setting the height of the cell content to an absolute value (which could cut off multi line content).

The table is embeded like this:

<vlayout id="123" sclass="main" vflex="1"
apply="SomeController">
...

<panel id="resultPanel" visible="false" title="scan" border="normal" vflex="1">

<caption sclass="mainCaption"/>

<panelchildren>

<vlayout sclass="resultInformation">
<label id="scanResultResultSizeLabel"/>
</vlayout>

<listbox id="scanResultListbox" vflex="1" mold="paging" pageSize="20"
sclass="listboxVerticalLinesRight defaultCursor">
</listbox>

</panelchildren>
</panel>
</vlayout>


We are using ZK 8.5.0. The issue was also reported in ZK-2359, but the solution was to set the height to an absolute value.

Is there any other solution to this?

delete retag edit

Sort by » oldest newest most voted

MDuchemin
1856 1 5

So, the bad news first: Autopaging sets a css on the rows to get them all on the same size because it's how autopaging ensures that the line heights are consistent.

When using autopaging, the listbox will work under the assumption that the size of the next row (if there is space left in the listbox after rendering) is consistent with the existing rows.

Let's say you have 1000px available, and your listbox currently have a set of 4 rows of 180 each in average. (it just divide the currently used space by the number of rows currently rendered) The listbox will calculate that it can fit in the next row, since there is currently 280 px available and the rows height is averaged to 180px. The listbox will send a pagesize request to the server, telling it to load 5 rows instead of 4. If the row returned by the server is bigger than the available space left in the listbox (281px or higher), the listbox will send back a new pageSize request of 4, because the current set of row is too big for the viewport. The listbox receive a set of 4 rows, etc. then the loop restarts from there. There isn't a good way for the listbox to know how many rows it can fit in that situation.

https://www.zkoss.org/wiki/ZKComponentReference/Data/Listbox#Autopaging The documentation indicates that all rows must have the same size for autopaging to work.

So, now to solutions. I know that these are basically the scenarios that you are trying to avoid, but since autopaging just doesn't do what you need, you can give a second look to these options:

1 - Set the same height on every row. Easiest choice if you can estimate the tallest possible row of the listbox, just make that the default size for every row. You will get some rows with empty space, but you will be able to use autopaging to automatically set the pageSize depending on the screen height.

2 - set a pageSize, have a scrollbar inside the listbox if necessary (if the size of all rows are bigger than the viewport). Depends how you feel about having a scrollbar in the listbox itself. I'm guessing you probably don't want one, since you are using autopaging, but hey :)

3 - change the display to a different option which works allow for the content to be displayed in lines with a consistent height. (change the long label to a button with a popup, or show the beginning of the labels (with an ellipsis if too long, using text-overflow: ellipsis; on the label) which the user can click or mouseover to get more info, etc.

Going further: ZK has the potential to be overridden for any usage. You could consider writing your own page control tool if you have an idea on how to handle the main issue here (calculating page size on the fly, while only being able to calculate loaded rows). This said, that feels like a project with a few hurdles to overcome. You'd need to manually handle the paging component since the default paging assume that every page has the same number of entries, test for page sizes, keep the current index in memory, etc. It would also cause problems for you if the model were to change during the component's lifecycle, since a row may have more than one height during its existence. That makes caching page sizes and row sizes difficult.

[hide preview]