R Shiny Action Button and Data Table Output

How to use action buttons to show and hide table output in R shiny?

I think this should cover for all the different scenarios.

I have used reactiveValues to save matrix3Input and matrix.

library(shiny)
library(shinyMatrix)
library(shinyjs)

default_mat <- matrix(c(1,24,0,1),4,1,dimnames=list(c("A","B","C","D"),NULL))

matrix3Input <- function(x, default_mat){
matrixInput(x,
label = 'Series terms:',
value = default_mat,
rows = list(extend = FALSE,names = TRUE),
cols = list(extend = TRUE,names = TRUE,editableNames = TRUE,delete = TRUE),
class = "numeric") # close matrix input
} # close function

ui <- fluidPage(
useShinyjs(),
titlePanel("Inputs"),
fluidRow(actionButton("modify","Modify"),
actionButton("show","Show"),
actionButton("hide","Hide"),
actionButton("reset","Reset"),
tableOutput("table2")
) # close fluid row
) # close fluid page

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

rv <- reactiveValues(mat = matrix3Input("matrix", default_mat), input = default_mat)
hide("table2")

observeEvent(input$modify,{
showModal(modalDialog(
rv$mat,
tableOutput("table1"))
)
hide("table2")
})

output$table1 <- renderTable({
rv$mat <- matrix3Input("matrix", input$matrix)
rv$input <- input$matrix
input$matrix
}, rownames = TRUE)

observeEvent(input$show,{
show("table2")
})

observeEvent(input$hide, hide("table2"))

observeEvent(input$reset,{
hide("table2")
rv$input <- default_mat
rv$mat <- matrix3Input("matrix", default_mat)
})

output$table2 <- renderTable({
rv$input
}, rownames = TRUE)

} # close server

shinyApp(ui, server)

R Shiny: Handle Action Buttons in Data Table

Does this accomplish what you're trying to do?

library(shiny)
library(DT)

shinyApp(
ui <- fluidPage(
DT::dataTableOutput("data"),
textOutput('myText')
),

server <- function(input, output) {

myValue <- reactiveValues(employee = '')

shinyInput <- function(FUN, len, id, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), ...))
}
inputs
}

df <- reactiveValues(data = data.frame(

Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
Motivation = c(62, 73, 3, 99, 52),
Actions = shinyInput(actionButton, 5, 'button_', label = "Fire", onclick = 'Shiny.onInputChange(\"select_button\", this.id)' ),
stringsAsFactors = FALSE,
row.names = 1:5
))

output$data <- DT::renderDataTable(
df$data, server = FALSE, escape = FALSE, selection = 'none'
)

observeEvent(input$select_button, {
selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
myValue$employee <<- paste('click on ',df$data[selectedRow,1])
})

output$myText <- renderText({

myValue$employee

})

}
)

r Shiny action button and data table output last N rows

@Tomáš - I would recommend avoiding putting your output statements inside of observeEvent. Instead, I would create an eventReactive that will be triggered by your action button. And when this happens, it will store all your needed info in a list, and all of your outputs will be dependent on this list. Here is one way to do this (below is the server function only).

server <- function(input, output) {

aq_data <- eventReactive(input$gobutton, {
list(data = airquality, nID = input$numericID, rID = input$radioID, sID = input$selectID, tID = input$textID)
})

output$textik <- renderText({
vypis=c("Zobrazili ste tabuľku s", aq_data()[["nID"]], "riadkami a boxplot pre atribút Ozone ste nastavili na farbu ", aq_data()[["rID"]])
print(vypis)
})

output$table <- renderTable(tail(aq_data()[["data"]], aq_data()[["nID"]]))

output$distPlot <- renderPlot({
dat <- aq_data()
boxplot(reformulate("Month", dat[["sID"]]), col = dat[["rID"]], border = 'white', main = dat[["tID"]], data = dat[["data"]])
})

}

R Shiny - saving values of function in data table after action button press

I think there may be a number of ways you could set this up differently.

One recommendation I have is to avoid putting output inside of your observers.

Another is calling your stopwatch functions only once - for data integrity, to make sure your display and data collected are the same.

In addition, it might be helpful to have a single data table store all of your open and close events, with an additional column for animal number. It would be relatively easy to work with a table like this for future analyses.

Here is a quick example you can try out, just to get a sense of the behavior. Please also add tableOutput('table') to your ui after your conditionalPanel to view the data frame.

# ui ----

