Actionbutton not working for first time in R shiny - r

I have used this code for a simple app to receive system and site name from users. And I have problem for the second time press the "submit" button. For example, if user has pressed "submit" directly without select system/select site, it will pop up "Please make sure system is not empty ." This is the first time press "submit" but when user has selected system and the site then pressed "submit" the second time, it does not work. Does any one know how to solve it?
Here is my code.
library(shiny)
library(shinyWidgets)
library(shinycssloaders)
library(shinythemes)
library(shinyTime)
library('tools')
# Define UI for application that draws a histogram
ui <- fluidPage(
theme = shinytheme("cyborg"),
# Application title
titlePanel("test"),
sidebarLayout(
sidebarPanel(
selectizeInput('system', '* Select System:', width = '100%',
choices = c("a","b","c"), multiple = FALSE,
options = list(
placeholder = 'Please Select Site',
onInitialize = I('function() { this.setValue(""); }')
)),
selectizeInput('site', '* Select Site:', width = '100%',
choices = c("A","B","C"), multiple = FALSE,
options = list(
placeholder = 'Please Select Site',
onInitialize = I('function() { this.setValue(""); }')
)),
hr(),
actionBttn(inputId = "submit", label= "Submit for Processing")
),
mainPanel(
h4("Test review")
)
)
)
server <- function(input, output, session) {
# observe submit
observeEvent(input$submit, {
print("test input submit button 2")
if (input$system=="") {
showModal(modalDialog(
title = "Error",
"Please make sure system is not empty."
))
}else if (input$site==""){
print("test1")
showModal(modalDialog(
title = "Error",
"Please make sure site is not empty."
))
}else {
showModal(modalDialog(
title = "Good",
"success"
))
}
}, once = TRUE)
}
# Run the application
shinyApp(ui = ui, server = server)

Related

Show only one notification in Shiny

I would like to control the phone number by showing a notification :
If the user type a wrong number (like "aaaa")
If the user type a long number (greater than 10 digits)
I used the function showNotification from shiny with closeButton = FALSE and duration = NULL.
When the user type a wrong number, the notification popped up but when he type a long number the the notification also popped up but the previous one does not disappear
I would like to show only one notification (wrong number or long number) but not the both at the same time. How can we do that ? Here's my apps :
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
############# UI ############
body <- dashboardBody(
tabItems(
tabItem(tabName = "tab1",
fluidRow(
tags$h1('my title'),
textInput("phone_number", "enter your phone number", value = ""),
actionButton("button", "go")
)
)
)
)
ui <- dashboardPage(
title = "Example",
options = list(sidebarExpandOnHover = TRUE),
header = dashboardHeader(disable = FALSE),
sidebar = dashboardSidebar(
minified = TRUE, collapsed = TRUE,
sidebarMenu(id="menu",
menuItem("first tab", tabName = "mytab", icon = icon("fas fa-acorn"),
menuSubItem('menu1',
tabName = 'tab1',
icon = icon('fas fa-hand-point-right'))
)
)
),
body
)
############# SERVER ############
server <- function(input, output) {
observeEvent(
input$button,
{
if(is.na(as.numeric(input$phone_number))) {
showNotification(type = "error",
duration = NULL,
closeButton = FALSE,
"wrong number")
} else if(nchar(input$phone_number)<10) {
showNotification(type = "error",
duration = NULL,
closeButton = FALSE,
"too long (10 digits required)")
}
}
)
}
############# RUN THE APP ############
shinyApp(ui = ui, server = server)
Some help would be appreciated
I would not use a notification here, because they will always be displayed for a fixed time duration and at a different position of the window, which might confuse the user. I would just render the message in using a textOutput:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
textInput("phone_number", "phone number"),
textOutput("phone_notification")
)
server <- function(input, output, session) {
output$phone_notification <- renderText({
if(input$phone_number == "") {
"" # empty is ok
}
else if(is.na(as.numeric(input$phone_number))) {
"wrong number"
} else if (nchar(input$phone_number) > 10) {
"too long"
} else {
"" # correct number
}
})
}
shinyApp(ui, server)
You can also style the text e.g. to make it red:
ui <- fluidPage(
useShinyjs(),
textInput("phone_number", "phone number"),
tagAppendAttributes(
textOutput("phone_notification"),
style = "color:red"
)
)
I needed the solution OP asked. I found the following code snippet to work in my case:
removeNotification(id = "onlyOnce", session = getDefaultReactiveDomain())
showNotification("Show me once", id = "onlyOnce")
See also: https://search.r-project.org/CRAN/refmans/shiny/html/showNotification.html

