render option inside renderDT conditional on Input selection in shiny - r

When using renderDT with buttons to download the data table, it can be set to download the whole data table, or only the data shown in the current view of the table. I would like to be able to set one way or the other based on the value of one of the input selections by the user.
In the example below, as it is, when clicking on the copy, pdf, or excel buttons, you only get the table in the current view (50 records). If I had render = TRUE in renderDT, then you would download the 200 records for that Type (see example). I would like it to be that when the selection is Type 1, the download would be of only the 50 records in the view, but when Type 2 is selected then it would download all the 200 records for Type 2.
library(shiny)
library(shinydashboard)
library(ggplot2)
library(data.table)
library(DT)
library(dplyr)
library(leaflet)
library(scales)
library(shinythemes)
# UI -----------------------------------------------------------------------------------
dataCM <- data.table(variable = 1:400,
type = c(rep('Type 1', 200), rep('Type 2', 200)))
ui <- fluidPage(
dashboardPage(
# Header ================================
dashboardHeader(
title = span(h3('Shiny App')
)
),
# Side bar ==============================
dashboardSidebar(width = 250,
sidebarMenu(id = 'sidebar',
# Tabs #
menuItem('Table', tabName = 'tables', icon = icon('bars'))
),
fluidRow(
box(width = 12, background = 'black',
radioButtons(inputId = 'checksubspecialty',
label = 'Choose Row',
choices = list('Type 1',
'Type 2')))
)
),
# Body ==================================
dashboardBody(
tabItems(
tabItem(tabName = 'tables',
fluidRow(
box(width = 12,
DTOutput('tableSurg')))
))
)
)
)
# Server --------------------------------------------------------------------------------
server <- function(input, output) {
data_subset <- reactive({
req(input$checksubspecialty)
dataM <- data.table(dataCM %>% filter(type %in% input$checksubspecialty))
dataM
})
output$tableSurg <- renderDT( # adding render = TRUE or FALSE in here is what sets if the download is of all or only the viewed data
{
dt <- data_subset()
dt
},
rownames = FALSE,
extensions = 'Buttons',
options = list(
pageLength = 50,
scrollY= '500px',
scrollX = TRUE,
dom = 'Bfrtip',
columnDefs = list(list(className = 'dt-left', targets = '_all')),
buttons = list(
list(extend = 'copy', title = "Title"),
list(extend = 'excel', title = "Title"),
list(extend = 'pdf', title = "Title")
)
))
}
# Run the application -------------------------------------------------------------------
shinyApp(ui = ui, server = server)

Try this
# Server --------------------------------------------------------------------------------
server <- function(input, output) {
data_subset <- reactive({
req(input$checksubspecialty)
dataM <- data.table(dataCM %>% filter(type %in% input$checksubspecialty))
dataM
})
TORF <- reactive({
if (input$checksubspecialty == "Type 1") TRUE else FALSE
})
output$tableSurg <- renderDT( server = TORF(), # adding server = TRUE or FALSE in here is what sets if the download is of all or only the viewed data
{
dt <- data_subset()
dt
},
rownames = FALSE,
extensions = 'Buttons',
options = list(
pageLength = 50,
scrollY= '500px',
scrollX = TRUE,
dom = 'Bfrtip',
columnDefs = list(list(className = 'dt-left', targets = '_all')),
buttons = list(
list(extend = 'copy', title = "Title"),
list(extend = 'excel', title = "Title"),
list(extend = 'pdf', title = "Title")
)
))
}

Related

Error in $: object of type 'closure' is not subsettable shiny R

