In this lesson, we'll add various inputs that allow a user to filter a collection of data using different sets of data to search through.
We'll take advantage of Stimulus targets
to make it simple to find which collection the user wants to search for. Stimulus also provides a nice way to get all targets
of a certain name as an array. We'll take a look at how that makes life easy when need to iterate over a collection of DOM nodes.
Damon Bauer: [0:01] I want to update this HTML so that a user can search by more than just one input field. I've just pasted a bunch of HTML. The first thing that we have is a select box that allows the user to choose which part of the data that they want to search for.
[0:18] Here, you see name is the default selection, but you can choose amount or category, which corresponds to the amount or the category in our transaction. Each one of those possible options is displayed here.
[0:31] The other thing to note on these inputs is they have a data target of filter, and then when they change, the updateFilter method is called. We need to do a few to our stimulus controller. The first is adding a function called updateFilterType that's run when a user selects which category they want to search.
[0:51] The other thing we'll have to add is a field target so our controller knows how to find this element. One more thing we'll add is a filter target so we know which inputs to hide and which one to show.
[1:09] Our action always takes an event as an argument. The first thing we're going to do is iterate over all of those filters. Stimulus provides this out of the box. If there are multiple nodes that have the same target on them, you can just pluralize the target.
[1:26] In this case, filterTarget would give us one of the filters. filterTargets gives all of them in an array that we can iterate over. Within this iterator, we're just going to hide all the filters to start. Let's see what that does.
[1:44] If I choose a different filter, you'll see all of our inputs are missing because we've added the useHidden class. Now, what we need to do is find the one that the user choose and display it by removing that class.
[2:00] We're going to look for an element that has a name that's equal to the value of the chosen option in the select drop-down. If the user chooses amount, the value that we get from our updateFilterType action will be amount, and that will correspond to the name attribute of this input, thus we can show that input.
[2:25] Within our query selector, we'll look for that name and we can remove the class. Then I pick category, and I've got another select box with all my categories listed. That's working perfectly. While we're here, let's replace this manual arrayFrom look up.
[2:54] Now, this won't work yet because we haven't define an itemTarget in our staticTargets array. Let's do that. Now, all that's left to do is add the dataTarget item to each transaction in our collection.
[3:15] The last thing we need to do in each one of these transactions is set the correct data field name attribute that corresponds with these possible options in our select drop-down. Let's refresh our page, and I'll pick a category. I'll select grocery.
[3:34] Nothing seems to be working, so let's take a look at what the problem is. Our selected option value is groceries with a lowercase g, but the data field category is displayed in an uppercase G. So there's a problem with our code that is run when the updateFilter method is called.
[3:55] If we look at updateFilter, what this is doing is getting the value of the field -- in this case, lowercase groceries -- and it's comparing the text content of each one of these transactions to the uppercase Groceries. Since there's one uppercase and a lowercase, there's a problem there.
[4:20] By adding the toLowercase method to both the label in the transaction as well as the selected value option, we remove the case-sensitive nature of that and make it case-insensitive. Now, our select box is working properly.