title: Using buttons with @interact
body: <p>EDIT: Re-written for clarity Sept. 8 2019 1330 UTC</p>
  <p>In a Jupyter notebook, I want to explore dates chosen by a date picker widget. The way of doing this I already knew was to use <code>@interact</code> and make the datepicker widget an argument to the interact function, like this:</p>
  <pre><code>def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date')):
  </code></pre>
  <p>But I need buttons &quot;Next Holiday&quot; and &quot;Previous Holiday&quot; to move from the selected date to the next holiday. I already have an array of holidays stored as datetime.datetime objects.</p>
  <p>So I tried adding the button objects to the arguments to the <code>@interact</code> function, like this:</p>
  <pre><code>@interact
  
  def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date'),
                   prev_button = widgets.Button(description=&quot;Prev Holiday&quot;),
                   next_button = widgets.Button(description=&quot;Next Holiday&quot;)):
  </code></pre>
  <p>That didn't work. Error says the line with the button widget &quot;cannot be transformed into a widget&quot;. Hmm, I thought it already was a widget...</p>
  <p>My next thought was to put the button code inside the function, rather than as an argument:</p>
  <pre><code>def explore_dates(d1=widgets.DatePicker(value=pd.to_datetime('2018-07-10', format='%Y-%m-%d'), description='Date')):
  
  prev_button = widgets.Button(description=&quot;Prev Holiday&quot;)
  next_button = widgets.Button(description=&quot;Next Holiday&quot;)
  prev_button.on_click(prev_holiday_callback)
  next_button.on_click(next_holiday_callback)
  box=widgets.HBox([prev_button,next_button])
  display(box)
  </code></pre>
  <p>That got the buttons on the screen and I can push them and my callback routines run. But when the datepicker is set up (per above) as an argument to <code>@interact</code>, it appears that it is no longer possible to reset its date using its .value attribute. (See code above) trying to set d1.value results in an error.</p>
  <p>I suppose I could get rid of <code>@interact</code> entirely, and just put the datepicker and both buttons into the mainline code. <strong>But I don't know how to reproduce the function of <code>@interact</code> at that point</strong>. Short of an infinite loop that waits for a click or observe event to come from one of the widgets, other than <code>@interact</code>, I don't know how to tell Python/Jupyter &quot;hey, just chill out until a widget event causes a callback to wake up the code&quot;.</p>
  <p>In case it's helpful, here are my callback routines for the buttons.</p>
  <pre><code>def button_click_common():
      global button_flag
      global button_date
      global holidays
      
      for i in range(len(holidays)):
          if(holidays[i]&lt;button_date): # haven't passed the prior holiday yet
              continue
          
          # Now holidays[i] has to either be same as or after button_date
          
          prior_holiday = i-1 # prior holiday is the one we just passed that was prior
          next_holiday = i    # assume at first we are between dates
          if holidays[i]==button_date:
              next_holiday +=1        # if we were already on a holiday date, next becomes the following one
          return prior_holiday, next_holiday
  
  def prev_holiday_callback(_):
      global button_flag
      global button_date
      global holidays
      
      prior_holiday,_ = button_click_common()
      
      button_date = holidays[prior_holiday]
      button_flag = True
      
  def next_holiday_callback(_):
      global button_flag
      global button_date
      global holidays
      
      _,next_holiday = button_click_common()
      
      button_date = holidays[next_holiday]    
      button_flag = True  
  </code></pre>
  <p>The idea here is that the callback updates button_date to the date of the next holiday, and sets the flag button_flag. Then code (not shown) in the explore_dates function was going to test the flag. But I can't figure out how to update the datepicker widget with the new date when it is defined as an argument to the <code>@interact</code> function.</p>
  <p>Feels like I'm going about this wrong. Any advice or guidance welcome...</p>
  <p>Thanks in advance!</p>