ScrollView with ScrollViewPager and filtering data

Hello Team,

Fuse Version: 1.7.3 Build 15528
Operating System: macOS High Sierra 10.13.3

i wrote that already to Uldis a few day ago, but i did not get an answer, perhaps he is busy or did not received my mails.

i am not sure if it is a bug or if i am doing something wrong:

when using “Each” in a “ScrollView” in combination with “ScrollViewPager” and changing the Observable of the “Each” for filtering or searching values in the list i get a blank view or in some cases the filtered results moving slowly from bottom to top.

i have attached a sample project
to reproduce the issue:

  • first scroll the view several times down that more data gets loaded by the ScrollViewPager ReachedEnd event.
  • type a search expression into the searchbar for example “jo” for Jordan or something else.
  • after the list gets filtered by the search expression you should see a blank white screen

also if you remove the search expression you can see in the console log that data gets loaded but not displayed anymore.

if you reload the project and do not scroll before you enter a search value the list gets filtered fine.

sometimes it happens that the filtered results appearing slowly from bottom to top, i realized when setting “SnapMinTransform” and “SnapMaxTransform” to “false” it is better.

i think perhaps the scrollview is not updating its scroll content after removing items of the Observable bound to “Each”

Not sure if there are options like ScrollView.BeginUpdate and ScrollView.EndUpdate where i can remove or add items to the bound Observable and after that ScrollView will do new calculations without animations.

i also tried ScrollView.seekTo(0,0) after removing items from the list for filtering, but i think ScrollPosition is virtual when using ScrollViewPager?!

Best Tom

Hi Tom,

now I see the problem, it’s that your list needs to change dynamically. ScrollViewPager only deals nicely with static lists, so it’s a no-go in this case. Mostly because ScrollViewPager keeps track on which page it is on, how many items are there in the list etc. So it gets totally confused when you start altering that list.

Lucky for you, implementing something that is very much ScrollViewPager-like isn’t too complicated, we even have an example for that. I’m sure you could adopt that for your use-case.

Hi Uldis,

thank you for your reply on this and for providing me a an example. Appreciate you support.
But this example cannot work with search/filtering.

For example:
you do a filter where the results are 7 items, the list gets cleared and the new 7 items will be appended to the list. after that atEnd “Scrolled” will fire its event because it is near end (list count < view height) and offset will change +5, the result is that you will see only 2 items of the 7.

you can try it in the attached sample project, I have added 542 test items with numbered names form 1 to 542, when you type for example 111 or 222 or something similar into the search field, you will have one result item. but this item will not be displayed because atEnd is fired and increases the offset with 5.

you will have the same problem if you have only 5 items available in the database and you are searching in this 5 items. you will trigger atEnd “Scrolled” and change the offset +5 which results in an empty view.

correct me if I am wrong but looks like there is no reliable solution of handling large amount of data with search/filter option at the moment which is in my eyes a basic operation in apps.

the easiest solution would be a reset option for the ScrollViewPager to its initial state after performing a search, but at the moment there is no option like this.

i am looking forward for a solution, perhaps you have an idea.

Thanks for ur help,
Tom

Hi Uldis,

at the moment i have a workaround for the search/filter problem, but it feels a bit hacky :wink:

i am using ScrollViewPager but also a binding to the Offset of the “Each”.
i know when using ScrollViewPager, the ScrollViewPager controls the Offset and the Limit of the “Each” but it is the only way i found to reset the internal ScrollViewPager Offset calculation…

<ScrollView LayoutMode="PreserveVisual">
    <Each ux:Name="theEach" Items="{items}" Offset="{theOffset}">
        ...
    </Each>

    <ScrollViewPager ux:Name="theScrollViewPager" Each="theEach" ReachedEnd="{ loadMore }" />
</ScrollView>

and in JS


function doSearch(searchExpr) {
    //clear all items in Observable
    items.clear();
    //set offset of "Each" to 0 so ScrollViewPager recalculates new Offset
    theOffset.value = 0;
  
    //... do the filtering stuff and add the results back to items (items.addAll(filterResults))

    // let ScrollViewPager know about the new added items...
    theScrollViewPager.check();
}

it is working but as i wrote already it feels a bit hacky, perhaps there will be a implementation in ScrollViewPager in the near future or something else…

Best Tom

If it’s working, then it’s not a hack!

That said, I still think you should’ve used the other approach I linked. Of course, it’s just a starting point and requires quite some work.