I have problem with my Shiny App.
In my app I have many DT, Boxes, sometimes DT in Box so I decided to create functions to do my code more clean.
My function to create DT get data which I want to visualize
My function to create Box get title of box, information if is should be
collapsed, and UI - what box should contain (for example few
elements like
fluidRow(
column(6, uiOutput("aaa")),
column(6, uiOutput("bbb"))
)
I also created function to create DT in Box which is based on the previously described functions.
As I understand, the problem is the way data is transferred, but I cannot solve it.
I prepared example of functionality I would like to achieve but doesn't work.
library(shiny)
library(shinydashboard)
library(DT)
Create_DT <- function(dataSource){
datatable(
dataSource,
rownames = FALSE,
selection = 'none',
class = 'cell-border stripe',
extensions = 'Buttons',
options = list(
buttons = list('copy', 'print', list(extend = 'collection',buttons = c('csv', 'excel', 'pdf'),text = 'Download')),
dom = 'Bfrtip',
info = FALSE,
lengthChange = FALSE,
paging = FALSE,
searching = FALSE,
scrollX = TRUE,
columnDefs = list(list(className = 'dt-center', targets = "_all"))
)
) %>% formatStyle(colnames(dataSource),"white-space"="nowrap")
}
Create_Box <- function(description, collapsed, ui){
box(
width = 12,
title = strong(description),
color = "primary",
collapsible = TRUE,
collapsed = collapsed,
ui
)
}
Create_DTinBox <- function(description, collapsed, ui){
Create_Box(description, collapsed, ui)
}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
uiOutput("result")
)
)
server <- function(input, output){
reactiveValues(iris = iris)
output$result <- renderUI({
Create_DTinBox(
description = "test",
collapsed = TRUE,
ui = column(6, offset = 3, Create_DT(reactiveValues$iris))
)
})
}
shinyApp(ui, server)
Any Idea how this app should look like to work fine while maintaining the structure of the function from the example?
You need to render the datatable. Also, your reactiveValues need to be defined properly. Try this
library(shiny)
library(shinydashboard)
library(DT)
Create_DT <- function(dataSource){
datatable(
dataSource,
rownames = FALSE,
selection = 'none',
class = 'cell-border stripe',
extensions = 'Buttons',
options = list(
buttons = list('copy', 'print', list(extend = 'collection',buttons = c('csv', 'excel', 'pdf'),text = 'Download')),
dom = 'Bfrtip',
info = FALSE,
lengthChange = FALSE,
paging = FALSE,
searching = FALSE,
scrollX = TRUE,
columnDefs = list(list(className = 'dt-center', targets = "_all"))
)
) %>% formatStyle(colnames(dataSource),"white-space"="nowrap")
}
Create_Box <- function(description, collapsed, ui){
box(
width = 12,
title = strong(description),
color = "primary",
collapsible = TRUE,
collapsed = collapsed,
ui
)
}
Create_DTinBox <- function(description, collapsed, ui){
Create_Box(description, collapsed, ui)
}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
uiOutput("result")
)
)
server <- function(input, output){
rv <- reactiveValues(df = iris)
output$result <- renderUI({
Create_DTinBox(
description = "test",
collapsed = TRUE,
ui = column(8, offset = 3, renderDT(Create_DT(rv$df)))
)
})
}
shinyApp(ui, server)

How can I change the name inside the downloaded file with DataTable Extensions in Shiny?

I have create a Shiny App where I can download my table in various file formats (pdf, excel, csv). However, I have found that each of them has the same title that my Shiny App has ("This is my table in Shiny").
I use this extension from DataTable.
Does anyone know if I can delete that title from the downloaded files?
This is how my app looks.
These are the downloaded files (excel and pdf)
My code:
library(shiny)
library(DT)
ui <- fluidPage(
# Application title
titlePanel("This is my table in Shiny")
, mainPanel(
DT::dataTableOutput("fancyTable")
)
)
server <- function(input, output) {
output$fancyTable <- DT::renderDataTable(
datatable( data = mtcars
, extensions = 'Buttons'
, options = list(
dom = "Blfrtip"
, buttons =
list("copy", list(
extend = "collection"
, buttons = c("csv", "excel", "pdf")
, text = "Download"
) )
, lengthMenu = list( c(10, 20, -1)
, c(10, 20, "All")
)
, pageLength = 10
)
)
)
}
# Run the application
shinyApp(ui = ui, server = server)
Thanks in advance
Regards
Trying a lot of things and searching another posts... I found the solution!
I needed to put each option into a list to be able to add the "title" parameter for each one.
library(shiny)
library(DT)
ui <- fluidPage(
# Application title
titlePanel("This is my table in Shiny")
, mainPanel(
DT::dataTableOutput("fancyTable")
)
)
server <- function(input, output) {
output$fancyTable <- DT::renderDataTable(
datatable( data = mtcars
, extensions = 'Buttons'
, options = list(
dom = "Blfrtip",
buttons =
list("copy", list(
extend = "collection",
buttons = list(
list(extend = "csv", title = "MY TITLE"),
list(extend = "excel", title = "MY TITLE"),
list(extend = "pdf", title = "MY TITLE")),
text = "Download"
)),
lengthMenu = list( c(10, 20, -1)
, c(10, 20, "All")
),
pageLength = 10
)
)
)
}
# Run the application
shinyApp(ui = ui, server = server)
Here you can see the new title!

