Mateus Figueiredo
Mateus Figueiredo

Reputation: 81

Change numericInput value based on selected row

I made a flowchart that changes based on numeric input the user provides. Now I want the user to be able to select a row from a table, and depending on what the user selected, the value of the numeric input changes.

In this example, selecting a movie title would change the numeric input "ticket price" based on a data frame with movie information. However, the user would be free to simply ignore the selectInput if they want to.

I already have the select input widget. I want it so that the widget reads the information of movie titles from the data frame with movie information.

I made this working example:

# Packages
library(shiny)
library(DiagrammeR)    # creates flowchart

### Define UI ###
ui <- fluidPage(
  
  # Sidebar with select input and numeric input
  sidebarLayout(
    sidebarPanel(h3("Flowchart creator with select Input"),
                 #User can choose movie title (optional)
                 selectInput(inputId = 'title',
                             label = "Movie title",
                             choices = c("","Matrix","Inception")),
                 
                 #User can manually type in ticket price
                 numericInput("inputb",
                              "Ticket price is:",
                              value = 60)
    ),
    
    # Show DiagrammeR plot
    mainPanel(
      grVizOutput("dg",width ="95%",height="95%")
    )
  )
)

### Define server ###

server <- function(input, output) { 
  
  #Creates tribble with movie information. 
  df <- as.data.frame(tribble(
    ~movie,~cost,~duration,
    "Matrix",10.00,136,
    "Inception",12.00,158,
    "Titanic",15.00,194)) #end movie tribble

    rv <<- reactive({
    #Creates tibble. DiagrammeR reads values inside the tibble.
    tibble::tibble(
      price.tickets  = input$inputb
    ) #End of tibble
  })
  
  #Define outputs to show in flowchart based on values on tibble
  #The flowchart can't read inputs. It can only read values on the tibble.
  output$price.tickets  = renderText({rv()$price.tickets })

  # Create flowchart with DOT language with DiagrammeR
  output$dg <- renderGrViz({
    grViz(diagram = "digraph flowchart {
  legend [label = '@@2']
  price [label = '@@1']
  legend->price
}
   [1]: rv()$price.tickets
   [2]: 'ticket price'
") #end of flowchart in DOT language
    
  })
}

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

So it's two things:

  1. Define selectInput choices based on the data.frame with movie information
  2. Update the numericInput value based on the cost of the movie selected by the user, if the user chooses a movie.

Thank you!

Upvotes: 1

Views: 71

Answers (1)

jpdugo17
jpdugo17

Reputation: 7116

We can combine datatable with updateNumericInput and updateSelectInput.

  output$table_movies <- renderDT({
    datatable(df,selection = 'single')
  })
  
  observeEvent(input$table_movies_rows_selected, {
    rws <- input$table_movies_rows_selected
    updateNumericInput(session = session,inputId = 'inputb',value = df[rws, 'cost'])
    updateSelectInput(session = session, inputId = 'title', selected = df[rws, 'movie'])
  })

Now every time a row is selected the inputs will "auto-select" that information and also trigger the flowchart to change.

App:

library(shiny)
library(DiagrammeR) 
library(DT)
library(tidyverse)

#Creates tribble with movie information. 
df <- as.data.frame(tribble(
  ~movie,~cost,~duration,
  "Matrix",10.00,136,
  "Inception",12.00,158,
  "Titanic",15.00,194)) #end movie tribble


### Define UI ###
ui <- fluidPage(
  
  # Sidebar with select input and numeric input
  sidebarLayout(
    sidebarPanel(h3("Flowchart creator with select Input"),
                 #User can choose movie title (optional)
                 selectInput(inputId = 'title',
                             label = "Movie title",
                             choices = df$movie),
                 
                 #User can manually type in ticket price
                 numericInput("inputb",
                              "Ticket price is:",
                              value = 60),
                 DTOutput('table_movies')
    ),
    
    # Show DiagrammeR plot
    mainPanel(
      grVizOutput("dg",width ="95%",height="95%")
    )
  )
)

### Define server ###

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

  
  rv <<- reactive({
    #Creates tibble. DiagrammeR reads values inside the tibble.
    tibble::tibble(
      price.tickets  = input$inputb
    ) #End of tibble
  })
  
  output$table_movies <- renderDT({
    datatable(df,selection = 'single')
  })
  
  observeEvent(input$table_movies_rows_selected, {
    rws <- input$table_movies_rows_selected
    updateNumericInput(session = session,inputId = 'inputb',value = df[rws, 'cost'])
    updateSelectInput(session = session, inputId = 'title', selected = df[rws, 'movie'])
  })
  
  #Define outputs to show in flowchart based on values on tibble
  #The flowchart can't read inputs. It can only read values on the tibble.
  output$price.tickets  = renderText({rv()$price.tickets })
  
  # Create flowchart with DOT language with DiagrammeR
  output$dg <- renderGrViz({
    grViz(diagram = "digraph flowchart {
  legend [label = '@@2']
  price [label = '@@1']
  legend->price
}
   [2]: 'ticket price'
") #end of flowchart in DOT language
    
  })
}

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

enter image description here

Upvotes: 1

Related Questions