Issue filtering items in collection-repeat with search box

I’m currently building an app which contains a long list of items which need to be filtered by a search-input at the top. We moved to collection-repeat to improve performance and it has worked fantastically except for an issue with the search functionality.

If I scroll down the list any significant amount and then enter text into the search-input, it appears that no results are returned. After some investigation, I realised that the results are present but just scrolled outside the view. The scroll position for the collection-repeat is not reset when the number of items changes (i.e. when it’s filtered by a search term).

Check this behaviour out at the following codepen

My current quick-fix solution to this problem is to add ng-change="scrollTop()" to the input tag. The problem with this is that on a mobile device, when the user inputs a letter the input loses focus. This is quite annoying as the user might want to enter more than one letter into the search and has to keep re-selecting the input to do that. I can imagine it would be possible to set the focus to the input element after scrollTop() has been fired but it would be ideal if we could get to the root of this issue and have a consistent fix. Or maybe I’m missing out on something else important here.

@aidan I have exactly the same issue with my list. Have you found any solution to fix this?

Hey. I implemented a temporary fix as per what I said in this issue https://github.com/driftyco/ionic/issues/2523

I will check this out further and probably try create a permanent fix and PR in the coming week. Let me know how you get on with it.

I’m using the scrollTop() workaround as well but the problem is still that the input field looses focus on every change in the input when calling scrollTop()…

1 Like

@mhartington any idea how to keep the focus on the input field when the ng-change call the scrollTop method?

Not sure why you need to call scrollTop, seems to work fine with out.

2 Likes

@mhartington First scroll down the end of the list. Then type in the number zero into the search box. No results appear in the list. You have to scroll back up to find any results.

I was using ng-change=“scrollTop()” to solve this at first but as @flavordaaave mentioned the input loses focus every time you type a letter. I then implemented this temp fix https://github.com/driftyco/ionic/issues/2523

Ahh alright I see. Well in that case, try resize instead of scroll top

@mhartington Yes, resize() brings the list items into view but the list is scrolled to the bottom and the top of the list is hidden. Ideally, the top hits from a search are placed at the top and therefore you want them visible immediately.

As I mentioned in the issue I created, adding scrollView.scrollTo(0,0, false, null, true); to the end of the renederer() function in the collectionRepeat directive solves this. Is there any reason why this might cause issues for other use cases do you think?

@mhartington Check out the PR I created for this at https://github.com/driftyco/ionic/pull/2523. By default the list will scroll to the top on list-change or resize but setting collection-list-top=false disables this, say for a messaging app where new messages are appended at the bottom of the list and are necessary to keep in view.

1 Like

@aidan Any idea how this could be applied for the “normal” ion-list (like used in my example codepen) without using the collection-repeat directive?

1 Like

Thanks! Works great!

Aidan thanks for your efforts with this issue.

The commit referenced in this thread (https://github.com/driftyco/ionic/pull/2523) solves the issue of the scrollview not resizing and items in a newly filtered list not being visible, however, it presents a new issue for me: now whenever I trigger a popover or modal to open from the view containing the list, it resets the list (scrolls to top).

I’m trying to get the list to behave properly while being filtered, AND also not lose scroll position when a modal or popup is displayed. Anyone have an idea how to solve this? Seems like maybe another check in the render function could solve this…? Any help or leads would be greatly appreciated. Thanks!