R Shiny close only embedded modaldialog

This is a follow-up question to this question from 4 years ago: How to close embedded modalDialog
library(shiny)
library(DT)
library(shinyWidgets)
library(shinyalert)
ui = fluidPage(
fluidRow(
column(width = 6,
actionButton('button',
label = "Click me",
icon = icon("fas fa-check"),
width = '100%')
)
)
)
server = function(input, output) {
observeEvent(input$button, {
showModal(
modalDialog(
title = "Test two modalDialogs",
br(),
autonumericInput("numeric",
"Enter a number less than 69",
value = NULL,
width = '100%'),
actionButton("buttonA",
label = "Click to see what happens",
icon = icon("fas fa-save")
),
footer = NULL
)
)
})
observeEvent(input$buttonA, {
if(input$numeric < 69){
showModal(
modalDialog(
title = h2("You did not enter a number which is greater than 69. Please try again."),
actionButton("buttonB",
label = "Ok."),
footer = tagList(modalButton("Try again"))
)
)
}
})
observeEvent(input$buttonB, {
removeModal()
})
}
shinyApp(ui = ui, server = server)
Is it by now possible to close only the second modal-dialog which opens after the user entered a value smaller than 69? Both options, the modalButton and also the removeModal close both dialogs.

How to render centralized text inputs in a window and save then? Customer Registration Example

