add shinyWidgets into datatable in R - shiny

I am currently trying to add nice user input from shinyWidgets into a DT datatable.
I tried to follow the example from DT github with the radioButtons, which is working fine :
library(DT)
library(shinyWidgets)
m = data.frame(matrix(
as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE,
dimnames = list(month.abb, LETTERS[1:5])
), stringsAsFactors = F)
for (i in seq_len(nrow(m))) {
m[i, ] = sprintf(
'<input type="radio" name="%s" value="%s"/>',
month.abb[i], m[i, ]
)
}
datatable(m, escape = FALSE, options = list(dom = 't', paging = FALSE, ordering = FALSE))
I would like now to have a sixth column with a likert scale, just like presented here : http://shinyapps.dreamrs.fr/shinyWidgets/
The div information is given when the command is executed in the R console. So I tried to add it just like the radioButtons :
library(DT)
library(shinyWidgets)
m = data.frame(matrix(
as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE,
dimnames = list(month.abb, LETTERS[1:5])
), stringsAsFactors = F)
for (i in seq_len(nrow(m))) {
m[i, ] = sprintf(
'<input type="radio" name="%s" value="%s"/>',
month.abb[i], m[i, ]
)
}
m$new_input <- NA
for (i in seq_len(nrow(m))) {
m[i, 6] = sprintf(
'<div class="form-group shiny-input-container">
<label class="control-label" for="Id102">Your choice:</label>
<input class="js-range-slider sw-slider-text" data-data-type="text" data-force-edges="true" data-from="0" data-from-fixed="false" data-from-shadow="false" data-grid="true" data-hide-min-max="false" data-keyboard="true" data-prettify-enabled="false" data-swvalues="["Strongly disagree","Disagree","Neither agree nor disagree","Agree","Strongly agree"]" data-to-fixed="false" data-to-shadow="false" id="%s"/>
</div>',
paste("slider",month.abb[i], sep = "_")
)
}
datatable(m, escape = FALSE, options = list(dom = 't', paging = FALSE, ordering = FALSE))
Unfortunately, this is clearly not giving the input from shinyWidgets.
Any idea ?

Here is an example.
library(shiny)
library(shinyWidgets)
library(DT)
ui <- fluidPage(
br(),
DTOutput("dt"),
br(),
tags$label("Slider1:"),
verbatimTextOutput("choice1"),
tags$label("Slider2:"),
verbatimTextOutput("choice2")
)
sti <- function(id){
as.character(sliderTextInput(
inputId = id,
label = "Your choice:",
grid = TRUE,
force_edges = TRUE,
choices = c("Disagree", "Agree"))
)
}
js <- c(
"function(settings){",
" $('[id^=slider]').each(function(){",
" $(this).ionRangeSlider({values: $(this).data('swvalues')});",
" });",
"}"
)
server <- function(input, output){
dat <- data.frame(
word = c("hello", "goodbye"),
status = c(sti("slider1"), sti("slider2"))
)
output[["dt"]] <- renderDT({
dtable <- datatable(dat, escape = FALSE,
callback = JS(c('Shiny.unbindAll(table.table().node());',
'Shiny.bindAll(table.table().node());')),
options = list(
initComplete = JS(js)
))
dep1 <- htmltools::htmlDependency(
"ionrangeslider", "2.1.6",
src = "www/shared/ionrangeslider",
script = "js/ion.rangeSlider.min.js",
stylesheet = c("css/ion.rangeSlider.css", "css/ion.rangeSlider.skinShiny.css"),
package = "shiny")
dep2 <- htmltools::htmlDependency(
"strftime", "0.9.2",
src = "www/shared/strftime",
script = "strftime-min.js",
package = "shiny")
dep3 <- htmltools::htmlDependency(
"shinyWidgets", "0.4.5",
src = "www",
script = "shinyWidgets-bindings.min.js",
stylesheet = "shinyWidgets.css",
package = "shinyWidgets")
dtable$dependencies <- c(dtable$dependencies, list(dep1,dep2,dep3))
dtable
}, server = FALSE)
output[["choice1"]] <- renderPrint(input[["slider1"]])
output[["choice2"]] <- renderPrint(input[["slider2"]])
}
shinyApp(ui, server)

