0

Probem when I refresh LismodelList data in a listbox

asked 2019-12-09 19:33:49 +0800

softteam gravatar image softteam
47 5

updated 2019-12-19 17:37:10 +0800

cor3000 gravatar image cor3000
5069 2 7
ZK Team

I put you in situation: When scrolling in a listbox horizontally and then refresh the listmodellistdata, the horizontal visual position of the listbox is at the beginning and I have to scrolling again. Is there any possibility to maintain the scrolling position when I refresh the data? Thanks in advance

Zul test file:

    <zk>
<window id="BLGeneral" width="100%" height="100%"  apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('org.Main')" onCreate="@command('InicializaPagina')">
<!--    <div height="100%" style="overflow:auto"> -->
        <listbox autopaging="true" mold="paging"  id="list"    model="@load(vm.beans)"  sizedByContent="true">
        <custom-attributes org.zkoss.zul.listbox.autohidePaging="false"/>
            <listhead sizable="true">
                <listheader label="id" sort="auto"/>
                <listheader label="nombre" sort="auto"/>
                <listheader label="apellido" sort="auto"/>
                <listheader label="edad" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>
                <listheader label="genero" sort="auto"/>

            </listhead>
            <template name="model" var="item">
                <listitem  value="@load(item)" >
                    <listcell label="@load(item.id)" />
                    <listcell label="@load(item.nombre)" />
                    <listcell label="@load(item.apellido)" />
                    <listcell label="@load(item.edad)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                    <listcell label="@load(item.genero)" />
                </listitem>
            </template>
        </listbox>
        <button id="BTNrefresh" label="Refrescar"/>

Controller file test:

public class Main extends   SelectorComposer<Component>{

    private ListModelList<Agregado> listaBeans = new ListModelList<Agregado>();
    private int cont = 0;

    @AfterCompose
    public void init(@ContextParam(ContextType.VIEW) Component view) {
        Selectors.wireComponents(view, this, false);
        Selectors.wireEventListeners(view, this);
        Selectors.wireVariables(view, this, null);
    }

    @Command
    @NotifyChange("*")
    public void InicializaPagina() {
        cont = 0;
        llenarBean();
    }

    private void llenarBean() {
        ArrayList<Agregado> agregado = new ArrayList<>();
        agregado.add(new Agregado("1", "Xavi "+cont, "Pons "+cont, "25 "+cont, "home "+cont));
        agregado.add(new Agregado("2", "Jordi "+cont, "Pons "+cont, "25 "+cont, "home "+cont));
        agregado.add(new Agregado("3", "Joan "+cont, "Pons "+cont, "25 "+cont, "home "+cont));
        agregado.add(new Agregado("4", "Pere "+cont, "Pons "+cont, "25v"+cont, "home "+cont));
        listaBeans.addAll(agregado);





    }

    @Listen("onClick=#BTNrefresh")
    public void refrescar() {
        cont++;
        listaBeans.clear();
        llenarBean();
    }

    public List<Agregado> getBeans () {
        return listaBeans;
    }
    public void setBeans (ListModelList<Agregado> beans) {
        listaBeans = beans;
    }


    public class Agregado {

        private String id;
        private String nombre;
        private String apellido;
        private String edad;
        private String genero;



        public Agregado(String id, String nombre, String apellido, String edad, String genero) {
            super();
            this.id = id;
            this.nombre = nombre;
            this.apellido = apellido;
            this.edad = edad;
            this.genero = genero;
        }
        public String getId() {
            return id;
        }
        public String getNombre() {
            return nombre;
        }
        public String getApellido() {
            return apellido;
        }
        public String getEdad() {
            return edad;
        }
        public String getGenero() {
            return genero;
        }
        public void setId(String id) {
            this.id = id;
        }
        public void setNombre(String nombre) {
            this.nombre = nombre;
        }
        public void setApellido(String apellido) {
            this.apellido = apellido;
        }
        public void setEdad(String edad) {
            this.edad = edad;
        }
        public void setGenero(String genero) {
            this.genero = genero;
        }


    }



}
delete flag offensive retag edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2019-12-19 17:59:11 +0800

cor3000 gravatar image cor3000
5069 2 7
ZK Team

updated 2019-12-19 17:59:23 +0800

invalidation is triggered also, when the model becomes empty, avoiding an empty model worked on my side:

@Listen("onClick=#BTNrefresh")
public void refrescar() {
    cont++;
    int previousSize = listaBeans.size();
    llenarBean();
    listaBeans.removeRange(0, previousSize);
}

BTW: your view model doesn't have to extend SelectorComposer it's not used as a composer and a View Model doesn't require any particular interface/base class.

link publish delete flag offensive edit

Comments

thanks!! it worked perfectly!!

softteam ( 2020-01-14 19:58:09 +0800 )edit
0

answered 2019-12-10 10:12:25 +0800

MDuchemin gravatar image MDuchemin
1511 1 5
ZK Team

Hi there,

If the position of the scroll is reset, that usually means that the listbox got invalidated. Based on the code provided, I'd say you probably run in one of 2 scenarios:

1 - triggering MVVM notification on listbox model: If your viewmodel triggers either a @notify("*"), a @notify("beans"), a BindUtils.postNotifyChange(null, null, this, "beans"); or any other instruction that trigger the model load binding, then the listbox will redraw.

You can easily test that by changing the model="@load()" by a model="@init()" binding on the listbox. @init only fire once when loading the page, so the model object itself is not replaced by a different instance. Since you are already using a ListModelList, you can just change the model content without replacing by a new instance.

2 - reaching the Listbox invalidate threshold: Mesh components will automatically invalidate and redraw if more 10 lines are modified in one event. This is controled by the invalidate threshold library property and can be configured for each listbox individually. This one is a performance trade-off. If you clear a model that holds 500 entries, rather than deleting 500 rows, it makes more sense to the UI to just start from an empty state and insert new lines directly.

You can use the invalidate threshold and set a large number (larger than expected model for this listbox) to test if it prevents invalidating.

link publish delete flag offensive edit

Comments

I tried both options but the scrolling position remains in the initial position

softteam ( 2019-12-12 23:02:55 +0800 )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

Follow
2 followers

RSS

Stats

Asked: 2019-12-09 19:33:49 +0800

Seen: 15 times

Last updated: Dec 19 '19

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