This is a follow up question to this
With this app we use a button to take a screenshot.
This takes a while, so I would like to implement a loader to the app.
For doing this without js
code is not a problem for me, but I can't get it to work with js
code.
Here is a minimal working example:
After clicking the Export to pdf
button, there should be a loader shown. I tried shinycssloaders
but had no succes:
library(shiny)
library(shinyWidgets)
js <- "
function Export(){
var $img = $('#img');
var width = $img.width();
var height = $img.height();
domtoimage.toPng($('html')[0])
.then(function (blob) {
var pdf = new jsPDF('p', 'mm', 'a4');
var imgProps = pdf.getImageProperties(blob);
var pdfWidth = pdf.internal.pageSize.width;
var pdfHeight = pdf.internal.pageSize.height;
var widthRatio = pdfWidth / width;
var heightRatio = pdfHeight / height;
var ratio = Math.min(widthRatio, heightRatio);
var w = imgProps.width * ratio;
var h = imgProps.height * ratio;
pdf.addImage(blob, 'PNG', 0, 0, w, h);
pdf.save('allPage.pdf');
});
}
"
ui <- fluidPage(
tags$head(
tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"),
tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"),
tags$script(HTML(js))
),
#background image
tags$img(id = "img",
src = "http://upload.wikimedia.org/wikipedia/commons/5/5d/AaronEckhart10TIFF.jpg",
style = 'position: absolute; width: 1250px; height: 880px;'),
div(
id = "container1",
style = "position: absolute; left: 30px; top: 170px; display: inline-block; vertical-align: middle; width: 300px;",
actionButton("export", "Export to PDF",
onclick = "Export();")
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
CodePudding user response:
You can set input values via javascript from the client. So you can toggle an input variable, say 'busyWithPDF' between states 0 and 1 by placing these lines in your UI javascript part:
js <- "
function Export(){
Shiny.setInputValue('busyWithPDF', 1)
// code to prepare PDF
// ...
// pdf.save('allPage.pdf');
Shiny.setInputValue('busyWithPDF', 0)
}
"
and use this input value, e.g to show/hide a conditional panel (which you could decorate with an infinite input loader)
shiny::conditionalPanel(condition = 'input.busyWithPDF',
div(class = 'well well-info',
h1('preparing PDF')
)
)