【问题标题】:R shiny - last clicked button idR 闪亮 - 最后点击的按钮 id
【发布时间】:2017-03-03 07:14:53
【问题描述】:

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

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

它显示了所有被点击的按钮,但是我想知道哪个是最后一个,以便再次启用对先前按钮的点击。我怎样才能做到这一点?我是闪亮的新手,不确定是否了解所有反应/隔离问题,所以我会非常感谢任何提示。

【问题讨论】:

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


    【解决方案1】:

    你可以通过添加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)
    

    【讨论】:

    • 非常感谢。您能否解释一下,如何在 selectInput 按钮中保存当前选择的值?假设我有 selectInput 和 actionButton 'Save'。对于每个“保存”单击,我想将 selectInput 中当前选定的值保存为 updateSelectInput,您可以添加吗?如果你愿意,我可以添加新问题。
    • 不完全是,我的意思是,如果 selectInput 我有选择 = c(1:5),selected = 1,如果我将应用选择的值更改为 4 并单击“保存”,则 selectInput 按钮将更新其选择值为 4(所以在“保存”按钮之前最后选择的值)
    • 我真的无法理解你想要什么......可能会更好地提出新问题
    • 请参考问题stackoverflow.com/questions/40171222/…,希望对你更容易理解。
    【解决方案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)
    

    【讨论】:

    • 如果我有100个actionButtons,怎么写这么多observeEvents?假设您的按钮以 'button'+X 开头,其中 X 是从 1 到 100
    【解决方案3】:

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

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

    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),那么可能有一种方法可以通过编程而不是手动枚举按钮来构建观察到的列表?

    【讨论】:

      猜你喜欢
      • 2019-08-14
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 2015-04-26
      • 1970-01-01
      相关资源
      最近更新 更多