R闪亮 - 最后点击按钮ID

时间:2016-10-21 05:05:45

标签: javascript r shiny observer-pattern action-button

我有多个操作按钮,我想在其上显示不同的选择输入,我想知道最后点击的按钮ID,我该怎么做?当我使用

which(lapply(c(1:10), function(i) { input[[paste0("ActionButton", i)]]}) == TRUE)

它显示了我点击的所有按钮,但是我想知道哪一个是最后一个按钮,以便再次启用前一个按钮。我怎样才能做到这一点?我是新手,并且不确定是否理解所有反应/隔离问题所以我会对任何提示都很有帮助。

3 个答案:

答案 0 :(得分:3)

你可以通过添加JS

来实现 很像

$(document).on('click', '.needed', function () {
                              Shiny.onInputChange('last_btn',this.id);
                             });

示例(如果要控制不是所有btn,请将类needed添加到btn)

 ui <- shinyUI(fluidPage(

  titlePanel("Track last clicked Action button"),
  tags$head(tags$script(HTML("$(document).on('click', '.needed', function () {
                                Shiny.onInputChange('last_btn',this.id);
                             });"))),

  sidebarLayout(
    sidebarPanel(
      actionButton("first", "First",class="needed"),
      actionButton("second", "Second",class="needed"),
      actionButton("third", "Third",class="needed"),
      actionButton("save", "save"),
      selectInput("which_","which_",c("first","second","third"))
    ),

    mainPanel(

      textOutput("lastButtonCliked")
    )
  )
))


server <- shinyServer(function(input, output,session) {
  observeEvent(input$save,{
    updateSelectInput(session,"which_",selected = input$last_btn)
  })
  output$lastButtonCliked=renderText({input$last_btn})

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

答案 1 :(得分:2)

此代码跟踪上次点击的按钮:

   library(shiny)


    ui <- shinyUI(fluidPage(


       titlePanel("Track last clicked Action button"),


       sidebarLayout(
          sidebarPanel(
            actionButton("first", "First"),
            actionButton("second", "Second"),
            actionButton("third", "Third")
          ),

          # Show a plot of the generated distribution
          mainPanel(
             textOutput("lastButtonCliked")
          )
       )
    ))


    server <- shinyServer(function(input, output) {

            rv <- reactiveValues(lastBtn = character())
            observeEvent(input$first, {
                    if (input$first > 0 ) {
                            rv$lastBtn = "first"
                    }
            })
            observeEvent(input$second, {
                    if (input$second > 0 ) {
                            rv$lastBtn = "second"
                    }
            })
            observeEvent(input$third, {
                    if (input$third > 0 ) {
                            rv$lastBtn = "third"
                    }
            })
            output$lastButtonCliked <- renderText({
                    paste("Last button clicked: ", rv$lastBtn)
            })
    })
    # Run the application 
    shinyApp(ui = ui, server = server)

带有许多按钮的lapply版本。归功于@Victorp和this answer

这是代码:

    library("shiny")
    ui <- fluidPage(
            fluidRow(
                    column(
                            width = 6,
                            lapply(
                                    X = 1:5,
                                    FUN = function(i) {
                                            actionButton(inputId = paste0("button", i), label = paste("Button ", i))
                                    }
                            )
                    ),
                    column(
                            width = 6,
                            textOutput("lastButtonCliked")
                    )
            )
    )
    server <- function(input, output){

            rv <- reactiveValues(lastBtn = character())

            lapply(
                    X = 1:6,
                    FUN = function(i){
                            observeEvent(input[[paste0("button", i)]], {
                                    if (input[[paste0("button", i)]] > 0) {
                                            rv$lastBtn = paste0("button", i)    
                                    }
                            })
                    }
            )

            output$lastButtonCliked <- renderText({
                    paste("Last button clicked: ", rv$lastBtn)
            })
    }
    shinyApp(ui = ui, server = server)

答案 2 :(得分:0)

利用每个按钮保持被按下的次数这一事实,还有第三种解决方案。如果您可以监控该次数,那么该次数的任何变化都将表明按下了哪个按钮。

这是一个简短的实现。该页面有三个按钮(具有任意名称):

page <- shinyUI(basicPage(
    actionButton("firstbtn",label="Btn1"),
    actionButton("secondbtn",label="Btn2"),
    actionButton("thirdbtn",label="Btn3"),
    textOutput("result")
))

shinyServer <- function(input, output, session) {
    # the number of clicks on each button is zero at first
    oldBtnClicks <- rep(0,3)

    observeEvent({ obs <<- list(input$firstbtn, input$secondbtn, input$thirdbtn) }, ({
        # store all button state in a list
        BtnState <- obs

        # extract in a vector the number of clicks from each
        newBtnClicks <- rep(0,3)
        for (i in 1:3) 
            newBtnClicks[i] <- if (is.null(BtnState[[i]])) 0 else BtnState[[i]][1]

        # look for the change in the number of clicks
        buttonClicked <- match(1, newBtnClicks - oldBtnClicks)

        # show the button number that was clicked
        output$result <- renderText(expr = buttonClicked)
        
        # update hte number of clicks in the shinyServer environment
        oldBtnClicks <<- newBtnClicks

    }))
}

shinyApp(ui = page, server = shinyServer)

服务器函数首先将每个按钮的点击设置为 0(它们还没有被按下)。然后它设置和观察者寻找任何按钮。被观察的列表可以是任意长度。

当一个事件发生时,按钮状态在一个列表中被检索(与观察到的列表相同)。从该列表中,检索每个子列表的第一个元素(这是该特定按钮的点击次数);如果可以隐藏某些按钮(如我自己的应用程序中的情况),则单击列表为空,因此手动将单击次数设置为 0。

最后,通过取前一个状态和新状态之间的差异,唯一不为零的地方(用match找到)是按钮按下的位置。完成后,不要忘记更新按钮状态列表。等等!

如果您的按钮具有常规名称(例如,BtnX,其中 X 从 1 到 n),那么可能有一种方法可以通过编程方式构建观察列表,而不是手动枚举按钮?