tuicalendr icon indicating copy to clipboard operation
tuicalendr copied to clipboard

How to Edit a Schedule Entry in Shiny

Open KoderKow opened this issue 4 years ago • 3 comments

Hello, I am interested in how to edit an entry in a weekly calendar. Options for doing this include:

  • Click and drag schedule entry to a different day
  • Click and drag to a different time during the same day
  • Click and drag the bottom of the entry to extend the time
  • Using the edit button on a selected entry

When I use the set_events() function to console.log(event) I can see the data for the destination where I moved the data in the dev console. I am new to this area of shiny so I am unsure how to solve this myself; how do I get the data of the edited object (using on of the methods mentioned), send it to R, update the calendar, and have that new data accessible for sending to a DT or saving the data as a csv?

I will provide a script that I am using for a weekly calendar view and chunks from your examples in the repo. With the actual data I cannot share, I have employee entries populating this calendar, however, the group leader may choose to edit the entries that better fit the team working on the project at hand.

library(shiny)
library(tuicalendr)

ui <- fluidPage(
    textOutput("text1"),
    tableOutput("show_inputs"),
    calendarOutput("continutiy_tab_calendar")
)

server <- function(input, output) {

    output$continutiy_tab_calendar <- renderCalendar({

        ## Create Calendar
        cal <- calendar(
            defaultDate = Sys.Date(),
            useNav = TRUE,
            readOnly = FALSE
        ) %>%
            set_month_options(narrowWeekend = TRUE)

        ## Example from README
        cal %>%
            add_schedule(
                calendarId = "courses",
                title = "R - introduction",
                body = "What is R?",
                start = sprintf("%s 08:00:00", Sys.Date()),
                end = sprintf("%s 12:30:00", Sys.Date()),
                category = "time"
            ) %>%
            add_schedule(
                calendarId = "courses",
                title = "R - Stats",
                body = "Stats with R",
                start = sprintf("%s 10:00:00", Sys.Date() + 1),
                end = sprintf("%s 14:00:00", Sys.Date() + 1),
                category = "time"
            ) %>%
            set_events(
                beforeUpdateSchedule = JS("function(event) {console.log(event);}")
            )
    })
}

# Run the application
shinyApp(ui = ui, server = server)

I appreciate the example for creating a schedule entry, that solves one part of my project I am working on! :)

KoderKow avatar Apr 06 '20 16:04 KoderKow

Hello @KoderKow ,

Thanks for openning the issue. I made some changes in the code to make possible to edit schedules, so please re-install the package with :

remotes::install_github("dreamRs/tuicalendr")

After that you can try the following example where you can create and edit schedules interactively :

library(shiny)
library(tuicalendr)

ui <- fluidPage(
  tags$h2("Create and edit schedule"),
  fluidRow(
    column(
      width = 9,
      calendarOutput("my_calendar")
    ),
    column(
      width = 3,
      uiOutput("schedule_update")
    )
  )
)

server <- function(input, output) {
  
  output$my_calendar <- renderCalendar({
    cal <- calendar(
      defaultDate = Sys.Date(),
      useNav = TRUE,
      readOnly = FALSE,
      useCreationPopup = TRUE
    ) %>%
      set_month_options(narrowWeekend = TRUE) %>%
      add_schedule(
        id = "r_intro",
        calendarId = "courses",
        title = "R - introduction",
        body = "What is R?",
        start = paste(Sys.Date(), "08:00:00"),
        end = paste(Sys.Date(), "12:30:00"),
        category = "time"
      )
  })
  
  output$schedule_update <- renderUI({
    if (!is.null(input$my_calendar_update)) {
      changes <- input$my_calendar_update$changes
      tags$div(
        "Schedule",
        tags$b(input$my_calendar_update$schedule$id),
        "have been updated with:",
        tags$ul(
          lapply(
            seq_along(changes),
            function(i) {
              tags$li(
                tags$b(names(changes)[i], ":"),
                changes[[i]]
              )
            }
          )
        )
      )
    }
  })
  
  observeEvent(input$my_calendar_add, {
    cal_proxy_create(
      proxy = "my_calendar",
      .list = input$my_calendar_add
    )
  })
  
  observeEvent(input$my_calendar_update, {
    cal_proxy_update(
      proxy = "my_calendar",
      .list = input$my_calendar_update
    )
  })
  
}

# Run the application
shinyApp(ui = ui, server = server)

Careful I changed the name of shiny input generated by the package ! (in example I send you earlier there was an input input$<ID>_schedule_add now it's just input$<ID>_add)

I plan to write a vignette to explain usage in shiny apps, but been a little busy. Don't hesitate to open issue, or share what can be better in the package.

Victor

pvictor avatar Apr 06 '20 18:04 pvictor

@pvictor Wow thank you so much for doing the updates and for providing an example! This is so cool!

I have it all working on my machine. My last remaining question is what is the most efficient way of presenting the data in either a data table within the shiny app or either saving the new data or rewriting.

I currently have 1000+ schedule entries on a calendar. I tried looking into the different input$... available but I could not find a way to extract the data from the calendar. I looked at str(cal) and I can see the data. How do I navigate to that?

KoderKow avatar Apr 07 '20 18:04 KoderKow

There's currently no method to retrieve all schedules from calendar, in my mind it was best to add entries when input$my_calendar_add is triggered, and update entries when input$my_calendar_update is triggered, like that you control what users add or modify in your calendar.

pvictor avatar Apr 10 '20 15:04 pvictor