ui <- fluidPage(
titlePanel("Lymnaea stopwatch"),

sidebarLayout(
sidebarPanel(

selectInput(
"select",
label = "Number of animals",
choices = c(1,2,3,4,5,6,7,8,9,10),
selected = c("1")
)
# action button conditionals ----
),
mainPanel(
h4("Start/Stop Experiment:"),
actionButton('start1',"Start"),
actionButton('stop1', "Stop"),
textOutput('initial1'),
textOutput('start1'),
textOutput('stop1'),
textOutput('stoptime1'),

conditionalPanel(
h4("Animal 1"),
condition = "input.select == '1'||input.select == '2'||input.select == '3'||input.select == '4'||input.select == '5'||input.select == '6'||input.select == '7'||input.select == '8'||input.select == '9'||input.select == '10'",
actionButton('open1', "Open"),
actionButton('close1', "Close"),
textOutput('open1'),
textOutput('opentime1'),
textOutput('close1'),
textOutput('closetime1'),
),
tableOutput('table')
)
)
)

# server ----

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

values <- reactiveValues(df = data.frame(Animal = integer(),
Event = character(),
Time = as.POSIXct(character()),
stringsAsFactors = FALSE),
timer = "Timer Off")

output$initial1 <- renderText({
values$timer
})

output$opentime1 <- renderText({
paste("Opened at:", tail(values$df[values$df[["Animal"]] == 1 & values$df[["Event"]] == "Open", "Time"], 1))
})

output$closetime1 <- renderText({
paste("Closed at:", tail(values$df[values$df[["Animal"]] == 1 & values$df[["Event"]] == "Close", "Time"], 1))
})

output$table <- renderTable({
values$df
})

observeEvent(input$start1, {
watch$start()
values$timer <- "Timer Started"
})

observeEvent(input$open1, {
values$df <- rbind(values$df, data.frame(Animal = 1, Event = "Open", Time = watch$open()))
})

observeEvent(input$close1, {
values$df <- rbind(values$df, data.frame(Animal = 1, Event = "Close", Time = watch$close()))
})

}

This could be scaled up for 10 animals, and there are alternative ways to provide feedback to user on data.

Let me know what you think, and if this is in the direction you had in mind.

How to use shiny's actionButton in DataTable through shiny module?

Your code:

paste0('Shiny.onInputChange(' , ns("select_button"), ', this.id)')

generates

"Shiny.onInputChange(NS_select_button, this.id)"

where NS is the name space. The object NS_select_button does not exist and clicking the button throws an error for this reason. You need quotes:

"Shiny.onInputChange('NS_select_button', this.id)"

To include some quotes, you can do:

onclick = sprintf("Shiny.onInputChange('%s', this.id)", ns("select_button"))

adding regular button to datatable - shiny app

Let's define a custom button.

Change the button label by text, change the shiny input ID in setInputValue, change mydf_btn to whatever you want.

library(shiny)

ui <- fluidPage(
DT::DTOutput("mydf")
)

server <- function(input, output, session) {
output$mydf <- DT::renderDataTable(
DT::datatable(
iris,extensions = 'Buttons', rownames = FALSE,
options = list(
info = FALSE, paging = FALSE, dom='lfBrtip',
buttons= list(
list(
extend = 'collection',
text = 'My Action',
action = DT::JS(
"function() {
var node = this[0].node;
var value = $(node).attr('data-value') || 0;
value ++;
$(node).attr('data-value', value);
Shiny.setInputValue('mydf_btn', value, {priority: 'event'});
}"
)
)
)
)
)
)
observe(print(input$mydf_btn))
}

shinyApp(ui, server)

Sample Image

r Shiny action button and data table output

Wrap it in a eventReactive instead:

library(shiny)

ui <- fluidPage(
fluidRow(column(6,div(checkboxGroupInput("test1", "Testing buttons",
choices=c("A","B","C"),
selected=c("A","B","C"))))),

hr(),
actionButton("gobutton","Start"),
dataTableOutput("summary_table")

)

server <- function(input,output){

data <- eventReactive(input$gobutton,{
if(is.null(input$test1)){
return()
}

df <- data.frame(col1=input$test1,col2=seq(1,length(input$test1),1))
df
})

output$summary_table <- renderDataTable({
data()
})
}

shinyApp(ui=ui, server=server)

R Shiny One actionButton for multiple Output

In your code, mydata() is a reactive function with output dt3 (the last line of the function), this is why you only get one table as result.

You could use reactiveValues combined with observeEvent:

library(shiny)
library(ggplot2)
library(dplyr)

ui <-shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(

selectInput("manufacturer", "Car Type:", c("audi","chevrolet")),
selectInput("year", "Year:", c("1999","2008")),
actionButton("action", "Go!")
),

mainPanel(tableOutput("dt2"),
tableOutput("dt3"))
)
))

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

mydata <- reactiveValues()