Well i trying to open a window by pressing a button to write some text inputs and submit to MySql table, like this example below, but i dont know how i centralize the texts inputs.
ATTEMPT
library(shinyWidgets)
library(shiny)
library(shinyjs)
library(RMariaDB)
shinyApp(
ui = fluidPage(
useShinyjs(), # Set up shinyjs
actionButton("btn", "Costumer Registration"),
),
server = function(input, output,session) {
#connect to MySQL
#localuserpassword= "PASSW"
#myconnect <- dbConnect(RMariaDB::MariaDB(), user='user', password=localuserpassword, dbname='name', host='localhost')
observeEvent(input$btn, { # open a window by pressing the "btn" button
confirmSweetAlert(
btn_labels = c("Cancel","Submit"),
session = session,
inputId = "SubmitCostumertoSQL",
type = "info",
title = paste0("Customer Registration"),
danger_mode = F,
closeOnClickOutside = T,
showCloseButton =T,
text = tags$div(
renderUI(textInput("name", "Name")),
renderUI(textInput("NRLE", "National Registry of Legal Entities")),
renderUI(textInput("address", "Address")),
)
)
} )
observeEvent(input$SubmitCostumertoSQL, {
#Send to MySQL
#querycostumer= paste("insert into TABLENAME(Name,NRLE,Addres)
# values('",input$name,"','",
# input$NRLE,"','",
# input$address,
# "')" ,sep = '')
#dbSendQuery(myconnect,querycostumer)
})
}
)
How to centralize the text input and save then into a object?
Include align = 'center' in your div, e.g. text = tags$div(align = 'center',
textInput can also include placeholder text if you want to match the example more closely.
Minimal working example
library(shinyWidgets)
library(shiny)
library(shinyjs)
shinyApp(
ui = fluidPage(
useShinyjs(),
actionButton("btn", "Costumer Registration"),
),
server = function(input, output,session) {
observeEvent(input$btn, {
confirmSweetAlert(
btn_labels = c("Cancel","Submit"),
session = session,
inputId = "SubmitCostumertoSQL",
type = "info",
title = paste0("Customer Registration"),
danger_mode = F,
closeOnClickOutside = T,
showCloseButton =T,
text = tags$div(align = 'center',
renderUI(textInput("name", "Name")),
renderUI(textInput("NRLE", "National Registry of Legal Entities")),
renderUI(textInput("address", "Address")),
)
)
})
})

How to create a popup window for user to input information in R shiny?

Here is an example. What I want is that users can run the demo as many time as they want by DEMO button. However when they click Browse for uploading local data (not reset button as I demonstrated in the example), I would popup a window to let users input their name and state in two input boxes. In the below example, by click RESET, a single popup box will launch (may be not a proper way).
library(shiny)
library(shinyWidgets)
if (interactive()) {
# Display an important message that can be dismissed only by clicking the
# dismiss button.
shinyApp(
ui <- fluidPage(
tabsetPanel(
##tabPanel-Input
tabPanel("Input", fluid = TRUE,
# tab title ----
titlePanel("Upload data"),
# sidebar layout with input and output tables ----
sidebarLayout(
# sidebar panel for inputs ----
sidebarPanel(
#show ct demo
actionBttn("runexample", "DEMO", style="simple", size="sm", color = "primary"),
# input1: Select a file ----
fileInput("file1", "Count matrix File (.xlsx)",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
#action run
actionBttn("runbutton", "GO", style="simple", size="sm", color = "primary"),
actionBttn("reset", "RESET", style="simple", size="sm", color = "warning"),
verbatimTextOutput(outputId = "reset"),
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Data file ----
span(textOutput("nrows"),style="color:blue"),
span(textOutput("ncols"),style="color:blue"),
tableOutput("matrix"),
)
)
)
)
),
server = function(input, output, session) {
###display demo count matrix
observeEvent(input$runexample, {
#ngenes
output$nrows <- renderText({paste("Number of genes: ", dim(mtcars)[1], " [First 10 rows displayed]")})
#nsamples
output$ncols<- renderText({paste("Number of genes: ", (dim(mtcars)[2]), " [First 10 rows displayed]")})
#display 10rows count matrix
output$matrix <- renderTable({
mtcars
})
}
)
observeEvent(input$reset, {
inputSweetAlert(
session = session, inputId = "mytext", input = "text",
title = "This is a free program, please leave your email:"
)
})
output$text <- renderPrint(input$mytext)
}
)
}
Here is an example using the modal dialog option provided by shiny. I trimmed your example down to the bits that mattered:
library(shiny)
if (interactive()) {
shinyApp(
ui <- fluidPage(
actionButton("reset", "RESET", style="simple", size="sm", color = "warning"),
verbatimTextOutput(outputId = "text")
),
server = function(input, output, session) {
l <- reactiveValues()
observeEvent(input$reset, {
# display a modal dialog with a header, textinput and action buttons
showModal(modalDialog(
tags$h2('Please enter your personal information'),
textInput('name', 'Name'),
textInput('state', 'State'),
footer=tagList(
actionButton('submit', 'Submit'),
modalButton('cancel')
)
))
})
# only store the information if the user clicks submit
observeEvent(input$submit, {
removeModal()
l$name <- input$name
l$state <- input$state
})
# display whatever is listed in l
output$text <- renderPrint({
if (is.null(l$name)) return(NULL)
paste('Name:', l$name, 'and state:', l$state)
})
}
)
}

R Shiny stop code execution until modal is closed

I want to execute rest of shiny app code only when modal dialog box is closed. How can I achieve this?
Here simple code:
# ui.R
actionButton("loadData", label = "Button", icon = icon("mail-forward"))
# server.R
observeEvent(input$loadData, {
showModal(modalDialog(
title = modal.title,
textInput("newName", "Enter file name:", value = ""),
easyClose = TRUE,
footer = list(
actionButton("confirmName", "OK"),
modalButton("Cancel"))
))
# ...code to be executed after modal is closed...
})
Create an event handler that executes code when the OK action button has been clicked, and also closes the modal using removeModal.
library(shiny)
ui <- fluidPage(
actionButton("loadData", label = "Button", icon = icon("mail-forward")),
verbatimTextOutput("filename")
)
server <- function(input, output, session) {
observeEvent(input$loadData, {
showModal(modalDialog(
title = "title",
textInput("newName", "Enter file name:", value = ""),
easyClose = TRUE,
footer = list(
actionButton("confirmName", "OK"),
modalButton("Cancel"))
))
})
output$filename <- eventReactive(input$confirmName, {
message("Closing modal")
removeModal()
input$newName
})
}
shinyApp(ui, server)
There's an example of this in the docs: https://shiny.rstudio.com/reference/shiny/latest/modalDialog.html

Resources