Scroll a multiselect ListItem into view

asked 2018-11-01 07:31:43 +0800

yateam gravatar image yateam
3 1

I have a ListModelList with several items preselected on @init of the ViewModel.

    listModelList = new ListModelList<>(longList);

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">
            <listheader label="Label"/>
        <template name="model">
                <listcell label="${each.description}" value="${each.id}"/>

The ViewModel then has a command fixScroll:

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);

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?

delete flag offensive retag edit


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

1 Answer

Sort by ยป oldest newest most voted

answered 2018-11-02 16:32:56 +0800

MDuchemin gravatar image MDuchemin
1743 1 5
ZK Team

updated 2018-11-09 11:11:41 +0800

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, may need to change in other version)

zk.afterLoad('zul.sel', function() {
    var xListbox = {};
    zk.override(zul.sel.Listbox.prototype, xListbox ,{
        _syncSelInView : function() {
            var result;
            //your switch here
                //do original action
                result = xListbox._syncSelInView.apply(this, arguments);
                // something else (scroll to top) or nothing
            return result;
link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools




Asked: 2018-11-01 07:31:43 +0800

Seen: 8 times

Last updated: Nov 09 '18

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More