Related

Toggle actionButton color (between Orange & Green) on click within Shiny DT and create new data frame from selected rows

I am developing a Shiny App, where the user can upload data, do some manipulations & create new df from selected rows. I have got till where I can add actionButtons per row in DT but cant make selections work. Selections work as expected if actionButtons are not included in the DT rows. What am I looking for?
1. To be able to toggle between two colors on click within each of the DT row (Orange = not selected; Green = selected, when clicked)
2. Create new data frame from selected rows of the datatable on another actionButton click (Ex: Category 01 or Category 02).
Once any of the Category 01 or Category 02 actionButton is clicked. I get this error Error: incorrect number of dimensions. As shown at the bottom of Image 2.
I have added reproducible code below.
Any help is much appreciated
As in screenshot1, actionbuttons are Orange And in screenshot2 they are Green ,
Data
data <- data.frame(Name = rep(paste("RIS", 1:20, sep = "_")),
Gender = rep(c("Male", "Female"), each = 10),
CDC = rnorm(20),
FDC = rnorm(20),
RDC = rnorm(20),
LDC = rnorm(20)
)
Example Code
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("simpleApp"),
sidebarLayout(
sidebarPanel(fileInput("file1", "Upload Input file", accept = ".csv"), width = 2,
actionButton("calc", "Calculate"),
hr(style = "border-color: red; height: 5px"),
actionButton("gen1", "Category 01"),
actionButton("gen2", "Category 02")),
mainPanel (
dataTableOutput("table"),
dataTableOutput("table2"),
dataTableOutput("select_table1"),
dataTableOutput("select_table2"))))
server <- function(input, output, session) {
addButtonColumn <- function(df, id, ...) {
f <- function(i) {
as.character(
actionButton(paste(id, i, sep = "_"), class = "btn-warning btn-sm", label = tags$strong("Select"),
onclick = 'Shiny.setInputValue(\"addPressed\", this.id, {priority: "event"})'))
}
addCol <- unlist(lapply(seq_len(nrow(df)), f))
DT::datatable(cbind(Decision = addCol, df),
escape = FALSE, filter = "top", options = list(columnDefs = list(list(targets = 1, sortable = FALSE))))
}
data <- reactive({
df <- input$file1
if(is.null(df))
return(NULL)
df <- read.csv(df$datapath, header = TRUE, sep = ",", row.names = NULL)
return(df)
})
output$table <- DT::renderDataTable(data(), options = list(paging = t, pageLength = 6))
table2 <- eventReactive(input$calc, {
df2 <- input$file1
if(is.null(df2))
return(NULL)
table2 <- data() %>%
mutate("Selection" = CDC * RDC + FDC * LDC) %>%
mutate(across(where(is.numeric), round, 3)) %>%
addButtonColumn("Button")
})
output$table2 <- DT::renderDataTable(table2(), options = list(paging = t, pageLength = 6))
select_table1 <- eventReactive(input$gen1, {
if(is.null(table2)){
return(NULL)
} else {
select_table1 <- table2()[input$table2_rows_selected,]
}
})
select_table2 <- eventReactive(input$gen2, {
if(is.null(table2)){
return(NULL)
} else {
select_table2 <- table2()[input$table2_rows_selected,]
}
})
output$select_table1 <- DT::renderDataTable(select_table1(), options = list(paging = t, pageLength = 6))
output$select_table2 <- DT::renderDataTable(select_table2(), options = list(paging = t, pageLength = 6))
}
shinyApp(ui = ui, server = server)
Some simple CSS can do it.
You called DT::datatable too early in the eventReactive. You need to call it within renderDataTable, otherwise, the render function can't recognize it properly (it can, but table2_rows_selected will not work).
df <- data.frame(Name = rep(paste("RIS", 1:20, sep = "_")),
Gender = rep(c("Male", "Female"), each = 10),
CDC = rnorm(20),
FDC = rnorm(20),
RDC = rnorm(20),
LDC = rnorm(20)
)
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("simpleApp"),
sidebarLayout(
sidebarPanel(fileInput("file1", "Upload Input file", accept = ".csv"), width = 2,
actionButton("calc", "Calculate"),
hr(style = "border-color: red; height: 5px"),
actionButton("gen1", "Category 01"),
actionButton("gen2", "Category 02")),
mainPanel (
dataTableOutput("table"),
dataTableOutput("table2"),
dataTableOutput("select_table1"),
dataTableOutput("select_table2"))),
tags$style(
'
table.dataTable tr.selected button {
background-color: green;
border-color: green;
}
'
)
)
server <- function(input, output, session) {
addButtonColumn <- function(df, id, ...) {
f <- function(i) {
as.character(
actionButton(paste(id, i, sep = "_"), class = "btn-warning btn-sm", label = tags$strong("Select"),
onclick = 'Shiny.setInputValue(\"addPressed\", this.id, {priority: "event"})'))
}
addCol <- unlist(lapply(seq_len(nrow(df)), f))
cbind(Decision = addCol, df)
}
data <- reactive({
df
})
output$table <- DT::renderDataTable(data(), options = list(paging = t, pageLength = 6))
table2 <- eventReactive(input$calc, {
df2 <- df
if(is.null(df2))
return(NULL)
data() %>%
mutate("Selection" = CDC * RDC + FDC * LDC) %>%
mutate(across(where(is.numeric), round, 3)) %>%
addButtonColumn("Button")
})
output$table2 <- DT::renderDataTable(DT::datatable(
table2(), escape = FALSE, filter = "top",
options = list(columnDefs = list(list(targets = 1, sortable = FALSE, paging = t, pageLength = 6)))
))
select_table1 <- eventReactive(input$gen1, {
if(is.null(table2)){
return(NULL)
} else {
print(input$table2_rows_selected)
select_table1 <- table2()[input$table2_rows_selected,]
}
})
select_table2 <- eventReactive(input$gen2, {
if(is.null(table2)){
return(NULL)
} else {
select_table2 <- table2()[input$table2_rows_selected,]
}
})
output$select_table1 <- DT::renderDataTable(DT::datatable(select_table1(), escape = FALSE, options = list(paging = t, pageLength = 6)))
output$select_table2 <- DT::renderDataTable(select_table2(), escape = FALSE, options = list(paging = t, pageLength = 6))
}
shinyApp(ui = ui, server = server)
Disabled your uploading part. You need to change it back.

