How to filter a second dropdown based on results from first dropdown

Hi,
I’m trying to figure out how not show some options in a second dropdown based on the first dropdown. The situation is a listing of high schools in a few different states. You pick the state in the first dropdown, then are shown only the schools in that state in the second dropdown.

Originally, I had each option set up with a class corresponding with the state abbreviation, then I’d use jquery to show/hide the options based on the state selection, which (when hidden) applies a display:none property.

This doesn’t work with Select2, so I was wondering if there is a way to do this, hiding certain options based on a class that is applied to them?

Thanks for your help.

You need to do two things:

  1. On the “state” Select2, attach an event handler that fires on the “change” event. The event handler should store the current selection (the selected state) in a variable that is accessible by…
  2. the custom results templating function you will add to the “schools” Select2. This function uses the selected state (from the variable I mentioned above) to decide whether to show (return the item text) or hide (return null) each item in the dropdown.
1 Like

That’s a lot of help, thanks.

If it’s not too much trouble, I have a related question.
I’ve got it working correctly so that I can access the item text for display, but I can’t seem to get at the item’s class. The object is “school”, so I can get to the text using school.text, which works fine.
In the console in my browser, I can see that the property that I’m looking for under className, so I assumed school.className would get me that, however when I send that to the log, I get “undefined” (when it should be a state abbreviation…IL, IA, MO, etc.).

Is there something special I need to do to be able to access that info (the class is what I would need to use to do the comparison for displaying or not).

Thanks.

The HTMLElement class attribute is not appropriate for storing application data; it is meant for presentational use only. I understand it was useful to use it in your previous CSS-based solution, but even in that case there are other, more appropriate attributes (e.g., data-* attributes) which are “visible” to CSS. That said, depending on how you’re providing the State data to Select2, I have a couple of suggestions.

If you’ve got the state selections are hard-coded in your HTML as a <select> element with child <option> elements for each state, then why not use the standard value attribute (e.g., <option value="CA">California</option>)? The value of this attribute will be assigned to the “id” property of Select2’s internal item representation, and that property is directly accessible on the object representing the user’s selection.
If, for whatever reason, you can’t (or don’t want to) use the value attribute, you can use a data-* attribute (e.g., <option data-state-abbr="CA">California</option>). The object that represents the user’s selection contains a property called “element” which holds a reference to the HTMLOption object (i.e, the <option> element) that the user’s selection represents. You can use standard methods on that object to access those data attributes.

If you are providing the State data as a Select2 JavaScript data array, you can include whatever additional data fields you need in your individual item objects; those objects must contain “id” and “text” properties, but they can also contain any other properties you need, and those properties are directly accessible on the object representing the user’s selection.

I hope this helps. If not, it would be helpful if I could see your HTML and JavaScript code (perhaps you could put your page up on codepen.io, jsfiddle.net or another similar site).

1 Like

Awesome, that helped a lot.

I was able to apply data-* attributes to the options and eventually get that to work. Your suggestion worked fine, it was my own unfamiliarity with javascript that caused the “eventually” part…lots of trying different things and beating my head against the problem. But it works now…probably not “pretty”…but it works.

Thanks again for your help.

You’re welcome. Frankly, I hoped my suggestion would challenge you a bit. The best way to learn something is to do it; and sometimes banging your head against the problem is even better :grinning: (I’ve certainly learned that recently!).

Good luck with your project!