1

Long-time lurker on the site, first-time poster. I have found threads that kind of address my issue but only partially. Here's the problem.

I have a very simple website consisting of some text and two dropdown boxes. I'm using Python 3.4 with Flask on the server side and some simple HTML on the client side with a bit of embedded JavaScript. The purpose of the first dropdown is to filter the second.

The first list is coded as:

<select id = "myState" name = "myState">
  <option selected = "selected">Select state...</option>
  <option value = "GA">Georgia</option>
  <option value = "NC">North Carolina</option>
  <option value = "TN">Tennessee</option>
  <option value = "VA">Virginia</option>
  <option value = "MD">Maryland</option>
  <option value = "PA">Pennsylvania</option>
  <option value = "NJ">New Jersey</option>
  <option value = "NY">New York</option>
  <option value = "CT">Connecticut</option>
  <option value = "MA">Massachusetts</option>
  <option value = "VT">Vermont</option>
  <option value = "NH">New Hampshire</option>
  <option value = "ME">Maine</option>
</select>

Meanwhile, the second list has 285 entries and gets coded via a Flask list variable like this:

<select id = "myShelter" name = "myShelter" onchange = "window.location.href = '/forecast/loc_id=' + document.getElementById('myShelter').value;">
  <option selected = "selected" disabled = "disabled" class = "labelText">Select location...</option>
  {% for o in shelter_list %}
  <option value = "{{ o[0] }}" class = "{{ o[4] }}" {{ o[3] }}>{{ o[1] }}</option>
  {% endfor %}
</select>

The {{ o[4] }} is what contains the state abbreviations, so that when a selection is made from the first list to filter the second down to whatever was selected, the following JavaScript uses the class of the option list to do the filtering:

<script>
  $(document).ready(function() {
    var allLocations = $('#myShelter option')
    $(myState).change(function() {
      var currState = document.getElementById("myState").value;
      var currStateLocations = allLocations.filter('.' + currState);
      $('#myShelter option').remove();
      $.each(currStateLocations, function (i, j) {
        $(j).appendTo('#myShelter');
      });
    });
  });
</script>

The JavaScript just pulls all 285 entries in the second list into a variable, clears the list, and uses the selection from the first list to filter the 285 entries down and put just the filtered items back in.

This works fine the first time around; however, with any subsequent selection from the first list, it doesn't work because $('#myShelter option') now contains just the filtered list. If you selected "North Carolina" the first time and then wanted "Virginia", it doesn't work because the list now contains just "North Carolina" entries.

What would be the best way to approach this? I would like to pull the full list into the JavaScript some other way so that it isn't dependent on what is already in the dropdown, but I am not sure how to do it. Perhaps a Flask {{ }} variable? Thanks so much.

dda
  • 6,030
  • 2
  • 25
  • 34
Pat Jones
  • 876
  • 8
  • 18

1 Answers1

0

Load the 285 entries into a global JS variable, and when you build your second dropdown box, you filter it against that global variable, keeping it intact.

dda
  • 6,030
  • 2
  • 25
  • 34
  • Thanks for the response, but I don't understand how making the variable global changes anything. I have no real experience with JavaScript, but it seems to me that as long as I keep defining the variable as `$('#myShelter option')` then I will keep getting the wrong behavior regardless of scope, yes? – Pat Jones Nov 28 '15 at 04:21
  • If you keep a copy of the 285 entries in a global variable, you can reset the second dropdown to the full 285 before filtering. – dda Nov 28 '15 at 04:51
  • The problem is that making a selection from the second drop down list causes the page to reload, at which point I lose the state of the global variable. The post [Global Variable usage on page reload](http://stackoverflow.com/questions/29986657/global-variable-usage-on-page-reload) has a lot of useful suggestions for how to avoid this problem. I ended up creating a third, hidden drop down list that is always populated with the full list of entries. This seems very hackish but it's all I can think of. – Pat Jones Nov 28 '15 at 06:39