observeEvent(input$action, {
dt <- mpg
mydata$dt2 <- dt %>%
filter(manufacturer==input$manufacturer) %>%
mutate(mean = mean(cty)) %>% slice(1:5)

mydata$dt3 <- mydata$dt2 %>% group_by(input$year) %>%
summarise(mean = mean(cty))
})

output$dt2 <- renderTable({ mydata$dt2 })
output$dt3 <- renderTable({ mydata$dt3 })

})

shinyApp(ui,server)

Shiny - ObserveEvent and actionButton adding a column to table

Perhaps you are looking for this

library(shiny)
library(shinydashboard)
library(tidyverse)
library(data.table)
library(DT)

upload_tab <- tabItem(tabName = "FileUpload",
titlePanel("Uploading Files"),
sidebarPanel(
fileInput('file1', 'Choose file to upload',
accept = c('text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain','.csv','.tsv')),
checkboxInput("header", "Header", TRUE),
radioButtons("sep", "Separator",
choices = c(Comma = ",",
Semicolon = ";",
Tab = "\t"),
selected = ","),
radioButtons("quote", "Quote",
choices = c(None = "",
"Double Quote" = '"',
"Single Quote" = "'"),
selected = '"')),
mainPanel(
DT::dataTableOutput('contents')
)
)

splitter_tab <- tabItem(
tabName = "Splitter",
fluidPage(
box(title = "Split means and letters into two separate columns", width = 3, solidHeader = T, status = "primary",
selectInput("get_let_mean",'Select column:',choices = NULL),
br(),
actionButton("splitter", "Split")),
mainPanel(
DT::dataTableOutput('contents1')
)
)
)

sideBar_content <- dashboardSidebar(
sidebarMenu(
menuItem("Upload File", tabName = "FileUpload"),
menuItem("Splitter", tabName = "Splitter")
)
)

body_content <- dashboardBody(
tabItems(
upload_tab,
splitter_tab
)
)

ui <- dashboardPage(
dashboardHeader(title = "Test"),
## Sidebar content
sideBar_content,
## Body content
body_content,
## Aesthetic
skin = "blue"
)

server <- function(input, output,session) {
rv <- reactiveValues(df=NULL)

data<-reactive({
if(is.null(input$file1))
return()
inFile <- input$file1
df <- read.csv(inFile$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
})


output$contents <- DT::renderDataTable({
DT::datatable(data(),
options = list(
"pageLength" = 40))
})

observe({
value <- names(data())
updateSelectInput(session,"get_let_mean", choices = value)
})

observeEvent(input$file1,{
rv$df <- data()
})


observeEvent(input$splitter,{
rv$df <- rv$df %>%
mutate(clean_values= max(.data[[input$get_let_mean]]))

})


output$contents1 <- DT::renderDataTable({
DT::datatable(rv$df,
options = list("pageLength" = 40))
})

}

shinyApp(ui, server)

In R shiny, how do I add functionality to the action button Add?

You want to use something like reactive or reactiveValues for values that can be changed over and over. To hide the table until a button is clicked, use a conditionalPanel based on the output of the button (it reveals how many times it has been clicked).

I have implemented these things in your code below:

EDIT: Replying to your first comment as well

library(shiny)
library(stringr)
library(shinydashboard)
library(tidyverse)
library(DT)

ui <- fluidPage(
fluidRow(tabsetPanel(id='tabs',
tabPanel("Tab1",
div(id = "form",
textInput("schoolId", label="SchoolId *" ),
selectInput("userId", label="UserId", choices = c("UserA", "UserB", "UserC"),selected = "UserA"),
textInput("class", label = "class"),
selectInput("result", label="result", choices = c("PASS", "FAIL" ))
),
actionButton("add", "Add")
),
tabPanel("Tab2",
tabPanel("View",
conditionalPanel("input.add != 0",
DTOutput("DT2"), hr(), downloadButton('downloadData', 'Download'))
)
)
)
)
)

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

observeEvent(input$add,{
new_entry <- data.frame(SCHOOLID=input$schoolId, USERID=input$userId
, CLASS= input$class
, RESULT=input$result)

if("value" %in% names(store)){
store$value<-bind_rows(store$value, new_entry)
} else {
store$value<-new_entry
}
# If you want to reset the field values after each entry use the following two lines
for(textInputId in c("schoolId", "class")) updateTextInput(session, textInputId, value = "")
updateSelectInput(session, "userId", selected = "UserA")
updateSelectInput(session, "result", selected = "PASS")
})
output$DT2 <- renderDT({
store$value
})

}

shinyApp(ui, server)


Related Topics



Leave a reply



Submit