highchart not rending in rshiny but is working in my directory

I am trying to reproduce the decomposed time series plot with highchart.
The result is perfect in the working directory of r but when I put it in r shiny no result comes out.
Here is my code
library(shinyjs)
library(shiny)
library(shinydashboard)
library(highcharter)
library(forecast)
shinyOptions(bslib = TRUE)
bs_global_theme()
bs_theme_base_colors(bg = "#002B36", fg = "#EEE8D5")
bs_theme_accent_colors(primary = "#2AA198")
thematic::thematic_shiny()
ui<-fluidPage(
theme=shinytheme("cerulean"),
themeSelector(),
useShinyjs(),
navbarPage(
title= "Stock exchange", position = "static-top",
id="nav",
tabPanel("Single stock analysis",value = "single_stock", icon = icon("chart-area"),
sidebarLayout(
div(id = "Sidebar",
sidebarPanel(width = 3, align = "center",
selectInput("ticker",
strong("Ticker"),
# quotes$Symbole,
choices = c("AirPassengers", "ttrc"),
selectize = TRUE
),
dateRangeInput("date", strong("Select data range"),
start = "2012-01-01", end = (Sys.Date()-1)
),
tags$br(),
fluidPage(column(width = 3, "Session")
)
)),
mainPanel(
fluidRow(align = "center",
selectInput("hideorshow", label = strong("Sidebar disposition"),
choices = c("Show", "Hide"), selected = "Show")),
tabsetPanel(
tabPanel("Data structure and summary",
icon = icon("table"),
h1(align = "center",
strong(" STRUCTURE OF THE DATAFRAME ")),
tags$br(),tags$b(),class="fa fa-table",
verbatimTextOutput("struc"),
tags$br(),tags$br(),
h1(align = "center",strong(" SUMMARY OF THE DATAFRAME ")),
br(),verbatimTextOutput("summary1")
),
tabPanel("Dataset",icon = icon("tablet-alt"), DTOutput('tbl1')),
tabPanel("Plot",icon = shiny::icon('chart-bar'), br(),br(), br(),
airDatepickerInput(inputId = "date.ts",
strong("Time of the first observation"),
value = "2017-01-01",
minDate = "1998-09-16",
maxDate = Sys.Date(),
view = "months",
minView = "months",
dateFormat = "yyyy-mm"),
highchartOutput("closing_pr.ts",width = "auto", height = "600px"),
),
)
)
)),
tabPanel("Multiple stocks analysis", tabName = "mult_stock", icon = icon("th"))
)
)
I think the problem is hide in the server; exactely the renderHighchart but i can't find it. Please any help will be appreciate.
cs <- new.env()
dt_new <- eventReactive(c(input$ticker,input$date[1],input$date[2]), {
if (input$ticker =="AirPassengers"){
data(AirPassengers)
mydata1 <- AirPassengers
}
else if (input$ticker =="ttrc"){
data(ttrc)
mydata1 <- ttrc
}
mydata1
})
output$closing_pr.ts<-renderHighchart({
year.ts <- as.numeric(year(input$date.ts))
month.ts <- as.numeric(month(input$date.ts))
dc <- decompose(AirPassengers)
df <- as.data.frame(dc[c("x","trend","seasonal","random")])
df2 <- data.frame(Date = index(dc$x),
apply(df, 2, as.numeric))
names(df2) <- c("Date", "Observed", "Trend", "Seasonal", "Random")
df2$Date <- as.Date(yearmon(df2$Date))
df2 <- as.xts(df2[,-c(1)],
order.by = df2$Date)
df2 <- round(df2, digits = 3)
highchart(type = "stock") %>%
hc_title(text = "TIME SERIE DECOMPOSITION") %>%
hc_add_series(df2[, "Observed"], yAxis = 0, name = "Observed", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Observed"), relative = 2) %>%
hc_add_series(df2[, "Trend"], yAxis = 1, type = "line",name = "Trend", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Trend"), relative = 1)%>%
hc_add_series(df2[, "Seasonal"], yAxis = 2, type = "line",name = "Seasonal", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Seasonal"), relative = 2) %>%
hc_add_series(df2[, "Random"], yAxis = 3, type = "line", name = "Random", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Random"), relative = 1)%>%
hc_exporting(
enabled = TRUE, # always enabled,
filename = paste0("Closing price decomposition line charts from ",
min(index(df2)),
" to ", max(index(df2))))%>%
hc_colors(colors = c("blue", "red", "cyan", "darkgreen"))
})
observeEvent(input$hideorshow, {
if ( input$hideorshow== "Show") {
shinyjs::show(id = "Sidebar")}
else {shinyjs::hide(id = "Sidebar")}
})
output$summary1 <- renderPrint({
summary(dt_new())
})
output$struc<- renderPrint({
str(dt_new())
})
}
shinyApp(ui=ui, server = server)
Try this
library(shinyjs)
library(shiny)
library(shinydashboard)
library(highcharter)
library(forecast)
library(lubridate)
library(zoo)
library(xts)
shinyOptions(bslib = TRUE)
# bs_global_theme()
# bs_theme_base_colors(bg = "#002B36", fg = "#EEE8D5")
# bs_theme_accent_colors(primary = "#2AA198")
# thematic::thematic_shiny()
ui<-fluidPage(
#theme=shinytheme("cerulean"),
#themeSelector(),
useShinyjs(),
navbarPage(
title= "Stock exchange", position = "static-top",
id="nav",
tabPanel("Single stock analysis",value = "single_stock", icon = icon("chart-area"),
sidebarLayout(
div(id = "Sidebar",
sidebarPanel(width = 3, align = "center",
selectInput("ticker",
strong("Ticker"),
# quotes$Symbole,
choices = c("AirPassengers", "ttrc"),
selectize = TRUE
),
dateRangeInput("date", strong("Select data range"),
start = "2012-01-01", end = (Sys.Date()-1)
),
tags$br(),
fluidPage(column(width = 3, "Session")
)
)),
mainPanel(
fluidRow(align = "center",
selectInput("hideorshow", label = strong("Sidebar disposition"),
choices = c("Show", "Hide"), selected = "Show")),
tabsetPanel(
tabPanel("Data structure and summary",
icon = icon("table"),
h1(align = "center",
strong(" STRUCTURE OF THE DATAFRAME ")),
tags$br(),tags$b(),class="fa fa-table",
verbatimTextOutput("struc"),
tags$br(),tags$br(),
h1(align = "center",strong(" SUMMARY OF THE DATAFRAME ")),
br(),verbatimTextOutput("summary1")
),
tabPanel("Dataset",icon = icon("tablet-alt"), DTOutput('tbl1')),
tabPanel("Plot",icon = shiny::icon('chart-bar'), br(),br(), br(),
airDatepickerInput(inputId = "date.ts",
strong("Time of the first observation"),
value = "2017-01-01",
minDate = "1998-09-16",
maxDate = Sys.Date(),
view = "months",
minView = "months",
dateFormat = "yyyy-mm"),
highchartOutput("closing_prts",width = "auto", height = "600px"),
),
)
)
)),
tabPanel("Multiple stocks analysis", tabName = "mult_stock", icon = icon("th"))
)
)
server <- function(input, output, session){
cs <- new.env()
# dt_new <- eventReactive(c(input$ticker,input$date[1],input$date[2]), {
dt_new <- reactive({
if (input$ticker =="AirPassengers"){
data(AirPassengers)
print("Hello")
mydata1 <- AirPassengers
} else if (input$ticker =="ttrc"){
data(ttrc)
mydata1 <- ttrc
}
as.data.frame(mydata1)
})
df1 <- reactive({
year.ts <- as.numeric(year(input$date.ts))
month.ts <- as.numeric(month(input$date.ts))
dc <- decompose(AirPassengers)
df <- as.data.frame(dc[c("x","trend","seasonal","random")])
df2 <- data.frame(Date = index(dc$x),
apply(df, 2, as.numeric))
names(df2) <- c("Date", "Observed", "Trend", "Seasonal", "Random")
df2$Date <- as.Date(yearmon(df2$Date))
df2 <- as.xts(df2[,-c(1)],
order.by = df2$Date)
df2 <- round(df2, digits = 3)
df2
})
output$closing_prts <- renderHighchart({
df2 <- df1()
highchart(type = "stock") %>%
hc_title(text = "TIME SERIE DECOMPOSITION") %>%
hc_add_series(df2[, "Observed"], yAxis = 0, name = "Observed", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Observed"), relative = 2) %>%
hc_add_series(df2[, "Trend"], yAxis = 1, type = "line",name = "Trend", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Trend"), relative = 1)%>%
hc_add_series(df2[, "Seasonal"], yAxis = 2, type = "line",name = "Seasonal", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Seasonal"), relative = 2) %>%
hc_add_series(df2[, "Random"], yAxis = 3, type = "line", name = "Random", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Random"), relative = 1)%>%
hc_exporting(
enabled = TRUE, # always enabled,
filename = paste0("Closing price decomposition line charts from ",
min(index(df2)),
" to ", max(index(df2))))%>%
hc_colors(colors = c("blue", "red", "cyan", "darkgreen"))
})
observeEvent(input$hideorshow, {
if ( input$hideorshow== "Show") {
shinyjs::show(id = "Sidebar")}
else {shinyjs::hide(id = "Sidebar")}
})
output$tbl1 <- renderDT({datatable(dt_new())})
output$summary1 <- renderPrint({
summary(dt_new())
})
output$struc<- renderPrint({
str(dt_new())
})
}
shinyApp(ui, server)

get user chosen choice from selectInput Shiny and store it as a string

I want to fetch user choice from selectInput and store it as a string to be use as filename to save a plot. If user change selectInput choice, the string variable should also update to reflect change.
Here are my code so far and the xxx variable obviously is not a string. Can anyone assist?
pacman::p_load(dplyr, tidyverse, reshape, ggplot2, shiny, shinydashboard)
mtcars_colName <- colnames(mtcars)
x_coord <- mtcars_colName[c(1:2)]
y_coord <- mtcars_colName[c(3:7)]
#Put plots on shiny ui
ui <- dashboardPage(
dashboardHeader(title = 'mtcars data'),
dashboardSidebar(
sidebarMenu(
menuItem("mtcars data comparison", tabName = 'mtcars_data_comparison', icon = icon('dragon'))
)
),
dashboardBody(
tabItems(
tabItem('mtcars_data_comparison',
fluidPage(
downloadButton("downloadPlot", "Download mtcars plot"),
box(plotOutput('metrics_plot'), width = 8, height = '100%'),
box(selectInput('y_metrics', 'mtcars y-axis', choices = y_coord), width = 4),
box(selectInput('x_metrics', 'mtcars x-axis', choices = x_coord), width = 4)
),
)
)
)
)
server <- function(input, output, session){
mtcars_plot <- reactive({ggplot(mtcars, aes_string(x=input$x_metrics, y=input$y_metrics)) +
geom_jitter(width =0.05) +
scale_y_continuous(labels = scales::comma) +
theme(
axis.text.x = element_blank(),
axis.line = element_line(),
axis.ticks.x = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
})
output$metrics_plot <- renderPlot({
mtcars_plot()
})
rv <- reactiveValues(value_store = character())
observeEvent(input$y_metrics, {
rv$value_store <- input$y_metrics
})
output$download10XPlot <- downloadHandler(
file = paste(rv$value_store, '.pdf', sep=''),
content = function(file) {
sep <- switch(input$filetype, "csv" = ",", "tsv" = "\t")
# pdf(file = file, width = 11, height = 8.5)
pdf(file, sep = sep)
print(TenX_plot())
dev.off()}
)
}
shinyApp(ui, server)
We can try
output$download10XPlot <- downloadHandler(
file = function() {paste(isolate(input$y_seq_metrics), '.pdf', sep='')},
content = function(file) {
pdf(file = file, width = 11, height = 8.5)
print(TenX_plot())
dev.off()}
)

how can i use download button for download highchart in shiny

How can I use a download button instead of hc_exporting function to download a highchart in shiny?
library(shiny)
library(shinydashboard)
library(highcharter)
library(shinyWidgets)
RecruitmentFunneldb_struct <-
structure(list(
yyyy = c(2019L, 2019L, 2019L, 2019L, 2019L, 2019L),
stages = c(
"Phone Scrining",
"Interview",
"Offer",
"Pre-Onboarding",
"Post-Joining",
"Joined"
),
pop = c(8L, 25L, 23L, 32L, 8L, 4L)
),
row.names = c(NA,
6L),
class = "data.frame")
ui <-
dashboardPage(
dashboardHeader(
title = HTML("Analytic view - Recruitment"),
titleWidth = 280
),
dashboardSidebar(disable = T),
dashboardBody(fluidPage(fluidRow(
box(
title = fluidRow(
column(10, "Recruitment Funnel"),
column(
2,
align = "right",
downloadButton("download", label = NULL, class = "butt1"),
tags$head(
tags$style(
".butt1{display: inline-block;} .butt1{font-size: 20px;} .butt1{border: none;} .butt1{padding-top: 1px} .butt1{background-color: transperent .butt1{padding-right: 50px}}"
)
)
)
),
solidHeader = T,
width = 4,
collapsible = F,
highchartOutput("Recruitment_Funnel", height = "240px")
)
)))
)
server <- function(input, output, session) {
output$Recruitment_Funnel <- renderHighchart({
Reserve_Data <- RecruitmentFunneldb_struct %>% arrange(-pop)
Reserve_Data %>%
hchart("funnel", hcaes(x = stages, y = pop))
})
output$download <- downloadHandler(
filename = function() {
paste("Funnel", ".", "pdf")
},
content = function(file) {
pdf(file)
output$Recruitment_Funnel()
dev.off()
}
)
}
shinyApp(ui, server)

button inside. DT::datatable does not render properly

I am trying to convert cells in a DT:datatable into clickable buttons, which action is append a new tab on my shiny app.
I have been using this post R Shiny: Handle Action Buttons in Data Table as reference but in my case the buttons shows up like this:
My app is a bit more complicated but I will try to re-create the part that does not work
This is an shorter version of my data.frame
mut_genes <- structure(list(acc_num = c("BM0042985", "BM0393251", "BM0673028"), disease = c("Sucrase isomaltase deficiency", "Metachromatic leukodystrophy", "Fatal surfactant deficiency"), gene = c("SI", "ARSA", "ABCA3"), chrom = c("3q25.2-q26.2", "22q13.31-qter", "16p13.3"), genename = c("Sucrase-isomaltase", "arylsulfatase A", "ATP binding cassette subfamily A member 3"), gdbid = c("120377", "119007", "3770735"), omimid = c("609845", "607574", "601615"), amino = c("Leu-Pro", "Glu-Lys", "Met-Ile"), deletion = c(NA_character_, NA_character_, NA_character_), insertion = c(NA_character_, NA_character_, NA_character_), codon = c(341L, 331L, 1L), codonAff = c(341L, 331L, 1L), hgvs = c("1022T>C", "991G>A", "3G>C"), hgvsAll = c("1022TtoC | L341P", "991GtoA | E331K", "3GtoC | M1I"), dbsnp = c("rs267607049", NA, NA), chromosome = c("3", "22", "16"), startCoord = c(165060026L, 50626052L, 2326464L), endCoord = c(165060026L, 50626052L, 2326464L), inheritance = c("AR", "AR", "AR"), gnomad_AC = c(NA_integer_, NA_integer_, NA_integer_), gnomad_AF = c(NA_real_, NA_real_, NA_real_), gnomad_AN = c(NA_integer_, NA_integer_, NA_integer_), mutype = c("missense", "missense", "initiation"), pmid = c("10903344", "12809637", "16641205"), pmidAll = c(NA, NA, "24871971"), base = c("M", "M", "M"), clinvarID = c("1413", NA, NA), clinvar_clnsig = c("Pathogenic", NA, NA), gene_id = c("2073", "190", "10")), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
library(shiny)
library(shinyjs)
library(tidyverse)
library(DT)
sidebar <- dashboardSidebar(
selectInput("search", label = "Search Options:",
choices = c("General", "Gene", "Mutation", "Reference", "Phenotype"), selected = "Gene"),
sidebarMenu(id="siderbarmenu", sidebarMenuOutput("menu"))
)
header <- dashboardHeader()
body <- dashboardBody(
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }",
".shiny-output-error:after { visibility: hidden; }"),
#ui
shinyjs::useShinyjs(),
tabItems(
tabItem("search_general", h1("A was done")),
tabItem(
tabName = "search_exact_gene",
tabsetPanel(
id = "tabs",
tabPanel(
title = "Main Dashboard",
value = "gene1",
fluidRow(
column(12,dataTableOutput("tablafilt_paste_genes"))
)
)
)
)
)
)
ui <- dashboardPage(header, sidebar, body)
And Here is the server part
server <- function(input, output, session) {
output$menu <- renderMenu({
my_general = list(
menuItem("Búsqueda general", tabName="search_general"),
conditionalPanel("input.siderbarmenu == 'search_general'",
textInput(inputId = "search_terms", label = "Search terms"),
selectInput("search_fields", label="Search choices", choices=c("All Fields", "Gene symbol",
"Gene description", "Chromosomal location", "HGNC/OMIM/GDB/Entrez ID", "RefSeq transcript",
"Disease/phenotype", "Gene Ontology"), selected = "Gene symbol"),
actionButton("submit", "Submit query")
)
)
my_gene = list(
menuItem("Búsqueda por gene", tabName="search_exact_gene"),
textInput(inputId = "search_exact_symbol", label = "Exact gene symbol only"),
actionButton("submit3", "Submit query")
)
if(input$search=="General"){
menu = my_general
} else if (input$search=="Gene"){
menu = my_gene
}
sidebarMenu(menu)
})
filtrado <- reactive({
dataset <- input$submit3
glist <- isolate(input$search_exact_symbol)
datos <- filter(mut_genes, gene %in% glist)
shinyInput <- function(FUN, len, id, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), ...))
}
inputs
}
datos <- mutate(datos, Mutacion=shinyInput(
FUN = actionButton,
len = nrow(datos),
id = 'button_',
label = "Mutacion",
onclick = 'Shiny.onInputChange(\"select_button\", this.id)')
)
return(datos)
})
output$tablafilt_paste_genes <- DT::renderDataTable({
if(is.null(filtrado()))
return()
datos <- filtrado()
DT::datatable(datos, escape = FALSE,
rownames = FALSE,
style = 'bootstrap',
class = 'compact cell-border stripe hover',
filter = list(position = 'top', clear = FALSE),
extensions = c('Buttons', "FixedHeader", "Scroller"),
options = list(
stateSave = FALSE,
ordering = FALSE,
autoWidth = TRUE,
search = list(regex = TRUE, caseInsensitive = TRUE),
columnDefs = list(
list(
className = 'dt-center',
targets = 1:ncol(datos)-1L,
render = JS("function(data, type, row, meta) {",
"return type === 'display' && typeof data === 'string' && data.length > 10 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 10) + '...</span>' : data;",
"}")
)
),
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'font-size': '12px'});",
"}"),
sDom = '<"top">Brtp<"bottom">i', # remove search general box and keep the top filters
scrollX = TRUE,
deferRender=TRUE,
buttons = list('colvis'),
FixedHeader = TRUE,
pageLength = 25,
lengthMenu = list(c(25, 50, 100, -1), list('25', '50', '100', 'All'))
),
callback = JS('table.page(3).draw(false); "setTimeout(function() { table.draw(true); }, 300);"')) %>%
formatStyle(columns = colnames(.$x$data), `font-size` = "15px")
})
}
runApp(shinyApp(ui, server))
My ideal situation is recreate the acc_num column and make it a buttom clickable, but when I have tried with
shinyInput <- function(FUN, len, id, label,...) {
inputs <- character(len)
for (i in seq_len(len)) {
label <- datos$acc_num[i]
inputs[i] <- as.character(FUN(paste0(id, i), label=label, ...))
}
inputs
}
It happens the same, I still see the <button id => even when I set the datatable option escape to false
That's because of the quotes. Your render function generates <span title="<button id = "xxx" ...... and this causes the issue.
You don't want to apply the span to the buttons, so add the regex test !(/button/).test(data) in the conditions:
render = JS("function(data, type, row, meta) {",
"return type === 'display' && typeof data === 'string' && data.length > 10 && !(/button/).test(data) ? ",
"'<span title=\"' + data + '\">' + data.substr(0, 10) + '...</span>' : data;",
"}")