title: ipywidgets, problem using a Text widget to filter options in a Select widget with automatic updates/ real-time interaction
body: <p>I'm trying to use ipywidgets for the first time to make an interactive browser in Jupyter Notebooks of Census data using the census module. In general I'm having difficulty learning the widget library. My plan is to use the Text widget to enter a search term that will then filter the available census 'concepts' or table options (example: &quot;Means of transportation to work&quot;) in a Selection or SelectMultiple widget. The selections made will then filter and show available data variables / columns for that census 'concept' or table (example: &quot;car&quot;, &quot;truck&quot;, &quot;bus&quot;, &quot;bike&quot;, &quot;walk&quot;)</p>
  <p>For reference, this first code block is what I got to work in a normal Jupyter Notebook with no widgets (at the bottom is the ipywidget attempt I'm having trouble with). I'm just starting to explore widgets and don't know anyone with experience with them. Any assistance is greatly appreciated!</p>
  <p>*Note, running my code would require a census api key from census.gov/data/developers.html, the &quot;Request a KEY&quot; option on the left side menu, and change the ckey=&quot;&quot; variable in the code below to your key. Keys are free, as it is publicly available government data.</p>
  <pre><code>#This section works for me as standalone code, not using ipywidgets
  #Show all concepts to get an idea of search phrases to use
  concepts_all = list([n for n in sorted(list([f&quot;{t['description']}&quot; for t in c.acs5.tables()]))]);
  #This is a VERY long list, so I commented out printing it
  #[print(c) for c in concepts_all]
  
  #Apply a search phrase and limit options accordingly
  concept_description_search_phrase = &quot;Means of transportation to work by travel&quot;
  [print(f&quot;{table['name']}: {table['description']}&quot;) for table in c.acs5.tables() if concept_description_search_phrase.lower() in table['description'].lower()]
  
  #From the filtered options, chose one specific one to search, and display available data for it
  concept_full_description = 'MEANS OF TRANSPORTATION TO WORK BY TRAVEL TIME TO WORK'
  variable_filter_phrase = 'bicycle'
  
  df = [pd.read_json(table['variables']) for table in c.acs5.tables() if table['description'] == concept_full_description][0]
  
  acs_variable_names_list = [row.name for n,row in df.iterrows() 
   if variable_filter_phrase.lower() in row['variables']['label'].lower() 
   and 'Annotation' not in row['variables']['label'] 
   and 'Margin of Error' not in row['variables']['label']]
  
  acs_variable_names_list
  # This is the final list I want out from a ipywidgets based workflow
  # Which are variable columns, (ex: number of people in each census block group that 
  # have a 10, 15, 30, 45, 60+ minute commute by bicycle
  ########################################################
  </code></pre>
  <p>I'm having trouble getting the ipywidgets to work properly, where the Text box will interactively filter the available options in the Selection menu. I can only get it to work on a default value for the Text widget, but not off of the interactive menu. I'm basically going for the effect of the Combobox widget, but with the option to select more than one item if desired, and still see all the available options after a selection is made (so I'm thinking to use a Text and Select widget together instead of Combobox). This is my attempt so far:</p>
  <pre><code>out = widgets.Output()
  display(out)
  
  search_phrase = widgets.Text(
      value = 'transportation',
      layout = widgets.Layout(width = '900px')
  )
  
  select_multiple = widgets.SelectMultiple(
          options = [n for n in concepts_all if search_phrase.value.lower() in n.lower()],
          layout = widgets.Layout(width='900px',height='250px'),
          ensure_option = True,
          disabled=False
  )
  
  
  def search_change(change):
      output.clear_output()
      display(search_phrase)
      with output:
          if change.new == '':
              print('new search')
              return search_phrase.value
          else:
              print('same search')
              return search_phrase.value
                     
  display(search_phrase)   
  display(select_multiple)
  #Issue here with getting the search_phrase to properly filter options in select_multiple
  
  
  #
  concept_full_description = select_multiple.value[0]  #Using Widgets
  variable_filter_phrase = widgets.Text(value = 'bicy')
  
  display(variable_filter_phrase) #Issue, this text box won't automatically filter the output
                                  #it is only filtering by the default value
  
  df = [pd.read_json(table['variables']) for table in c.acs5.tables() if table['description'] == concept_full_description][0]
  
  acs_variable_names_list = [row.name for n,row in df.iterrows() 
   if variable_filter_phrase.value.lower() in row['variables']['label'].lower() 
   and 'Annotation' not in row['variables']['label'] 
   and 'Margin of Error' not in row['variables']['label']] #print(row.name,&quot;: &quot;,row['variables']['label'])
  
  acs_variable_names_list
  #This is the desired output list that will go into later workflows
  </code></pre>
  <p>I think I'm doing something wrong either in use of the .observe(), .interact(), or output /clear_output process. I'm just learning the ipywidgets and am even having trouble getting this to work in a basic example trying to follow the ipywidgets.readthedocs.io documentation.</p>