The listview component is very powerful in itself but it has some problems:
One of the problems is when you need to use the filter bar, it’s not possible to format the filter box the way a textbox can be formatted.
The other problem is the search doesn’t evaluate the occurrence of text in the middle of the items text.
Example: If I type “al” and one of the items is “Italo”, it doesn’t show that item even though the string “al” is contained in it. But it will show Alfred, Albert and everything that STARTS with “al”.
If you need a workaround for these problems, you can follow this tutorial to build your own filter bar on the list view.
Inside an horizontal arrangement: One text box and One Button
Outside the arrangement (below): One Listview with the property “Show Filter View” unchecked.
Invisible component: One Clock with property “Timer Enabled” checked and Interval set to 250 ms
It should look something like this:
The text box will be our search box or filter. And right there, we solved one of the problems. Since the textbox is completely editable, you can change every property, like background color, custom font, etc. and it will still be usable as a search or filter box.
The button will be a quick CLEAR button, to delete whatever we typed in the textbox. You can use this or not, but I find it very useful, so the user doesn’t have to delete the characters typed one by one in case they want to perform a totally new search.
Now we need to “listen” to what the user is typing in the text box, so we can start searching in the list of items for what the user typed, and filter the list in real time as the user keeps typing.
To listen to it, we are going to use the clock component, set to 250 ms, which means that the Timer event will be called 4 times per second (1 second = 1000 ms) to grab the text typed, search for it in the list and temporarily eliminate from it, any item that doesn’t contain the text typed. That should be fast enough to simulate a real time filtering.
Note: This last step is also possible to build using @Taifun’s textbox extension, instead of using a clock. There’s an event in that extension that triggers when a textbox text is changed. Use that if it’s better or easier for you. I try to use extensions as less as possible to avoid compatibility issues and to be able to control everything in my procedures.
Let’s start by defining some global variables we will need:
TextboxPreviousText will be used to store the previous text every time the text changes.
FullList is the complete list of items that will populate the listview.
Let's initialize the listview elements when the app starts:
Now let’s see what the CLEAR button will do when clicked:
The button will delete everything in the textbox and set the listview to visible. We will see in a minute why we need to set it to visible.
This is what will happen every time an item is picked from the listview:
We will save the current value of the search box.
Change the text box text to the item selected from the listview.
And since the user selected something from the listview, we don’t need to show the listview anymore, so we hide it.
And this is the block that makes the whole thing possible.
This block is executed 4 times per second. Let me explain what it does:
First, it checks if the text box text changed from the previous check. We accomplish that by comparing TextBoxPreviousText with the current text of the text box.
If those are different, it means the user typed something in it and we should perform a new search.
For that, we have to set the listview to visible so the user can see all the items that match the search.
Then, we update the variable TextboxPreviousText, by copying in it what’s in the text box. Now both have the same content, until the user types something new in the text box.
Now we perform a quick search to save time, in case the text we are searching is not in the list. We check if the list contains the text but we treat the list as a normal string or text instead of a list. If this returns false, then we don’t need to search item by item, which will take more time and return the value “Not found…” as the only element in the listview.
But in case the text is present in the list, then we need to identify the items and create a temporary list with only those items that matches the search. We start by creating a local variable to hold the matching items.
Then we use a For Each Item In List block to go thru the list 1 item at a time and ask if that item has the text we are looking for. If it does, it adds that item to the temporary list.
After the list is all checked, we set the listview elements to those filtered items we found matching the search box.
In this video you can see the whole thing working: