Modify shiny action button once it is clicked - r

I have the following in server.R
shinyServer(function(input, output) {
# builds a reactive expression that only invalidates
# when the value of input$goButton becomes out of date
# (i.e., when the button is pressed)
ntext <- eventReactive(input$goButton, {
input$n
})
output$nText <- renderText({
ntext()
})
})
and the following in ui.R
shinyUI(pageWithSidebar(
headerPanel("actionButton test"),
sidebarPanel(
numericInput("n", "N:", min = 0, max = 100, value = 50),
br(),
actionButton("goButton", "Go!"),
p("Click the button to update the value displayed in the main panel.")
),
mainPanel(
verbatimTextOutput("nText")
)
))
My goal is to make the go action button disappear once it is clicked five times and give a pop up window warning if clicked less than five times.

As #daattali is saying, shinyjs make this really easy, you can do it like this:
library(shiny)
library(shinyjs)
ui <- shinyUI(
fluidPage(
useShinyjs(),
sidebarPanel(
actionButton('btn','Click me')
),
mainPanel(
verbatimTextOutput("nText")
)
)
)
server <- shinyServer(function(input,output,session){
n <- 0
makeReactiveBinding('n')
observeEvent(input$btn, {
if(n < 5){
info('Msg')
} else if(n > 5){
hide('btn')
}
n <<- n + 1
})
output$nText <- renderText({
n
})
})
shinyApp(ui=ui,server=server)
Here's how you would hide the button without using shinyjs:
library(shiny)
ui <- shinyUI(
fluidPage(
tags$head(
tags$style(
HTML('#num{display: none;}')
)
),
useShinyjs(),
sidebarPanel(
conditionalPanel(
condition = "input.num < 5",
actionButton('btn','Click me')
),
numericInput('num','',0)
),
mainPanel(
verbatimTextOutput("nText")
)
)
)
server <- shinyServer(function(input,output,session){
n <- 0
makeReactiveBinding('n')
observeEvent(input$btn, {
n <<- n + 1
updateNumericInput(session,'num',value=n)
})
output$nText <- renderText({
n
})
})
shinyApp(ui=ui,server=server)
And finally without using observeEvent:
library(shiny)
ui <- shinyUI(
fluidPage(
tags$head(
tags$style(
HTML('#num{display: none;}')
)
),
useShinyjs(),
sidebarPanel(
conditionalPanel(
condition = "input.num < 5",
actionButton('btn','Click me')
),
numericInput('num','',0)
),
mainPanel(
verbatimTextOutput("nText")
)
)
)
server <- shinyServer(function(input,output,session){
n <- 0
makeReactiveBinding('n')
observe({
input$btn
isolate({
n <<- n + 1
updateNumericInput(session,'num',value=n)
})
})
output$nText <- renderText({
n
})
})
shinyApp(ui=ui,server=server)

You don't need to define a reactive n. It is already the value of input$btn.
library(shiny)
library(shinyjs)
ui <- shinyUI(
fluidPage(
useShinyjs(),
sidebarPanel(
actionButton('btn','Click me')
),
mainPanel(
verbatimTextOutput("nText")
)
)
)
server <- shinyServer(function(input,output,session){
observe({
if(input$btn < 5){
info('Msg')
} else {
hide('btn')
}
})
output$nText <- renderText({
input$btn
})
})
shinyApp(ui=ui,server=server)

Related

Shiny, two action buttons, it only responds to the second button and not to the first button

Tell me in R Shiny, there are two action buttons. I want to update the data according to the button I press. But for some reason it only responds to the second button and not to the first button. What is the solution?
if (interactive()) {
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("action_1", "Get 1"),
actionButton("action_2", "Get 2"),
),
mainPanel(
textOutput("result")
),
)
)
server <- function(input, output) {
data <- eventReactive(input$action_1, 1)
data <- eventReactive(input$action_2, 2)
output$result <- renderText(data())
}
shinyApp(ui, server)
}
The second line of this piece of code overwrites the first one:
data <- eventReactive(input$action_1, 1)
data <- eventReactive(input$action_2, 2)
You can do:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("action_1", "Get 1"),
actionButton("action_2", "Get 2"),
),
mainPanel(
textOutput("result")
),
)
)
server <- function(input, output) {
result <- reactiveVal()
observeEvent(input$action_1, { result(1) })
observeEvent(input$action_2, { result(2) })
output$result <- renderText(result())
}
shinyApp(ui, server)
}
If you have many buttons you can simply add a class to it and some simple JS to monitor the last click like so:
library(shiny)
monitorJS <- "$(document).on('click', '.monitor', function () {
Shiny.onInputChange('last_click',this.id);
});"
ui <- fluidPage(
tags$head(tags$script(monitorJS)),
sidebarLayout(
sidebarPanel(
uiOutput("buttons")
),
mainPanel(
textOutput("result")
),
)
)
server <- function(input, output, session) {
output$buttons <- renderUI({
a <- list()
for(i in 1:200){
id <- paste0("action_",i)
name <- paste0("Get ",i)
a[[i]] <- actionButton(id, name, class = "monitor")
}
tagList(a)
})
data <- eventReactive(input$last_click,{
# Your click ligic here
value <- gsub("action_","",input$last_click)
value
})
output$result <- renderText({
data()
})
}
shinyApp(ui, server)

Update a variable with input data

I'm trying to append a value taken from an input (in the present case input$n) to a list (in the present case the variable "keyword_list"), when the user presses the an action button (in the present case the button input$goButton).
ui.R
library(shiny)
pageWithSidebar(
headerPanel("actionButton test"),
sidebarPanel(
#numericInput("n", "N:", min = 0, max = 100, value = 50),
textInput("n", "Caption", "Enter next keyword"),
br(),
actionButton("goButton", "Go!"),
p("Click the button to update the value displayed in the main panel.")
),
mainPanel(
verbatimTextOutput("nText"),
dataTableOutput('mytable')
)
)
})
server.R
library(shiny)
# Define server logic required to summarize and view the selected
# dataset
function(input, output,session) {
#prepare data
keyword_list <- matrix()
makeReactiveBinding('keyword_list')
observe({
if (input$goButton == 0)
return()
isolate({
keyword_list <- append(keyword_list,input$n) })
})
ntext <- eventReactive(input$goButton, {
input$n
})
output$nText <- renderPrint({
#input$n
ntext()
})
output$mytable = renderDataTable({
as.data.frame(keyword_list)
})
}
How about this:
library(shiny)
ui <- pageWithSidebar(
headerPanel("actionButton test"),
sidebarPanel(
#numericInput("n", "N:", min = 0, max = 100, value = 50),
textInput("n", "Caption", "Enter next keyword"),
br(),
actionButton("goButton", "Go!"),
p("Click the button to update the value displayed in the main panel.")
),
mainPanel(
verbatimTextOutput("nText"),
dataTableOutput('mytable')
)
)
})
library(shiny)
# Define server logic required to summarize and view the selected
# dataset
server <- function(input, output,session) {
global <- reactiveValues(keyword_list = "")
observe({
if (input$goButton == 0)
return()
isolate({
global$keyword_list <- append(global$keyword_list, input$n)
})
})
ntext <- eventReactive(input$goButton, {
input$n
})
output$nText <- renderPrint({
#input$n
ntext()
})
output$mytable = renderDataTable({
as.data.frame(global$keyword_list)
})
}
shinyApp(ui, server)

How to use dataframe defined in one buttons observeevent inside another button's observeevent?

This is the code:
button 1 is an actionbutton ,the observeevent is defined as follows
observeEvent(
input$button1,{
mid<-c("1","2")
name<-c("a","b")
datatable1<-data.frame(mid,name)
output$deatilscv <- renderUI({
div(id="div1",
fluidPage(shinyjs::useShinyjs(),
actionButton("button2", "CLICK") )) )}
observeEvent(
input$button2,{
a<-datatable1(1,1) #this shows an error datatable1 not found
print(a)
})
How to access datatable1 details inside observeevent of actionbutton button2
This is a working example:
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Example"),
sidebarLayout(
sidebarPanel(
actionButton("button1", "button1")
),
mainPanel(
uiOutput("deatilscv")
)
)
))
server.R
library(shiny)
library(shinyjs)
shinyServer(function(input, output) {
datatable1 <- eventReactive(input$button1, {
mid<-c("1","2")
name<-c("a","b")
tmp <- data.frame(mid,name)
})
output$deatilscv <- renderUI({
if(!input$button1) return()
div(id="div1",
fluidPage(shinyjs::useShinyjs(),
actionButton("button2", "CLICK") ))
})
observeEvent(
input$button2,{
a <- datatable1()[1,1] #this shows an error datatable1 not found
print(a)
})
})
note that the print(a) in the observe event prints to the console.
Radio buttons version
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Example"),
sidebarLayout(
sidebarPanel(
radioButtons("rb1", "Select options", choices = c("Choice1", "Choice2"))
),
mainPanel(
uiOutput("deatilscv1"),
uiOutput("deatilscv2")
)
)
))
server.R
library(shiny)
library(shinyjs)
shinyServer(function(input, output) {
datatable1 <- eventReactive(input$rb1, {
if (input$rb1 == "Choice1") {
mid<-c("1","2")
name<-c("a","b")
tmp <- data.frame(mid,name)
} else {
mid<-c("3","4")
name<-c("c","d")
tmp <- data.frame(mid,name)
}
tmp
})
output$deatilscv1 <- renderUI({
if(input$rb1 != "Choice1") return()
div(id="div1",
fluidPage(shinyjs::useShinyjs(),
actionButton("button2", "CLICK1"),
renderDataTable(DT::datatable(datatable1()))))
})
output$deatilscv2 <- renderUI({
if(input$rb1 !="Choice2") return()
div(id="div1",
fluidPage(shinyjs::useShinyjs(),
actionButton("button3", "CLICK2"),
renderDataTable(DT::datatable(datatable1()))))
})
observeEvent(
input$button2,{
a <- datatable1()[1,1] #this shows an error datatable1 not found
print(a)
})
observeEvent(
input$button3,{
a <- datatable1()[1,1] #this shows an error datatable1 not found
print(a)
})
})

how to update a variable in ui.R using observer in server.R

I have a variable that is declared in ui.R
cond1 <- 0
If certain conditions are met in server.R, I want to update
cond1 <- 1
I tried the following in server.R
observer({
###if certain conditions are met, update value of cond1
updateTextInput(session,"cond1",value=1)})
The idea is to have an if statement
if(cond1==1){
#display panel in ui.R}
You can do conditionalPanels, use renderUI or use jQuery, here's a example of all of them:
library(shiny)
shinyApp(
ui = shinyUI(
fluidPage(
tags$head(
tags$script(
HTML(
'
Shiny.addCustomMessageHandler("toggleUI",function(message){
if( message.show ){
$("#"+message.selector).show();
}
else{
$("#"+message.selector).hide();
}
})
'
)
)
),
sidebarLayout(
sidebarPanel(
selectInput("selection","Select UI",choices = c("ui1"="ui1","ui2"="ui2","ui3"="ui3"))
),
mainPanel(
uiOutput("ui1"),
conditionalPanel(
condition = "input.selection == 'ui2'",
sliderInput("breakCount", "Break Count", min=1, max=1000, value=10)
),
fluidRow( id="ui3",
div("Some more here")
)
)
)
)
),
server = shinyServer(function(input,output,session){
observeEvent(input$selection,{
# Get selected value
sel.val <- input$selection
# If selection = ui1
if (sel.val == 'ui1'){
output$ui1 <- renderUI({
plotOutput('plt')
})
output$plt <- renderPlot({plot(runif(100))})
} else{
# Remove ui1
output$ui1 <- renderUI({ NULL})
}
# Toggle ui3
if (sel.val == 'ui3'){
session$sendCustomMessage(type='toggleUI', message=list(selector='ui3',show=TRUE))
} else{
session$sendCustomMessage(type='toggleUI', message=list(selector='ui3',show=FALSE))
}
})
})
)

embed iframe inside shiny app

this is my UI. R
shinyUI(fluidPage(titlePanel("Getting Iframe"),
sidebarLayout(
sidebarPanel(
fluidRow(
column(6,
selectInput("Member", label=h5("Choose a option"),
choices=c('BCRA1','FITM2'))
))),
mainPanel(fluidRow(
column(3, htmlOutput("frame"))
)
)
)))
This is my server.R
library(shiny)
members <- data.frame(name=c("Name 1", "Name 2"), nr=c('BCRA1','FITM2'))
shinyServer(function(input, output) {
loadframe <- reactive({
validate(
need(input$Member, "Member input is null!!")
)
query <- members[which(members$nr==input$Member),2]
paste0("http://news.scibite.com/scibites/news.html?q=GENE$",query)
})
output$frame <- renderUI({
tags$iframe(src=loadframe(), height=600, width=535)
})
})
I want to get the iframe from the web page but its printing blank any help on this would be appreciated ?
library(shiny)
members <- data.frame(name=c("Name 1", "Name 2"), nr=c('BCRA1','FITM2'))
ui <- fluidPage(titlePanel("Getting Iframe"),
sidebarLayout(
sidebarPanel(
fluidRow(
column(6, selectInput("Member", label=h5("Choose a option"),choices=c('BCRA1','FITM2'))
))),
mainPanel(fluidRow(
htmlOutput("frame")
)
)
))
server <- function(input, output) {
observe({
query <- members[which(members$nr==input$Member),2]
test <<- paste0("http://news.scibite.com/scibites/news.html?q=GENE$",query)
})
output$frame <- renderUI({
input$Member
my_test <- tags$iframe(src=test, height=600, width=535)
print(my_test)
my_test
})
}
shinyApp(ui, server)

Resources