Wide datatables causing scrollx to scroll back when applying filters

I am able to render a datatable in my shiny app. However, whenever there is a wide table, the horizontal scroller gets back to it's initial position when you apply filters on the columns in the back. This issue occurs with numeric columns only.
I was wondering if there is a way I can disable range-based filters (but keep the filters itself) or if there is any other workaround for this problem.
I have searched github issues and stackoveflow prior to posting this question here since I couldn't find anybody having this problem.
Here is a reproducible example along with pictures-
options(scipen = 99999) #converts the sci numbers to their regular format
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinythemes)
library(writexl)
library(dplyr)
library(DT)
library(dplyr)
mtcars_modified <- mtcars %>% dplyr::mutate(wt_2= wt,
qsec_2 = qsec,
am_2= am,
mpg_2= mpg,
gear_2 = gear,
carb_2 = carb,
disp_2 = disp,
row_names_col= rownames(mtcars))
ui <- fluidPage(
theme = shinythemes::shinytheme("simplex"),
shinyjs::useShinyjs(), # enables javascript/jQuery enhanchments
# Create Right Side Text
navbarPage(
id = "navbar",
title= div(HTML("G<em>T</em>")),
#windowTitle = "GT",
tabPanel("Data Set Info",
materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 1,
"iris"= 2,
"mtcars_modified" = 3),
icon= icon("check"),
selected = 1,
status = "success",
animation="smooth"
),
br(),
br()
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel1", "navigation"
),
tabPanelBody(
"panel2",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel1_data')),
tabPanel("Summary", verbatimTextOutput("panel1_sum")),
tabPanel(
"Plot"
)
)
),
tabPanelBody(
"panel3",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel3_data')),
tabPanel("Summary", verbatimTextOutput("panel3_sum")),
tabPanel(
"Plot"
)
)
)
)
)
)
) ,
#resizes the navbar tabs/button
tags$head(tags$style(HTML('.navbar-brand {width: 270px; font-size:35px; text-align:left;
font-family: "serif";')))
)
)
server <- function(input, output, session) {
# this event hides the side panel when toggled on/off
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
if(!isTRUE(input$toggleSidebar)) {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-8').addClass('col-sm-12')")
} else {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-12').addClass('col-sm-8')")
}
})
# here we put all the data
data_sets <- list(df1 = data.frame(),
df2= iris,
df3 = mtcars_modified)
# store current dataset in reactive so we can work with plot panels
data_to_use <- reactiveValues(name = "df", data = data.frame())
observeEvent(input$controller, {
# skip first panel since it is used to display navigation
updateTabsetPanel(session, inputId= "hidden_tabs", selected = paste0("panel", input$controller))
# enswure value is avilable throught selected tabSet
req(input$controller)
# get current data and df name
data_to_use$data <- data_sets[[as.numeric(input$controller)]]
data_to_use$name <- names(data_sets[as.numeric(input$controller)])
# update table and sum
output[[paste0('panel', input$controller, '_data')]] <-
DT::renderDT(server = FALSE, {
DT::datatable(data_to_use$data,
filter = 'top',
extensions = 'Buttons',
options = list(scrollY = 600,
scrollX = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
lengthMenu= list(c(10, 25, 50, -1),
c('10', '25', '50','All')),
buttons = list(
list(extend = "collection", text = "Download",
filename = "data_excel",
exportOptions = list(
modifier = list(page = "all")
),
action = DT::JS("function ( e, dt, node, config ) {
Shiny.setInputValue('Download_DATA', true, {priority: 'event'});}"
)
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE,
rownames = TRUE))})
output[[paste0('panel', input$controller, '_sum')]] <- renderPrint(summary(data_to_use$data))
})
}
#runs the app
shinyApp(ui= ui, server= server)

How to fix filter options not popping up for esquisserUI in Shiny?

