R Shiny: заставить новую кнопку действия появляться, если предыдущий ввод не пустой, и исчезать, если она - PullRequest
0 голосов
/ 05 апреля 2019

В идеале мое мини-приложение должно работать следующим образом:

  1. Пользователь выбирает имя из списка ранее существующих имен;

  2. Если имяпользователь имеет в виду, что его нет в списке; для ввода нового имени появляется открытое окно;

  3. Пользователь нажимает кнопку действия "Показать выбранное имя" илюбое имя, выбранное или введенное, отображается на главной панели;

  4. Другая кнопка действия «Показать количество символов» появляется только после нажатия кнопки «Показать выбранное имя» - но только если имявыбирается из списка ИЛИ, если открытое поле для предоставленного пользователем имени не является пустым.Если пользователь нажимает эту новую кнопку, он показывает количество символов в выбранном имени.

Я не могу заставить работать последний пункт: как я могу заставить ТОЛЬКО вторую кнопку появляться, есливыбранное (или напечатанное) имя НЕ пустое и исчезает, как только пользователь удаляет все в открытом окне?

Большое спасибо!Ниже мой код:

library(shiny)
ui = shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      selectInput("name_fromlist", "Select a name", choices = ""),
      uiOutput("open_end")
    ),
    mainPanel(
      textOutput("name_final"), br(),
      actionButton("button1", label = "Show chosen name"), br(),
      textOutput('final_name'),
      uiOutput("second_button")  # it should show number of characters in the chosen name
    )
  )
))

server = shinyServer(function(input, output, session) {

  # A vector of pre-existing names:
  mynames <- c("John", "Mary", "Jim", "Bill")

  # Pull-down to select one of the names:
  observe({
    updateSelectInput(session, inputId = "name_fromlist", label = "Select a name:", 
                      choices = c(mynames, "Name not on our list"))
  })

  # Open end box to appear only if the name the user wants to enter is not on the list:
  output$open_end <- renderUI({
    if (!input$name_fromlist == 'Name not on our list') return(NULL) else {
      textInput("Not_on_list", "If the name you want is not on our list, type it here:")
    }
  })

  # button 1 shows the name selected or typed:
  observeEvent(input$button1, {
    if (input$name_fromlist == 'Name not on our list') selected_name <- input$Not_on_list else {
      selected_name <- input$name_fromlist
    }
    output$final_name <- renderText({paste("Chosen name:  ", selected_name)})
  })

  # # This part is not working:
  # observe({
  #   if (input$name_fromlist == 'Name not on our list' & input$Not_on_list == '') renderUI({NULL}) else {
  #     output$add_user <- renderUI({
  #       actionButton("second_button", label = "Show number of characters")
  #     })
  #   } # end of else
  # }) # end of observe
})

shinyApp(ui = ui, server = server)

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Похоже, я нашел решение - без условной панели. Обратите внимание, что вторая кнопка исчезает, если открытое окно пусто:

library(shiny)

# A vector of pre-existing names:
mynames <- c("John", "Mary", "Jim", "Bill")

ui = shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      selectInput("name_fromlist", "Select a name", choices = c(mynames, "Name not on our list")),
      uiOutput("open_end")
    ),
    mainPanel(
      textOutput("name_final"), br(),
      actionButton("button1", label = "Show chosen name"), 
      br(),
      textOutput('final_name'), br(),
      uiOutput("button2"),
      br(),
      # Display number of characters for the chosen names
      conditionalPanel(condition = " input.name_fromlist != 'Name not on our list' |
                       input.Not_on_list != '' ", 
                       textOutput("no_of_char")
      )      
    )
  )
))

server = shinyServer(function(input, output, session) {

  # Open end box to appear only if the name the user wants to enter is not on the list:
  output$open_end <- renderUI({
    if (!input$name_fromlist == 'Name not on our list') return(NULL) else {
      textInput("Not_on_list", "If the name you want is not on our list, type it here:")
    }
  })

  # button 1 shows the name selected or typed:
  observeEvent(input$button1, {
    if (input$name_fromlist == 'Name not on our list') selected_name <- input$Not_on_list else {
      selected_name <- input$name_fromlist
    }
    output$final_name <- renderText({paste("Chosen name:  ", selected_name)})
    output$button2 <- renderUI({
      actionButton("button2", label = "Show number of characters")
    })
  })

  # This observe allows the second button to disappear:
  observe({
    if (!is.null(input$Not_on_list)) {
      if (input$name_fromlist == 'Name not on our list' & input$Not_on_list == '') {
        output$button2 <- renderUI({NULL})
      }
    }
  })

  #### observeEvent for Second Button
  ## This is to display number of charactesr based on chosen/typed names
  observeEvent(input$button2, {
    if (input$name_fromlist == "Name not on our list") {
      selected_name <- input$Not_on_list
    } else {
      selected_name <- input$name_fromlist  
    }

    output$no_of_char <- renderText({paste("Number of Characters:  ", nchar(selected_name))})
  })

})


shinyApp(ui = ui, server = server)
0 голосов
/ 05 апреля 2019

Вы можете попробовать использовать conditionalPanel, и вам нужно будет создать еще один observeEvent для управления этой второй кнопкой.

library(shiny)
ui = shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      selectInput("name_fromlist", "Select a name", choices = ""),
      uiOutput("open_end")
    ),
    mainPanel(
      textOutput("name_final"), br(),
      actionButton("button1", label = "Show chosen name"), br(),
      textOutput('final_name'),

      #### Second Button ####
      #  to only appear if name from the list is chosen or Name not on the list is not empty
      conditionalPanel(condition = "(input.name_fromlist != '' & input.name_fromlist != 'Name not on our list') |input.Not_on_list != ''", 
                       actionButton("button2", label = "Show number of characters")),

      # Display number of characters for the chosen names
      textOutput("no_of_char")

    )
  )
))

server = shinyServer(function(input, output, session) {

  # A vector of pre-existing names:
  mynames <- c("John", "Mary", "Jim", "Bill")

  # Pull-down to select one of the names:
  observe({
    updateSelectInput(session, inputId = "name_fromlist", label = "Select a name:", 
                      choices = c(mynames, "Name not on our list"))
  })

  # Open end box to appear only if the name the user wants to enter is not on the list:
  output$open_end <- renderUI({
    if (!input$name_fromlist == 'Name not on our list') return(NULL) else {
      textInput("Not_on_list", "If the name you want is not on our list, type it here:")
    }
  })

  # button 1 shows the name selected or typed:
  observeEvent(input$button1, {
    if (input$name_fromlist == 'Name not on our list') selected_name <- input$Not_on_list else {
      selected_name <- input$name_fromlist
    }
    output$final_name <- renderText({paste("Chosen name:  ", selected_name)})
  })

  #### observeEvent for Second Button
  ## This is to display number of charactesr based on chosen/typed names
  observeEvent(input$button2, {
    if (input$name_fromlist == "Name not on our list") {

      selected_name <- input$Not_on_list
    } else {
      selected_name <- input$name_fromlist  
    }

    output$no_of_char <- renderText({paste("Number of Characters:  ", nchar(selected_name))})
  })

})

shinyApp(ui = ui, server = server)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...