0

Listbox - lost selection on model refresh

asked 2020-04-29 17:43:26 +0800

zkulm gravatar image zkulm
100 1

Hi ZK community,

we have an issue with a Listbox backed by a ListModel. If the ListModel is refreshed and at the same time the User selects a row, the selection is lost.

See the zkfiddle below for an example with three variants of the ListModel refresh. Variant 1 and 2 have the same behaviour while variant 3 seems to (unreliably) select the row after jumping between selected items.

You can reproduce this issue by the following steps: 1. select a row 2. select the input field 3. select a different row

This results in no row selected.

https://zkfiddle.org/sample/3vfa3e3/4-onBlur-Event-Order

Thanks for your help!

delete flag offensive retag edit

6 Answers

Sort by ยป oldest newest most voted
0

answered 2020-04-30 18:52:29 +0800

MDuchemin gravatar image MDuchemin
1688 1 5
ZK Team

Hi there!

The sequence of event in this zkfiddle is as follow (when focusing the textbox, then clicking on a listitem)

1 - blur happen first (on mousedown), and cause an immediate zkau request with the blur event.

2 - while the request is in transit, the user finishes the click (mouseup), which cause a new request to be queued with the onSelect event, targeting the listitem li-1. However, for this request to start, the client waits on the ongoing request containing the blur. In the meantime, the client UI will display the item as selected.

3 - server processes the blur event. This cause the listbox to do a partial redraw (outerPartial command in the reply). As soon as the server refreshes the ListModel, the target component li-1 no longer exist, and has been replaced by the new listitem li-2

4 - the response for the first zkau request arrives to the client. The listbox redraws and loose the selection info that was set at client-side. The new request (for the select event) is sent at this time. It still contains the id of the deleted li-1.

5 - Server receives the onSelect event, with non-existing target (li-1 is already deleted). This select command is ignored.

From there, the question is: What is the use-case that you are trying to achieve? In my understanding, if blur on the textbox cause a redraw in the listbox, then the selectable options were invalid as soon as the textbox was blured, so not selecting is reasonable.

This said, it would be confusing of the end-user. So it could be better to set a processing mask on the listbox when this happen, to prevent the user from being able to "select" a listitem which will be replaced in the first place.

If you don't expect the listitems to be replaced, then there is probably something to dig in the ListModel itself. I see that you are implementing your own ListModel from AbstractListModel. Do you need a different handling than the default ListModelList? (In any case, I'd recommend choosing a different name to avoid confusion, as ListModelList is already the a commonly used ListModel implementation from the libraries)

Let me know how you expect the Listbox to behave in this case (when the user tries to select a listitem slated for replacement), I might get a better idea of the requirement :)

link publish delete flag offensive edit
0

answered 2020-05-06 18:39:14 +0800

zkulm gravatar image zkulm
100 1

Hello Duchemin,

Thank you for your reply. We have a further question regarding your Point 5: Is it possible to get Information on this ignored Event (e.g. Index number)? Or maybe get an index from a SelectEvent?

This would allow us to react to the information in our Controller, so that we can select the ListItem, even if it may not be the same ListItem as before.

We also considered the processing Mask, but we are reluctant to implement this solution because it may be very intrusive for the user.

Thanks again for your help.

Best regards from our Team.

link publish delete flag offensive edit
0

answered 2020-05-07 19:06:07 +0800

MDuchemin gravatar image MDuchemin
1688 1 5
ZK Team

Hello zkulm,

Not by default. The default onSelect event is only going to return a UUID for the selected item (which no longer exists at that point)

This said, you can do it with a custom event: https://zkfiddle.org/sample/3vfa3e3/7-onBlur-Event-Order-extra-event Just hook into the fireOnSelect method (which is called by the listbox to send the select event to the server), and add your own event to be fired to the server. You can then pass arbitrary data (such as the current selectedIndex at client-listbox side) and listen to it in the composer.

Non-standard, and you have no-guaranty that the target index is the item that you want. For example, if your listbox allows for sorting, then you will get the first item in the sorted list, not your original model. If you only care to know the index of the selected row however, it should provide that info.

link publish delete flag offensive edit
0

answered 2020-05-11 21:26:30 +0800

zkulm gravatar image zkulm
100 1

Hello Duchemin,

we have decided for a variation of your suggested solution. We intercept the AuRequest to get the index by storing information of the lastest discarded Listitems.

Now the issue seems to be to effectively make use of the index in the Event Cycle. The solution below has the issue that sometimes, the selection seems to be "jumping around".

https://zkfiddle.org/sample/3vfa3e3/10-onBlur-Event-Order

We would be grateful if you could help us out again.

Best regards from our Team.

link publish delete flag offensive edit
0

answered 2020-05-12 18:29:01 +0800

MDuchemin gravatar image MDuchemin
1688 1 5
ZK Team

Hi zkulm,

What I see in this fiddle is: step 1 - trigger blur on textbox by clicking in the listbox. Listbox selection is set at client-side after blur is sent, queuing the onSelect event (already prepared with old UUID). step 2 - blur is resolved, trigger listbox refresh including setting the selection state back to step 0 (before blur), since that's the only known selection at this stage. In the reply, this cause the selection step 3 - the listbox selection event is sent from client, with the old uuid. At the same time. the listbox is redrawn with the old selection from step 2 step 4 - the server process your customized select event, re-change the selection state to match your workflow. When the reply arrives, the selection is set back again to the new position.

It boils down to a question of priority between the client-side selection (done before the request / response cycle), the first redrawing caused by blur, and the 2nd redrawing caused by the resolution of the select event.

I wonder how this could be handled better. For example, what if we delay the blur event for a few milliseconds? It will make the UI less responsive for that blur, but it might be enough to do blur after the selection is sent, which would remove this issue while keeping the separation between data and component. here's a sample: https://zkfiddle.org/sample/3vfa3e3/12-onBlur-Event-Order-extra-event This way, if the user do a normal click on the listitem, the listbox select event should fire BEFORE the blur event on the textbox. Since the listbox would already have set selection (the listitem has not yet been reinstantiated at server side with a new UUID), the select event can finish normally, and the blur then fire on a model that already has the right selection. This said, I'm not a fan of the fact that this creates a racing condition between blur and select :|

Personally, I don't love the idea of mixing old UUIDs with current events in the listbox. Feels wrong, since it mixes presentation and data. This said, if that what makes sense in your workflow, then one good point of ZK is the ability to override and adapt :)

link publish delete flag offensive edit
0

answered 2020-05-15 17:45:44 +0800

zkulm gravatar image zkulm
100 1

Hello Duchemin,

thank you again for your very helpful input and your patience. In the end, we decided for the index based solution.

Best regards from our Team.

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

Follow
2 followers

RSS

Stats

Asked: 2020-04-29 17:43:26 +0800

Seen: 19 times

Last updated: May 15

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