I have some requests for my app.
{1} After readjusting the mainPanel, esquisserUI filters are not popping up anymore. Here is the working example which I followed https://dreamrs.github.io/esquisse/articles/shiny-usage.html
In addition, I also looked at this GitHub issue, however it was for disabling the filters: https://github.com/dreamRs/esquisse/issues/71
And final request regarding general information:
{2} what does server = FALSE will do for huge datasets? (https://rstudio.github.io/DT/server.html) DT recommends to leave it as default to TRUE state, however if I do that, I don't get the full data upon download. I only get the data in the current page. Are there problems you foresee?
Thank you, here is a reproducible example.
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(esquisse)
library(shinythemes)
library(xlsx)
library(DT)
# Credit: #Iz100 helped me a lot with UI.
ui <- fluidPage(
theme = shinytheme("simplex"),
useShinyjs(),
# Create Right Side Text
navbarPage(
title= div(HTML("G<em>T</em>")),
tabPanel("Data Set Info",
materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 1,
"iris"= 2,
"mtcars" = 3),
icon= icon("check"),
selected = 1,
status = "success",
animation="smooth"
),
br(),
br(),
a(actionButton(inputId = "admin_email", label = "Contact Admin",
icon = icon("envelope", lib = "font-awesome")),
href="mailto:my_awesome_email_address.com")
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel1", "navigation"
),
tabPanelBody(
"panel2",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel1_data')),
tabPanel("Summary", verbatimTextOutput("panel1_sum")),
tabPanel(
"Plot",
esquisserUI(
id = "esquisse2",
header = FALSE,
choose_data = FALSE
)
)
)
),
tabPanelBody(
"panel3",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel3_data')),
tabPanel("Summary", verbatimTextOutput("panel3_sum")),
tabPanel(
"Plot",
esquisserUI(
id = "esquisse3",
header = FALSE,
choose_data = FALSE
)
)
)
)
)
)
)
) ,
#resizes the navbar tabs/button
tags$head(tags$style(HTML('.navbar-brand {width: 270px; font-size:35px; text-align:left;}')))
)
)
server <- function(input, output, session) {
# this event hides the side panel when toggled on/off
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
if(!isTRUE(input$toggleSidebar)) {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-8').addClass('col-sm-12')")
} else {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-12').addClass('col-sm-8')")
}
})
myModal <- function() {
div(id = "Download_DATA",
modalDialog(easyClose = TRUE,
title = "Alert!",
"Please remove all the filters if you want a full dataset.",
br(),
br(),
downloadButton("download_excel","Download as XLSX")
)
)
}
# here we put all the data
data_sets <- list(df1 = data.frame(),
df2= iris,
df3 = mtcars)
# store current dataset in reactive so we can work with plot panels
data_to_use <- reactiveValues(name = "df", data = data.frame())
# modules only need to be called it once but individually for esquisse
callModule(
module = esquisserServer,
id = "esquisse2",
data = data_to_use
)
callModule(
module = esquisserServer,
id = "esquisse3",
data = data_to_use
)
observeEvent(input$controller, {
# skip first panel since it is used to display navigation
updateTabsetPanel(session, inputId= "hidden_tabs", selected = paste0("panel", input$controller))
# enswure value is avilable throught selected tabSet
req(input$controller)
# get current data and df name
data_to_use$data <- data_sets[[as.numeric(input$controller)]]
data_to_use$name <- names(data_sets[as.numeric(input$controller)])
# update table and sum
output[[paste0('panel', input$controller, '_data')]] <- DT::renderDT(server = FALSE, {
DT::datatable(data_to_use$data,
filter = 'top',
extensions = 'Buttons',
options = list(scrollY = 600,
scrollX = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
lengthMenu= list(c(10, 25, 50, -1),
c('10', '25', '50','All')),
buttons = list(
list(extend = "collection", text = "Download",
filename = "data_excel",
exportOptions = list(
modifier = list(page = "all")
),
action = DT::JS("function ( e, dt, node, config ) {
Shiny.setInputValue('Download_DATA', true, {priority: 'event'});}"
)
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE,
rownames = TRUE))})
output[[paste0('panel', input$controller, '_sum')]] <- renderPrint(summary(data_to_use$data))
})
# observes if download is clicked
observeEvent(input$Download_DATA, {
showModal(myModal())
})
# writes to an excel file
output$download_excel <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".xlsx", sep="")
},
content = function(file) {
write.xlsx(data_to_use$data, file, row.names = FALSE)
}
)
}
#runs the app
shinyApp(ui= ui, server= server)
1. I checked the HTML of esquisserUI, they give all dropdowns the same IDs if you use multiple esquisserUI. This is a big NO in HTML development and will cause a lot of issues. They call it a module, but they didn't follow Shiny module guidelines where to use NS() for all UI IDs. The easy proof is try this below. Then uncomment the second set of esquisserUI and esquisserServer and try again. You will find the dropdown no longer works.
library(esquisse)
ui <- fluidPage(
esquisserUI(
id = "esquisse1",
header = FALSE,
choose_data = FALSE
)#,
# esquisserUI(
# id = "esquisse2",
# header = FALSE,
# choose_data = FALSE
# )
)
server <- function(input, output, session) {
data_to_use <- reactiveValues(data = iris, name = "iris")
callModule(
module = esquisserServer,
id = "esquisse1",
data = data_to_use
)
# callModule(
# module = esquisserServer,
# id = "esquisse2",
# data = data_to_use
# )
}
shinyApp(ui, server)
Currently there is no straight fix for this unless you ask them to fix it. We need to use a workaround:
I added a new tab to the main panel called "plot" which is the esquisserUI, and two buttons in the data panel so when you click on the button, it will jump you to the plot panel with the right data.
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(esquisse)
library(shinythemes)
library(xlsx)
library(DT)
# Credit: #Iz100 helped me a lot with UI.
ns <- NS("myapp")
ui <- fluidPage(
theme = shinytheme("simplex"),
useShinyjs(),
# Create Right Side Text
navbarPage(
title= div(HTML("G<em>T</em>")),
tabPanel("Data Set Info",
materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 1,
"iris"= 2,
"mtcars" = 3,
"plots" = 4),
icon= icon("check"),
selected = 1,
status = "success",
animation="smooth"
),
br(),
br(),
a(actionButton(inputId = "admin_email", label = "Contact Admin",
icon = icon("envelope", lib = "font-awesome")),
href="mailto:my_awesome_email_address.com")
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel1", "navigation"
),
tabPanelBody(
"panel2",
tabsetPanel(
tabPanel(
"Data", DT::DTOutput('panel2_data'),
actionButton("plot2", "Plot iris")
),
tabPanel("Summary", verbatimTextOutput("panel2_sum"))
)
),
tabPanelBody(
"panel3",
tabsetPanel(
tabPanel(
"Data", DT::DTOutput('panel3_data'),
actionButton("plot3", "Plot mtcars")
),
tabPanel("Summary", verbatimTextOutput("panel3_sum"))
)
),
tabPanelBody(
"panel4",
esquisserUI(
id = "esquisse",
header = FALSE,
choose_data = FALSE
)
)
)
)
)
),
#resizes the navbar tabs/button
tags$head(tags$style(HTML('.navbar-brand {width: 270px; font-size:35px; text-align:left;}')))
)
)
server <- function(input, output, session) {
# this event hides the side panel when toggled on/off
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
if(!isTRUE(input$toggleSidebar)) {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-8').addClass('col-sm-12')")
} else {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-12').addClass('col-sm-8')")
}
})
myModal <- function() {
div(id = "Download_DATA",
modalDialog(easyClose = TRUE,
title = "Alert!",
"Please remove all the filters if you want a full dataset.",
br(),
br(),
downloadButton("download_excel","Download as XLSX")
)
)
}
# here we put all the data
data_sets <- list(df1 = data.frame(),
df2= iris,
df3 = mtcars)
# store current dataset in reactive so we can work with plot panels
data_to_use <- reactiveValues(name = "df", data = data.frame())
# modules only need to be called it once but individually for esquisse
callModule(
module = esquisserServer,
id = "esquisse",
data = data_to_use
)
# go to plot panel if plot button clicked
observeEvent(c(input$plot2, input$plot3), {
updatePrettyRadioButtons(session, "controller", selected = 4)
}, ignoreInit = TRUE)
observeEvent(input$controller, {
# skip first panel since it is used to display navigation
updateTabsetPanel(session, inputId= "hidden_tabs", selected = paste0("panel", input$controller))
# enswure value is avilable throught selected tabSet
# only render data if data panels are selected
req(input$controller %in% 2:3)
# get current data and df name
data_to_use$data <- data_sets[[as.numeric(input$controller)]]
data_to_use$name <- names(data_sets[as.numeric(input$controller)])
# update table and sum
output[[paste0('panel', input$controller, '_data')]] <- DT::renderDT(server = FALSE, {
DT::datatable(data_to_use$data,
filter = 'top',
extensions = 'Buttons',
options = list(scrollY = 600,
scrollX = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
lengthMenu= list(c(10, 25, 50, -1),
c('10', '25', '50','All')),
buttons = list(
list(extend = "collection", text = "Download",
filename = "data_excel",
exportOptions = list(
modifier = list(page = "all")
),
action = DT::JS("function ( e, dt, node, config ) {
Shiny.setInputValue('Download_DATA', true, {priority: 'event'});}"
)
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE,
rownames = TRUE))})
output[[paste0('panel', input$controller, '_sum')]] <- renderPrint(summary(data_to_use$data))
})
# observes if download is clicked
observeEvent(input$Download_DATA, {
showModal(myModal())
})
# writes to an excel file
output$download_excel <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".xlsx", sep="")
},
content = function(file) {
write.xlsx(data_to_use$data, file, row.names = FALSE)
}
)
}
#runs the app
shinyApp(ui= ui, server= server)
2. So server = TRUE only sends a very small portion of the entire dataset to UI for large ones. When you scroll or jump pages, new data will be sent. This saves time and has better performance. If it is FALSE, all data will be sent at once. Imagine you need to load a 2GB table in your browser everytime you start the app, how slow will it be. For small datasets, you can leave it FALSE.
Updates
It seems esquisse people fixed the bug. Install the develop version and then:
ui <- fluidPage(
esquisse_ui(
id = "esquisse1",
header = FALSE
),
esquisse_ui(
id = "esquisse2",
header = FALSE
)
)
server <- function(input, output, session) {
data_to_use <- reactiveValues(data = iris, name = "iris")
esquisse_server(id = "esquisse1", data_rv = data_to_use)
esquisse_server(id = "esquisse2", data_rv = data_to_use)
}
shinyApp(ui, server)

