-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I have a ListModelList with several items preselected on @init of the ViewModel.
listModelList = new ListModelList<>(longList);
listModelList.setMultiple(true);
listModelList.setSelection(longListSubset);
When the page renders, the ListBox is scrolled down to the last selected item (last in terms of list order, not selection order). I would like it to scroll to the top.
I have wired the ListBox to the view model, and added an onAfterRender event to the ListBox:
<listbox id="listbox" model="@load(vm.listModelList)" onAfterRender="@command('fixScroll')" hflex="min" style="height:300px;" checkmark="true" sizedByContent="true">
<listhead>
<listheader label="Label"/>
</listhead>
<template name="model">
<listitem>
<listcell label="${each.description}" value="${each.id}"/>
</listitem>
</template>
</listbox>
The ViewModel then has a command fixScroll:
@Command
public void fixScroll() {
// ZK scrolls to the last selection in the list, making the top out of view. Scroll back up.
Listitem first = listbox.getItemAtIndex(0);
Clients.scrollIntoView(first);
}
I have confirmed that the command fires and that the first item in the list is retrieved correctly. But scrollIntoView has no effect. This seems to be related to multiple selection. The view always remains on the last selection. Is there a way to override this behavior?
Hi Yateam,
You're right, the fireSized client method on the listbox triggers after sizing (when the listbox is attached to the page). It in turn calls the _syncSelInView() client function which sync the selection state received from the server side to currently displayed client-side objects. During _syncSelInView, the function will find the last item in the selection:
var selItem = this._selItems.length > 0 ? this._selItems[this._selItems.length - 1] : undefined;
and scroll to the position of this item.
You mentioned that you want the listbox to not scroll and keep the scroll position to the top of the listbox. Do you only want that behavior when loading the listbox? What if you change the selection later? Should it scroll at that point?
You can override this function for every listbox with the following (for 8.5.1.2, may need to change in other version)
<script><![CDATA[
zk.afterLoad('zul.sel', function() {
var xListbox = {};
zk.override(zul.sel.Listbox.prototype, xListbox ,{
_syncSelInView : function() {
var result;
//your switch here
if(false){
//do original action
result = xListbox._syncSelInView.apply(this, arguments);
}else{
// something else (scroll to top) or nothing
}
return result;
}
});//zk.override
});//zk.afterLoad
]]></script>
Asked: 2018-11-01 07:31:43 +0800
Seen: 11 times
Last updated: Nov 09 '18
Thanks, MDuchemin. In my case, I didn't care about sync behavior at all so overrode the function to do nothing. Worked great!
yateam ( 2018-11-03 01:10:44 +0800 )edit