在R/Shiny中如何让actionLink输入值为按钮名称而非点击次数?
解决Shiny actionLink返回按钮文本而非点击次数的问题
actionLink(包括actionButton)的默认行为是返回累计点击次数,要让它返回按钮的显示文本,你需要手动通过JavaScript触发自定义输入值更新,下面是两种可行方案:
方案1:原生Shiny + 内嵌JavaScript
直接在actionLink的onclick参数里添加代码,调用Shiny的setInputValue方法,将对应输入ID的值设置为按钮的文本:
library(shiny) library(dplyr) library(purrr) ui <- fluidPage( tags$div( id = "sidebar", class = "sidebar", selectInput( inputId = "custom_select", label = "Clubs", choices = names(mtcars), selectize = F, size = 5, width = "300px" ), div( # 给每个actionLink添加onclick事件,设置输入值为按钮文本 names(mtcars) %>% map(~ actionLink( inputId = .x, label = .x, onclick = sprintf("Shiny.setInputValue('%s', '%s');", .x, .x) )) ) ), h1(htmlOutput(outputId = 'title')), h1(htmlOutput(outputId = 'title2')) ) server <- function(input, output, session) { output$title <- renderUI({ input$custom_select }) output$title2 <- renderUI({ # 现在点击第一个按钮,这里会返回按钮的文本(比如"mpg")而非点击次数 input[[names(mtcars)[1]]] }) } shinyApp(ui, server)
方案2:使用shinyjs包简化操作
如果需要更灵活的控制,可以用shinyjs包来监听点击事件并更新输入值:
library(shiny) library(dplyr) library(purrr) library(shinyjs) ui <- fluidPage( useShinyjs(), # 初始化shinyjs tags$div( id = "sidebar", class = "sidebar", selectInput( inputId = "custom_select", label = "Clubs", choices = names(mtcars), selectize = F, size = 5, width = "300px" ), div( names(mtcars) %>% map(~ actionLink(inputId = .x, label = .x)) ) ), h1(htmlOutput(outputId = 'title')), h1(htmlOutput(outputId = 'title2')) ) server <- function(input, output, session) { output$title <- renderUI({ input$custom_select }) # 给每个actionLink添加点击监听 walk(names(mtcars), function(btn_id) { onclick(btn_id, { # 设置输入值为按钮的文本 shinyjs::runjs(sprintf("Shiny.setInputValue('%s', '%s');", btn_id, btn_id)) }) }) output$title2 <- renderUI({ input[[names(mtcars)[1]]] }) } shinyApp(ui, server)
原理说明
两种方案核心都是调用Shiny.setInputValue()方法,手动覆盖actionLink默认的点击次数输入值,将其替换为按钮的显示文本。这样在server端读取input[[按钮ID]]时,就能得到和selectInput一样的选项名称效果。
内容的提问来源于stack exchange,提问作者JohnBones JohnBones
相关产品推荐
相关产品推荐

