I can successfully move the "next" button for slickR's carousel. However, when I use the similar method to move the "previous" button it does not work. The action and the mouseover no longer work. Why is this? How can I move the "prev" button and maintain full functionality?
The documentation refers to an element in settings called, appendArrows. But it is not clear to me how to use this.
appendArrows character, Change where the navigation arrows are attached (Selector, htmlString, Array, Element, jQuery object), Default: $(element)
Here is where the fully functional moved buttons should appear:
library(shiny)
library(slickR)
# Test #########################################################################
chart_names_list <- c( "http://placehold.it/900x500/39CCCC/ffffff&text=Slide+1",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+2",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+3")
num_slides <- 2
ui <- fluidPage(
tags$head(
tags$style(HTML("
.slick-next {
right: 163px;
top: 20px;
}
.slick-prev {
left: 670px;
top: 20px;
}
.slick-slide {
margin-top: 30px;
}
")
)
),
slickROutput("slick_output")
)
server <- function(input, output, session) {
output$slick_output <- renderSlickR({
slickR(obj = chart_names_list, height = 300, width = "100%") +
settings(dots = TRUE)
})
}
shinyApp(ui, server)
appendArrows parameter is used to tell in which div class the arrows should be displayed.
This shows the principle, but still needs some extra css to get exactly the result you expect :
library(shiny)
library(slickR)
# Test #########################################################################
chart_names_list <- c( "http://placehold.it/900x500/39CCCC/ffffff&text=Slide+1",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+2",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+3")
num_slides <- 2
ui <- fluidPage(
tags$head(
tags$style(HTML("
.arrows {
height: 30px;}"))
),
fluidRow(
column(6,),
column(2,
tags$div(class="arrows"
)),column(4)),
slickROutput("slick_output")
)
server <- function(input, output, session) {
output$slick_output <- renderSlickR({
slickR(obj = chart_names_list, height = 300, width = "100%") +
settings(dots = TRUE, appendArrows = '.arrows')
})
}
shinyApp(ui, server)
Taking #Waldi's valuable suggestions and adding some css leads to a complete answer below.
library("shiny")
library("slickR")
# Test #########################################################################
chart_names_list <- c( "http://placehold.it/900x500/39CCCC/ffffff&text=Slide+1",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+2",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+3")
num_slides <- 3
ui <- fluidPage(
tags$head(
tags$style(HTML("
.arrows {
height: 30px;
}
.slick-prev {
left: 230px; # moves right
}
.slick-next {
left: 250px; # moves right
}
"))
),
fluidRow(
column(6,),
column(2,
tags$div(class="arrows"
)),
column(4)),
slickROutput("slick_output")
)
server <- function(input, output, session) {
output$slick_output <- renderSlickR({
slickR(obj = chart_names_list, height = 300, width = "100%") +
settings(dots = TRUE, appendArrows = '.arrows')
})
}
shinyApp(ui, server)
As this is the original question regarding the positioning of the arrow buttons, I guess it's worth mentioning, that #ixodid realized here, that #Waldi's column-approach is no longer working when the browser window is resized.
The following is a workaround regarding this:
library("shiny")
library("slickR")
chart_names_list <- c( "http://placehold.it/900x500/39CCCC/ffffff&text=Slide+1",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+2",
"http://placehold.it/900x500/39CCCC/ffffff&text=Slide+3")
num_slides <- 3
ui <- fluidPage(
tags$head(
tags$style(HTML("
.arrows {
height: 20px;
}
.slick-prev {
left: calc(100% - 60px);
}
.slick-next {
left: calc(100% - 35px);
}
.slick-slide img {
width: 100% !important;
}
"))
),
fluidRow(
column(12, tags$div(class="arrows"))
),
slickROutput("slick_output")
)
server <- function(input, output, session) {
output$slick_output <- renderSlickR({
slickR(obj = chart_names_list, height = 300) +
settings(dots = TRUE, appendArrows = '.arrows')
})
}
shinyApp(ui, server)
Related
I'm trying to use Fabric.js interactively in a Shiny app. Shiny should render the image, then the user will modify it via Fabric. Then, Shiny will read that image back in to the server and further process it. However, I can't get past the first step at the moment!
In the code below, the plot/png displays below the canvas, but not inside of it. Is how I reference the image id in the javascript wrong?
Maybe it is because the renderImage places the image inside a div?
Here's the code:
library(shiny)
js <- "
$(document).ready(function () {
var canvas = new fabric.Canvas('drawarea');
var imgElement = document.getElementById('myimage');
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 0,
opacity: 0.75,
width:300,
height:300
});
canvas.add(imgInstance);
});
"
ui <- fluidPage(
tags$head(tags$script(HTML(js))),
tags$head(tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js", type="text/javascript")),
tags$head(
tags$style(HTML("
canvas {
border: 1px solid #999;
}
myimage{display:none;}
"))
),
titlePanel("Fabric Demo"),
sidebarLayout(
sidebarPanel(
h4("Side")
),
mainPanel(
HTML('
<canvas width="800" height="800" id="drawarea" style="border: 1px solid red;float: right"> </canvas>
'),
plotOutput("div.for.image")
)
)
)
server <- function(input, output, session) {
output$div.for.image <- renderImage({
outfile <- tempfile(fileext='.png')
# Generate a png
png(outfile, width=400, height=400)
hist(rnorm(20))
dev.off()
# Return a list
list(src = outfile,
alt = "This is alternate text",
id = "myimage")
}, deleteFile = TRUE)
}
shinyApp(ui=ui,server=server)
You can use the shiny:value JavaScript event, which is triggered when an output is rendered.
library(shiny)
js <- "
$(document).on('shiny:value', function(evt) {
if(evt.name === 'divForImage') {
setTimeout(function(){
var canvas = new fabric.Canvas('drawarea');
var imgElement = document.getElementById('myimage');
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 0,
opacity: 0.75,
width: 300,
height: 300
});
canvas.add(imgInstance);
}, 0);
}
});
"
# ui #########
ui <- fluidPage(
tags$head(
tags$script(
src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"
),
tags$script(HTML(js)),
tags$style(HTML(
"canvas {border: 1px solid #999;}
#myimage{display:none;}"))
),
titlePanel("Fabric Demo"),
sidebarLayout(
sidebarPanel(
h4("Side")
),
mainPanel(
tags$canvas(
width="800", height="800", id="drawarea", style="border: 1px solid red; float: right;"
),
imageOutput("divForImage")
)
)
)
## server #######
server <- function(input, output, session) {
output[["divForImage"]] <- renderImage({
outfile <- tempfile(fileext='.png')
# Generate a png
png(outfile, width=400, height=400)
hist(rnorm(20))
dev.off()
# Return a list
list(src = outfile,
alt = "This is alternate text",
id = "myimage")
}, deleteFile = TRUE)
}
shinyApp(ui=ui, server=server)
Note: don't use periods in ids, this can lead to some issues.
You have to trigger the JavaScript code after the image has been inserted by Shiny. Right now you a re firing the code as soon as the document is ready.
I would use shinyjs for this task and use the runjs and delay function, to wait until the list with the image is returned and visible in the HTML.
If you want to hide the image rendered by Shiny you need an # in the css (like #myimage)
Full Code:
library(shiny)
library(shinyjs)
js <- "
$(document).ready(function () {
var canvas = new fabric.Canvas('drawarea');
var imgElement = document.getElementById('myimage');
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 0,
opacity: 0.75,
width:300,
height:300
});
canvas.add(imgInstance);
});
"
# ui #########
ui <- fluidPage(
useShinyjs(),
tags$head(tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js", type="text/javascript")),
tags$head(
tags$style(HTML("canvas {border: 1px solid #999;}
#myimage{display:none;}"))
),
titlePanel("Fabric Demo"),
sidebarLayout(
sidebarPanel(
h4("Side")
),
mainPanel(
HTML('<canvas width="800" height="800" id="drawarea" style="border: 1px solid red;float: right"></canvas>'),
plotOutput("div.for.image")
)
)
)
## server #######
server <- function(input, output, session) {
output$div.for.image <- renderImage({
outfile <- tempfile(fileext='.png')
# Generate a png
png(outfile, width=400, height=400)
hist(rnorm(20))
dev.off()
delay(200, runjs(HTML(js)))
# Return a list
list(src = outfile,
alt = "This is alternate text",
id = "myimage")
}, deleteFile = TRUE)
}
shinyApp(ui=ui,server=server)
Closely related to this question, I am trying to move the showNotification´s to a certain div that is already on the page. Is there an easy way to do that?
The following app should illustrate the problem. The notifications in the lower right should go in the yellow div.
library(shiny)
ui=shinyUI(fluidPage(
tags$head(
tags$style(HTML("
#error {
width: 100%;
border: black 1px solid;
padding: 5px;
margin: 10px 0;
background-color: #f7f2d9;
}
"))
),
sidebarLayout(
sidebarPanel(
sliderInput("lambda","Number",min = 1,max = 100,value = 27)
),
mainPanel(
h3("Move the slider above 28 to trigger a Notification! "),
plotOutput("algebra"),
div(id = "error", p("The notifications should appear in here")),
tableOutput('table')
)
)
))
server=function(input, output) {
output$algebra <- renderPlot({
if (input$lambda > 28){
showNotification("How can I put this message in the #error div?", id = "error", type = "warning", duration = NULL)
return(NULL)
}
n <- 1:100
lambda <- seq(min(n), max(n), length.out = input$lambda)
plot((2*lambda)+3, type = "o",xlab= "X (number of data points)", ylab = "Y = 2x+3")
})
output$table <- renderTable(iris)
}
shinyApp(ui,server)
This seems to work:
library(shiny)
library(shinyjs)
ui=shinyUI(fluidPage(
useShinyjs(),
tags$head(
tags$style(HTML("
#error {
width: 100%;
border: black 1px solid;
padding: 5px;
margin: 10px 0;
background-color: #f7f2d9;
}
#shiny-notification-panel {
position: static;
}
"))
),
......
and in server:
output$algebra <- renderPlot({
if(input$lambda > 28){
showNotification("How can I put this message in the #error div?", type = "warning", duration = NULL)
runjs('setTimeout(function(){$("#error").append($("#shiny-notification-panel"))},0);')
return(NULL)
}
......
Not highly tested though. An alternative is bsAlert from the shinyBS package.
I have a shiny app where a datatable is displayed. There is a column with a checkbox that allows the user to select the row and when pressing a button a modal is displayed. The modal contains a table with a subset of the datatable including only the row selected (my real app triggers another function but the effect is the same)
However, when the user deselects the row and selects another row, the previous content in the model is displayed before being replaced with the new one.
Is there any way of resetting the model everytime the button is pressed?
Here is the code I am using:
library(shinydashboard)
library(shinydashboardPlus)
library(shiny)
library(flextable)
data(mtcars)
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
fluidPage(
tags$head(tags$style("#modal1 .modal-body {padding: 10px}
#modal1 .modal-content {-webkit-border-radius: 12px !important;-moz-border-radius: 12px !important;border-radius: 12px !important;}
#modal1 .modal-dialog { width: 800px; display: inline-block; text-align: left; vertical-align: top;}
#modal1 .modal-header {background-color: #339FFF; border-top-left-radius: 6px; border-top-right-radius: 6px}
#modal1 .modal { text-align: center; padding-right:10px; padding-top: 24px;}
#moda1 .close { font-size: 16px}")),
tags$script(HTML('$(".modal").on("hidden.modal1", function(){
$(this).removeData();
});'
)
),
fluidRow(
column(2,offset = 2,
HTML('<div class="btn-group" role="group" aria-label="Basic example">'),
actionButton(inputId = "Compare_row_head",label = "Get full data"),
HTML('</div>')
),
column(12,dataTableOutput("tabla")),
tags$script(HTML('$(document).on("click", "input", function () {
var checkboxes = document.getElementsByName("row_selected");
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}
}
Shiny.onInputChange("checked_rows",checkboxesChecked);})')
),
tags$script("$(document).on('click', '#Main_table button', function () {
Shiny.onInputChange('lastClickId',this.id);
Shiny.onInputChange('lastClick', Math.random())
});")
)
)
)
ui <- dashboardPagePlus(enable_preloader = TRUE, sidebar_fullCollapse = TRUE, header, sidebar, body)
## Server side
server = function(input, output, session) {
data("mtcars")
# Reactive function creating the DT output object
output$tabla <- renderDataTable({
req(mtcars)
data <- mtcars
data
data[["Select"]]<-paste0('<input type="checkbox" name="row_selected" value="Row',1:nrow(data),'"><br>')
datatable(data, escape = FALSE)
})
###Modal visualisation
observeEvent(input$Compare_row_head,{
showModal(tags$div(id="modal1", annotation_modal1))
}
)
annotation_modal1<-modalDialog(
fluidPage(
h3(strong("Example modal"),align="left"),
uiOutput('disTable')
),
size="l"
)
output$disTable <- renderUI({
req(input$checked_rows)
row_to_sel=as.numeric(gsub("Row","",input$checked_rows))
if (length(row_to_sel)){
#if (length(s)) {
#df <- vals$fake_sales
df <- mtcars
df <- as.data.frame(df[row_to_sel,])
ft <- flextable(df)
ft <- flextable::bold(ft, part="header")
ft <- flextable::autofit(ft)
ft <- flextable::width(ft, j=2, width=.1)
ft <- flextable::align(ft, align = "left", part = "all" )
ft %>% htmltools_value()
}
})
} # Server R
shinyApp(ui, server)
In the code pasted above I have tried to reset the modal using this:
tags$script(HTML('$(".modal").on("hidden.modal1", function(){
$(this).removeData();
});'
)
)
But it doesn't work
Thanks
The problem here is, that disTable only is rendered when your modalDialog is triggered (not already when the boxes are checked).
We can force shiny to render disTable earlier (when input$checked_rows is changed) by setting:
outputOptions(output, "disTable", suspendWhenHidden = FALSE)
Please check the following:
library(shinydashboard)
library(shinydashboardPlus)
library(shiny)
library(DT)
library(flextable)
data(mtcars)
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
fluidPage(
tags$head(tags$style("#modal1 .modal-body {padding: 10px}
#modal1 .modal-content {-webkit-border-radius: 12px !important;-moz-border-radius: 12px !important;border-radius: 12px !important;}
#modal1 .modal-dialog { width: 800px; display: inline-block; text-align: left; vertical-align: top;}
#modal1 .modal-header {background-color: #339FFF; border-top-left-radius: 6px; border-top-right-radius: 6px}
#modal1 .modal { text-align: center; padding-right:10px; padding-top: 24px;}
#moda1 .close { font-size: 16px}")),
fluidRow(
column(2,offset = 2,
HTML('<div class="btn-group" role="group" aria-label="Basic example">'),
actionButton(inputId = "Compare_row_head",label = "Get full data"),
HTML('</div>')
),
column(12,dataTableOutput("tabla")),
tags$script(HTML('$(document).on("click", "input", function () {
var checkboxes = document.getElementsByName("row_selected");
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}
}
Shiny.onInputChange("checked_rows",checkboxesChecked);})')
),
tags$script("$(document).on('click', '#Main_table button', function () {
Shiny.onInputChange('lastClickId',this.id);
Shiny.onInputChange('lastClick', Math.random())
});")
)
)
)
ui <- dashboardPagePlus(enable_preloader = TRUE, sidebar_fullCollapse = TRUE, header, sidebar, body)
## Server side
server = function(input, output, session) {
data("mtcars")
# Reactive function creating the DT output object
output$tabla <- renderDataTable({
req(mtcars)
data <- mtcars
data
data[["Select"]]<-paste0('<input type="checkbox" name="row_selected" value="Row',1:nrow(data),'"><br>')
datatable(data, escape = FALSE)
})
###Modal visualisation
observeEvent(input$Compare_row_head,{
showModal(tags$div(id="modal1", annotation_modal1))
}
)
annotation_modal1 <- modalDialog(
fluidPage(
h3(strong("Example modal"), align="left"),
uiOutput('disTable')
),
size="l"
)
output$disTable <- renderUI({
req(input$checked_rows)
row_to_sel=as.numeric(gsub("Row", "", input$checked_rows))
if (length(row_to_sel)){
#if (length(s)) {
#df <- vals$fake_sales
df <- mtcars
df <- as.data.frame(df[row_to_sel,])
ft <- flextable(df)
ft <- flextable::bold(ft, part="header")
ft <- flextable::autofit(ft)
ft <- flextable::width(ft, j=2, width=.1)
ft <- flextable::align(ft, align = "left", part = "all" )
ft %>% htmltools_value()
}
})
outputOptions(output, "disTable", suspendWhenHidden = FALSE)
} # Server R
shinyApp(ui, server)
I am working on a shiny app that takes a long time to do calculations, I want to have a modal progress bar that closes automatically as soon as all calculations work.
The ideal solution would have two features
Covers most of the screen and prevents the user to interact with app
Closes automatically as soon as it finishes making calulations
I found this solution in the following question:
library("shiny")
library("shinyWidgets")
ui <- fluidPage(
actionButton(inputId = "go", label = "Launch long calculation"), #, onclick = "$('#my-modal').modal().focus();"
# You can open the modal server-side, you have to put this in the ui :
tags$script("Shiny.addCustomMessageHandler('launch-modal', function(d) {$('#' + d).modal().focus();})"),
tags$script("Shiny.addCustomMessageHandler('remove-modal', function(d) {$('#' + d).modal('hide');})"),
# Code for creating a modal
tags$div(
id = "my-modal",
class="modal fade", tabindex="-1", `data-backdrop`="static", `data-keyboard`="false",
tags$div(
class="modal-dialog",
tags$div(
class = "modal-content",
tags$div(class="modal-header", tags$h4(class="modal-title", "Calculation in progress")),
tags$div(
class="modal-body",
shinyWidgets::progressBar(id = "pb", value = 0, display_pct = TRUE)
),
tags$div(class="modal-footer", tags$button(type="button", class="btn btn-default", `data-dismiss`="modal", "Dismiss"))
)
)
)
)
server <- function(input, output, session) {
value <- reactiveVal(0)
observeEvent(input$go, {
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 0) # reinitialize to 0 if you run the calculation several times
session$sendCustomMessage(type = 'launch-modal', "my-modal") # launch the modal
# run calculation
for (i in 1:10) {
Sys.sleep(0.5)
newValue <- value() + 1
value(newValue)
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 100/10*i)
}
Sys.sleep(0.5)
# session$sendCustomMessage(type = 'remove-modal', "my-modal") # hide the modal programmatically
})
}
shinyApp(ui = ui, server = server)
This solves issue 1, but I have to click on dismiss to see the results
The original progressbar provided in shiny is exactly what you need.
But I use css to make the progessbar display in the middle in the screen.
You can find the detail of using progress bar in shiny here.
library("shiny")
ui <- fluidPage(
actionButton(inputId = "go", label = "Launch long calculation"), #, onclick = "$('#my-modal').modal().focus();"
# css to center the progress bar
tags$head(
tags$style(
HTML(".shiny-notification {
height: 100px;
width: 800px;
position:fixed;
top: calc(50% - 50px);
left: calc(50% - 400px);
font-size: 250%;
text-align: center;
}
"
)
)
)
)
server <- function(input, output, session) {
value <- reactiveVal(0)
observeEvent(input$go, {
withProgress(message = 'Calculation in progress', value = 0,detail="0%", {
# run calculation
for (i in 1:10) {
Sys.sleep(0.5)
newValue <- value() + 1
value(newValue)
incProgress(1/10,detail = paste0(i*10,"%"))
}
Sys.sleep(0.5)
})
})
}
shinyApp(ui = ui, server = server)
Not a whole answer, just answering the additional css requests. You could change the css to, which will make the panel fill up the whole page.
.shiny-notification {
height: 100%;
width: 100%;
top: 0;
left: 0;
position:fixed;
font-size: 250%;
text-align: center;
background-color: rgba(0, 0, 0, 0.7);
color: white;
}
I made a simple example to show my problem, which is:
how to set notifications at different places independently of each others (let's say I want each notification to be displayed at the top right and left, respectively)
```
library(shiny)
ui <- fluidPage(
# tags$head(
# tags$style(
# HTML(".shiny-notification {
# position: fixed;
# top: 800px;
# left: 40px;
# width: 15em;
# opacity: 1;
# }
# "
# )
# )
# )
actionButton("showme", "Show Notification:")
)
server <- function(input, output, session) {
observe({
showNotification(
id = "welcome_notif",
"Blablablablabla .... blablablabla.",
duration = 20,
closeButton = TRUE,
type = "message")
})
observeEvent(input$showme,{
showNotification(
id = "showme_notif",
"Hihihi", # put text in notification
duration = 30,
closeButton = TRUE,
type = "message")
})
}
shinyApp(ui = ui, server = server)
```
I saw that there is a special CSS for notification in shiny code (https://github.com/rstudio/shiny/blob/master/inst/www/shared/shiny.css).
If I change the CSS class (as shown in commented code), I only manage to change the place where all notifications will be displayed (but not independently).
EDIT:
I tried to use addClass with shinyjs:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
inlineCSS(list(.customclass = "position: fixed; top: 200px;")),
actionButton("showme", "Show Notification:")
)
server <- function(input, output, session) {
observe({
showNotification(
id = "welcome_notif",
"Blablablablabla .... blablablabla.",
duration = 20,
closeButton = TRUE,
type = "message")
})
observeEvent(input$showme,{
showNotification(
id = "showme_notif",
"Hihihi", # put text in notification
duration = 30,
closeButton = TRUE,
type = "message")
})
observe({
addClass(id = "showme_notif", class = "customclass")
})
}
shinyApp(ui = ui, server = server)
as suggested by Florian (see below) but it seems that I can only handle elements generated in UI and not in server like notifications.
For example this works:
if (interactive()) {
shinyApp(
ui = fluidPage(
useShinyjs(),
inlineCSS(list(.customclass = "position: fixed; top: 200px;")),
p(id = "element", "Watch what happens to me")
),
server = function(input, output) {
observe({
addClass(id = "element", class = "customclass")
})
}
)
}
I am able to modify the CSS of the element, since the notification gets the id: shiny-notifaction-xxx where xxx is the name of your notification. But all notifications are put together in another container, and I am unable to modify the CSS so that it does what you want.
library(shiny)
ui <- fluidPage(
tags$style("#shiny-notification-showme_notif {margin:20px;}"),
actionButton("showme", "Show Notification:")
)
server <- function(input, output, session) {
observe({
showNotification(
id = "welcome_notif",
"Blablablablabla .... blablablabla.",
duration = 200,
closeButton = TRUE,
type = "message")
})
observeEvent(input$showme,{
showNotification(
id = "showme_notif",
"Hihihi", # put text in notification
duration = 300,
closeButton = TRUE,
type = "message")
})
}
shinyApp(ui = ui, server = server)
So according to Florian, one answer could be:
library(shiny)
ui <- fluidPage(
tags$style("#shiny-notification-showme_notif {position: fixed; top: 800px; left: 40px; width: 15em; opacity: 1;}"),
tags$style("#shiny-notification-welcome_notif {position: fixed; top: 800px; right: 40px; width: 15em; opacity: 1;}"),
actionButton("showme", "Show Notification:")
)
server <- function(input, output, session) {
observe({
showNotification(
id = "welcome_notif",
"Blablablablabla .... blablablabla.",
duration = 200,
closeButton = TRUE,
type = "message")
})
observeEvent(input$showme,{
showNotification(
id = "showme_notif",
"Hihihi", # put text in notification
duration = 300,
closeButton = TRUE,
type = "message")
})
}
shinyApp(ui = ui, server = server)
and can be modified, as required.