Jain
Jain

Reputation: 999

Display and Hide dataframe in Shiny

# ui.R

shinyUI(
 fluidPage(
    titlePanel("Make a data frame and display"),
    fluidRow(column(4,selectInput('types', 'Select the type',c("Basketball","Soccer")))),
    uiOutput('typeChange'),
    mainPanel(dataTableOutput('displayDf'))
 )
)

I am trying to take a user input and store the data in to a data frame. I then want to display the data frame simultaneously as the user keeps on adding records. The above code lets user select between Basketball and Soccer

# server.R
# Create a function to initiate and clear global variables

clear_all <- function(){
z <<- c()
z1 <<- c()
z2 <<- c()
z3 <<- c()
}
clear_all()

shinyServer(function(input, output, session) {

# make additional ui depending on the sport selected.
output$typeChange <- renderUI({
    if (input$types=="Basketball"){
        clear_all()
        fluidRow(
        column(4,textInput("v1","Player name")),
        column(4,selectInput("v2", "Age:",c("20","25","30"))),
        column(4,actionButton("add", "Add the above player")))
    }else if (input$types=="Soccer"){
        clear_all()
        fluidRow(
        column(4,textInput("v1","Player name")),
        column(4,selectInput("v2", "Age",c("20","25","30"))),
        column(4,selectInput("v3", "Income:",c("100","125","150"))),
        column(4,actionButton("add", "Add the above player")))
    }else{}
})

# if a user adds a player, update the dataframe and display
observeEvent(input$add, {
    if (input$types=="Basketball"){
        z1 <<- c(z1,input$v1)
        z2 <<- c(z2,input$v2)
        z<<- data.frame(Player=z1,Age=z2)
    }else if (input$types=="Soccer"){
        z1 <<- c(z1,input$v1)
        z2 <<- c(z2,input$v2)
        z3 <<- c(z3,input$v3)
        z<<- data.frame(Player=z1,Age=z2,Income=z3)
    }

    output$displayDf=renderDataTable(z)
})
})

The server side code creates new text and selectinput depending on what sport is selected. The functionality I am trying to create is that after selecting a sport, a user can enter the other inputs and add the player. The list of players a user added should be displayed as long as the user doesn't select a different sport. Once the user changes the sport, the data frame will be empty and nothing from the previous sport should be displayed.

The issue that I am facing is that if I add 3 players in basketball and then change my top selection to soccer, i still see the basketball data until i add a soccer player. I want the displayed data frame to hide as soon as I change the sport. Also attached are the screenshots of the same.Please advise.After Adding 3 players in Basketball

Changing the sport to Soccer

Upvotes: 1

Views: 1677

Answers (1)

shosaco
shosaco

Reputation: 6155

Your problem can be solved if you put the datatable in a reactive Output, so that it's always displaying what input$type says, that is:

  1. Make a list of reactive Values, tables which has length 2 and stores tables for basketball and soccer, respectively.
  2. According to the content of input$type show one or the other.

I tidied your app while solving this (1. don't use duplicate input IDs, 2. using global variables is not as clean as using the reactives, 3. Use conditionPanels):

library(shiny)
library(plotly)
library(shinyjs)

ui <- shinyUI(
  fluidPage(
    useShinyjs(),
    titlePanel("Make a data frame and display"),
    fluidRow(column(4,selectInput('types', 'Select the type',c("Basketball","Soccer")))),
    fluidRow(column(width=8,
                    column(4, textInput("v1","Player name")),
                    column(4, selectInput("v2", "Age:",c("20","25","30"))),
                    conditionalPanel(condition="input.types == 'Soccer'",
                                     column(4, selectInput("v3", "Income:",c("100","125","150"))))),
                    column(1, actionButton("add", "Add the above player"))),
    mainPanel(dataTableOutput('displayDf'))
  )
)


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

  tables <- reactiveValues(basketball = data.frame(Player = character(), Age = numeric()),
                           soccer     = data.frame(Player = character(), Age = numeric(), Income = double()))

# if a user adds a player, update the dataframe and display
  observeEvent(input$add, {
    if (input$types=="Basketball"){
      oldVals <- tables$basketball
      tables$basketball <- rbind(oldVals, data.frame(Player = input$v1, Age = input$v2))
    }else if (input$types=="Soccer"){
      oldVals <- tables$soccer
      tables$soccer <- rbind(oldVals, data.frame(Player = input$v1, Age = input$v2, Income = input$v3))
    }

    # reset the input values
    reset("v1")
    reset("v2")
    reset("v3")
  })

  # display the appropriate table
  output$displayDf <- renderDataTable({
    if (input$types=="Basketball") tables$basketball else tables$soccer
  })
})

shinyApp(ui, server)

Upvotes: 2

Related Questions