RShiny - When printing the table from renderDT it prints the HTML code for the title instead of just the title

In my shiny app I want to be able to create an excel or pdf from a table. I am using renderDT to create the table, and buttons inside options in that function to have that feature. ON the shiny app once it is ran, when clicking on the pdf button the table prints well, but the title on top of it shows the HTML code for the title, instead of the title itself. There are other ways to create the title but I am doing it in a specific way so I can add a logo to the title.
Here is some sample code:
library(shiny)
library(shinydashboard)
library(data.table)
library(DT)
library(tableHTML)
# Data
Op_dataGen <- data.table(Var1 = 1:100,
Var2 = sample(letters, 100, replace = TRUE))
ui <- fluidPage(
tags$style(".main-sidebar {padding-top: 74px}"),
tags$head(tags$style(
HTML('
.skin-blue .main-header .logo {background-color:#1F3758; font-size:auto; display:contents;
font-weight:bold; }
.skin-blue .main-header .logo b {color:#fff; font-size:auto; font-weight:bold;}
'
))),
dashboardPage(
# a) header
dashboardHeader(
title = span(img(src="logo.png", width = 250), tags$b('Organization Title')),
tags$li(tags$style(".main-header {max-height: 74px}"),
tags$style(".main-header .logo {height: 74px, width: 90px}"),
class = "dropdown")
),
dashboardSidebar(width=250,
sidebarMenu(id = 'sidebar',
#Tabs#
menuItem('View Table', tabName = 'table'))
),
# c) body
dashboardBody(
fluidRow(
tabItems(
tabItem(tabName = 'table',
box(width = 12,
title = 'Total NumberTable',
DTOutput('TableG'))
))))
)
)
server <- shinyServer(function(input, output) {
TableG <- copy(Op_dataGen)
output$TableG <- renderDT({
TableG
},
rownames = FALSE,
extensions = 'Buttons',
options = list(
pageLength = 100,
scrollY = '360px',
scrollX = TRUE,
dom = 'Bfrtip',
buttons = c('copy', 'excel', 'pdf')
)
)
})
shinyApp(ui = ui, server = server)
You can set the title you want like this:
output$TableG <- renderDT({
datatable(
TableG,
rownames = FALSE,
extensions = "Buttons",
options = list(
pageLength = 100,
scrollY = '360px',
scrollX = TRUE,
dom = 'Bfrtip',
buttons = list(
list(extend = "copy", title = "TheTitleYouWant"),
list(extend = "excel", title = "TheTitleYouWant"),
list(extend = "pdf", title = "TheTitleYouWant")
)
)
)
})

Resources