Following this tutorial: https://book.javascript-for-r.com/shiny-cookies.html, I tried to expand it to have two separate input fields
the script.js is given by:
// set a cookie
Cookies.set('name', 'value')
// get cookies
Cookies.get();
// remove a cookie
Cookies.remove('name');
// script.js
function getCookies(){
var res = Cookies.get();
Shiny.setInputValue('cookies', res);
}
// script.js
Shiny.addCustomMessageHandler('cookie-set', function(msg){
Cookies.set(msg.name, msg.value);
getCookies();
})
Shiny.addCustomMessageHandler('cookie-remove', function(msg){
Cookies.remove(msg.name);
getCookies();
})
// script.js
$(document).on('shiny:connected', function(ev){
getCookies();
})
the app.R (as you can see as of now I have everything every button twice, once for the first name, one for the last name)
What does not work: If the input field for the first name is empty and I specify only the last name, then the last name is set for both the first name as well as the last name. Similarly if I set both names and remove only the first name, then the last name will also be assigned to the first name. however this does not happen the other way round, i.e. if I at first specify the first name, then only the first name will not be also assigned to the last name.
What I would ultimately like to achieve: is that I can have only one remove and save button which would save/remove both names simultaneosly. (if both were given in the first place)
app.R
library(shiny)
addResourcePath("www", "www")
ui <- fluidPage(
tags$head(
tags$script(
src = paste0(
"https://cdn.jsdelivr.net/npm/js-cookie@rc/",
"dist/js.cookie.min.js"
)
),
tags$script(src = "www/script.js")
),
textInput("name_set", "What is your first name?"),
textInput("name_set2", "What is your last name?"),
actionButton("save", "Save first name", style="background-color: cyan;"),
actionButton("save2", "Save last name", style="background-color: pink;"),
actionButton("remove", "remove first name", style="background-color: cyan;"),
actionButton("remove2", "remove last name", style="background-color: pink;"),
uiOutput("name_get"),
uiOutput("name_get2")
)
server <- function(input, output, session){
# save
observeEvent(input$save, {
msg <- list(
name = "name", value = input$name_set
)
if(input$name_set != "")
session$sendCustomMessage("cookie-set", msg)
})
observeEvent(input$save2, {
msg2 <- list(
name = "name2", value = input$name_set2
)
if(input$name_set2 != "")
session$sendCustomMessage("cookie-set", msg2)
})
observeEvent(input$save, {
msg <- list(
name = "name", value = input$name_set
)
if(input$name_set != "")
session$sendCustomMessage("cookie-set", msg)
})
# delete
observeEvent(input$remove, {
msg <- list(name ="name")
session$sendCustomMessage("cookie-remove", msg)
})
observeEvent(input$remove2, {
msg <- list(name ="name2")
session$sendCustomMessage("cookie-remove", msg)
})
# output if cookie is specified
output$name_get <- renderUI({
if(!is.null(input$cookies$name))
h3("Your first name:", input$cookies$name)
else
h3("What is your first name?")
})
output$name_get2 <- renderUI({
if(!is.null(input$cookies$name2))
h3("Your last name:", input$cookies$name2)
else
h3("What is your last name?")
})
}
shinyApp(ui, server)
CodePudding user response:
Not sure to understand but I suspect this is due to the partial matching of the extraction with $
:
> L <- list(name2 = "test")
> is.null(L$name)
FALSE
If my guess if good, you have to use the double brackets to subset:
is.null(L[["name"]])
TRUE