1

I've been working with R Shiny, and I'm having a bit of a problem. I want to create a user flow for the date range input where:

  1. if the user inputs a start date after the end date, the end date automatically follows and mimics the start date.

  2. if the user inputs an end date before the start date, the start date automatically follows and mimics the end date.

I thought of trying to use an observeEvent() for the separate inputs like below:

#inputId of dateRangeInput = dateRange

#start date
observeEvent(input$dateRange[1], {
   - logic - 
})

#end date
observeEvent(input$dateRange[2], {
   - logic - 
})

All the above did is run both observe events regardless of whether I changed the input for the start date or end date, so I know my logic or understanding of the functions are probably flawed here.

Is there a way of doing something similar to what I was trying to accomplish or should I be trying a different approach?

Thank you in advance for your time!

  • It would help if you could provide a more complete [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) to make it clear what your UI looks like and what behavior you want to happen on the server. The reactive "thing" is `input$dateRange`, when the value of that input changes, the entire vector is updated, not just one element in the vector. – MrFlick Jul 09 '21 at 21:38
  • 4
    I think what you'll need to do is save the current values within a `reactiveVal` and then check when `input$dateRange` changes to see which of the two ends has changed, and only react to those. It's neither direct nor elegant, but it can be done. – r2evans Jul 09 '21 at 21:45
  • Can you provide `ui` and `server` code required for the question to be completely reproducible along with necessary data if required? – Ronak Shah Jul 10 '21 at 03:04
  • Also be aware that the `value` of the slider needs to be valid at all times during the update. Otherwise a `NULL` will appear. My answer [here](https://stackoverflow.com/questions/62864777/default-updatedateinput-doesnt-work-going-forward/62870806#62870806) may be relevant. @r2evans has identified the main issue and its solution. – Limey Jul 11 '21 at 08:12

1 Answers1

0

Thanks to everyone for chiming in with their input. I realize now that I could have put a better, reproducible example up to help you guys get a better idea of my problem, so sorry about that - I will keep this in mind for future posts (shoutout to @MrFlick for the great link to a post about making one!)

I ended up taking @r2evans comment into account and was able to come up with a solution based off of it! I'm fairly new to Stackoverflow so not sure if I can mark a comment as the answer, but thank you so much @r2evans!

Below was the solution that I used in my server function to help me get the functionality I wanted:

curr_date <- shiny::reactiveValues(start=format(Sys.Date(),"%Y-%m-%d"), end=format(Sys.Date(), "%Y-%m-%d"))
  
shiny::observeEvent(input$reports_date_range, {
    
    dates <- input$reports_date_range
    
    # if start date changed 
    if (dates[1] != curr_date$start) {
      
      # if start date is after end date, have end date follow and update curr_date
      if(dates[1] > curr_date$end) {
        updateDateRangeInput(session, "reports_date_range", start = dates[1], end = dates[1])
        curr_date$start <- dates[1]
        curr_date$end <- dates[1]
      } else { # if start date is equal to or before end date, update curr_date$start
        curr_date$start <- dates[1]
      }
      
    } else if (dates[2] != curr_date$end) { # if end date changed
      
        # if end date is before start date, have start date follow end date
        if(dates[2] < curr_date$start) {
          updateDateRangeInput(session, "reports_date_range", start = dates[2], end = dates[2])
          curr_date$start <- dates[2]
          curr_date$end <- dates[2]
        } else { # if end date is equal to or after the start date, update curr_date$end
          curr_date$end <- dates[2]
        }
      
    }
  })

Basically, the reactive values in curr_date hold the current date the inputs are defaulted to at the beginning, and are updated to what the inputs become every time they are changed.

In the server logic, I check if there is a mismatch between the date inputted by the user, and the historic value I have for the input in curr_date to figure out which of the two dates (start or end) were changed by the user. Then, it's a simple matter of applying the correct code based on what the user did!

Thank you once again everyone and let me know if there is anything you guys can spot to make this solution better, I will update if there are any findings!