I'm trying to remove the header row in a DT datatable, does anyone know if there's an option for doing this?
Minimal example:
#SERVER.R
output$myTable <- renderDataTable({
datatable(dataset, rownames = FALSE, selection = 'none', options = list(dom = 't'))
})
#UI.R
dataTableOutput('myTable')
Just add colnames = NULL to your datatable()
datatable(mtcars, rownames = FALSE,colnames=NULL, selection = 'none', options = list(dom = 't'))
See ?datatable
Sebastian's answer from Oct 28 '15 did not work for me inside renderDataTable(datatable(...)). Using colnames = NULL inside datatable(...) removed all data from the table. I had to use colnames = "" to remove the table headers.
Adding colnames = NULL no longer works and it renders an empty table. You can use headerCallBack option to add a css that hides the header row to achieve this.
headerCallback <- c(
"function(thead, data, start, end, display){",
" $('th', thead).css('display', 'none');",
"}"
)
datatable(mtcars,
rownames = FALSE,
colnames=NULL,
selection = 'none',
options = list(
dom = 't',
headerCallback = JS(headerCallback)
)
)
Related
I have some code that creates a DT table with radio buttons. On top of that I need to add particular colors to each row. I have been trying to use formatStyle too add a different color to each row but I haven't gotten the syntax correct.
Here is the working code:
library(shiny)
library(DT)
c1 = "This is comment 1"
c2 = "This is comment 2"
c3 = "This is comment 3"
c4 = "This is comment 4"
c5 = "This is comment 5"
comments1 = list(c1,c2,c3,c4,c5)
m1 = matrix(
as.character(1:5), nrow = 5, ncol = 1, byrow = FALSE,
dimnames = list(comments1, LETTERS[1])
)
for (i in seq_len(ncol(m1))) {
m1[, i] = sprintf(
'<input type="radio" name="%s" value="%s"/>',
'AValue', m1[,i]
)
}
callback1 <- c(
"var LETTERS = ['AValue'];",
"for(var i=0; i < LETTERS.length; ++i){",
" var L = LETTERS[i];",
" $('input[name=' + L + ']').on('click', function(){",
" var name = $(this).attr('name');",
" var value = $('input[name=' + name + ']:checked').val();",
" Shiny.setInputValue(name, value);",
" });",
"}"
)
ui <- fluidPage(
title = 'Radio buttons in a table',
DT::dataTableOutput('foo1'),
verbatimTextOutput('sel1'),
)
server <- function(input, output, session) {
output$foo1 = DT::renderDataTable(
m1, escape = FALSE, selection = 'none', server = FALSE,
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS(callback1),
)
output$sel1 = renderPrint({
input[["AValue"]]
})
}
shinyApp(ui, server)
Here are the some of the different variations of the calls that I have tried.
#formatStyle needs to be called on DT:datatable()
#Test adding formatStyle
output$foo1 <- DT::renderDataTable({
dat <- datatable(m1, escape = FALSE, selection = 'none',
options = list(dom = 't', paging = FALSE, ordering = FALSE))
callback = JS(callback1) %>% formatStyle(0, target='row', backgroundColor = styleEqual(3,'red'))
})
or
#Test adding formatStyle
output$foo1 <- DT::renderDataTable({
DT::datatable(m1,escape = FALSE, selection = 'none',
options = list(dom = 't', paging = FALSE, ordering = FALSE, callback = JS(callback1))
%>% formatStyle(0, target='row', backgroundColor = styleEqual(3,'red')))
})
Any help would be greatly appreciated.
Thanks!
You need to pass the table as an argument of the formatStyle. To do that inside the renderDataTable you can use the datatable function.
It seems that your condition to assign a color to a row is not going to match any row. You need to put something that could be in the column. Below is an example where an entire row has a red background when the content in column 0 is equal to "This is comment 3".
output$foo1 = DT::renderDataTable({
DT::datatable(
m1, escape = FALSE, selection = 'none',
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS(callback1)
) %>% formatStyle(0, target='row', backgroundColor = styleEqual('This is comment 3','red'))
}, server = FALSE
)
Perhaps you can define a new column with row_numbers and assign colors to the rows of interest. You can make the row_num column not visible. Try this
mycolors <- c('green','pink','red','yellow','orange')
output$foo1 = DT::renderDataTable({
m2 <- as.data.frame(m1) %>% dplyr::mutate(row_num = 1:n())
datatable( m2, escape = FALSE,
selection = 'none',
extensions = c("Select", "Buttons"),
callback = JS(callback1), ### needs double-click to select the radiobutton
options = list(dom = 't', paging = FALSE, ordering = FALSE,
columnDefs = list(list(visible=FALSE, targets=2))
)
) %>% formatStyle(2,
target='row',
backgroundColor = styleEqual(c(1:5),mycolors))
}, server = FALSE,
#callback = JS(callback1) ### does not recognize input[["AValue"]]
)
I am trying to place a button inside the datatable where if the user wants to reset the sorted column they can hit the button and table gets reset or changed to it's original order. At the moment, when I press the button, it is not triggering any event on click. The event should replace the data in the server part.
I am currently following these posts:
shiny DT datatable - reset filters
https://github.com/rstudio/DT/issues/76
Reset a DT table to the original sort order
However, in the last two posts above, even though they get the job done, the button is not part of the datatable.
Here is my reprex:
library(DT)
library(shiny)
library(shinyjs)
# function placed in the global.R
clearSorting <- function(proxy) {
shinyjs::runjs(paste0("$('#' + document.getElementById('", proxy$id,"').getElementsByTagName('table')[0].id).dataTable().fnSort([]);"))
}
# ui.R
ui <- fluidPage(
DT::DTOutput(outputId = "table"),
shinyjs::useShinyjs()
)
# servcer.R
server <- function(input, output) {
output$table <- renderDT({
DT::datatable(data = iris,
filter = 'top',
extensions = c('Buttons'),
options = list(scrollY = 600,
scrollX = TRUE,
autoWidth = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
buttons = list(
list(
extend = '',
text = 'Reset Table',
action = JS("function() {document.getElementById('reset_sort').click();}")
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE))
})
observeEvent(input$reset_sort, {
data <- iris
clearSorting(proxy = DT::dataTableProxy(outputId = "table"))
DT::replaceData(proxy = DT::dataTableProxy(outputId = "table"),
data = data,
rownames = FALSE)
})
}
shinyApp(ui = ui, server = server)
Here is a way:
library(DT)
js <- c(
"function(e, dt, node, config){",
" dt.iterator('table', function(s){",
" s.aaSorting.length = 0;",
" s.aiDisplay.sort(function(a,b){",
" return a-b;",
" });",
" s.aiDisplayMaster.sort(function(a,b){",
" return a-b;",
" });",
" }).draw();",
"}"
)
datatable(
iris,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
list(
extend = "collection",
text = "Reset columns order",
action = JS(js)
)
)
)
)
To use it in Shiny, you may need to set server = FALSE in renderDT:
output$table <- renderDT({
......
}, server = FALSE)
The DT package in Shiny produces a table with a searchbar that searches over every column in the table. I have a column of metadata which I do not want to display in the table, but I still want the rows to come up if I search with the search bar.
For example, the app below contains a column titled searchCol . This column is just letters. I want to hide this column in the actual table, and I want to be able to search for the letter b , using the DT search bar, and have the second row show up.
Is there a way to hide the column but have it still work with the search bar?
library(shiny)
library(DT)
ui <- fluidPage(
DTOutput('tbl1'),
)
server <- function(input, output, session) {
output$tbl1 <- DT::renderDT(server = TRUE, {
datatable(
cbind(data.frame(replicate(3,sample(0:1,26,rep=TRUE))), data.frame(searchCol = letters)),
escape = FALSE,
rownames = FALSE,
filter = list(position = "top", clear = FALSE, plain = TRUE),
selection = "single",
options = list(
autoWidth = TRUE,
pageLength = 50,
lengthMenu = c(50, 100, 1000),
dom = 'Blfrtip',
buttons = c('copy', 'excel')
)
)
})
}
shinyApp(ui, server)
I've adapted the answer from here to the format you need to use in DT::datatable. You can use columnDefs to define the render options for the different columns, targets defines which column you mean. Please note that the JS library datatables starts counting columns at 0.
library(shiny)
library(DT)
ui <- fluidPage(
DTOutput('tbl1'),
)
server <- function(input, output, session) {
output$tbl1 <- DT::renderDT(server = TRUE, {
datatable(
cbind(data.frame(replicate(3,sample(0:1,26,rep=TRUE))), data.frame(searchCol = letters)),
escape = FALSE,
rownames = FALSE,
filter = list(position = "top", clear = FALSE, plain = TRUE),
selection = "single",
options = list(
autoWidth = TRUE,
pageLength = 50,
lengthMenu = c(50, 100, 1000),
dom = 'Blfrtip',
buttons = c('copy', 'excel'),
columnDefs = list(
list(
targets = 3,
searchable = TRUE,
visible = FALSE
)
)
)
)
})
}
shinyApp(ui, server)
I have an editable datatable which is paginated as follows :
d1 = file.df
output$file.df_data<-DT::renderDataTable(
d1,selection = 'none', editable = list(target = "cell", disable = list(columns = c(which(names(d1) != "product_type")-1))),
rownames = FALSE,
extensions = 'Buttons',
options = list(
paging = TRUE,
searching = TRUE,
fixedColumns = TRUE,
autoWidth = TRUE,
ordering = TRUE,
dom = 'Bfrtip',
buttons = c('csv', 'excel')
),
class = "display"
)
When I make an edit on the current page, move to some other page, and then return to the previous page the edits that I had made on the page disappear. How can I make the edits persist across the pages?
Following is the code I am using to observe edits-
observeEvent(input$file.df_data_cell_edit, {
d1[input$file.df_data_cell_edit$row,input$file.df_data_cell_edit$col+1] <<- input$file.df_data_cell_edit$value
})
You have to use a proxy and the editData function:
library(shiny)
library(DT)
ui <- basicPage(
br(),
DTOutput("dtable")
)
server <- function(input, output, session){
dat <- iris
output[["dtable"]] <- renderDT({
datatable(dat, editable = TRUE)
})
proxy <- dataTableProxy("dtable")
observeEvent(input[["dtable_cell_edit"]], {
info <- input[["dtable_cell_edit"]]
dat <<- editData(dat, info, proxy)
})
}
shinyApp(ui, server)
Is there a way to have the selected row(s) in a shiny datatable (DT) be available for the user to copy (Ctrl+C) to their clipboard. Ideally it would also supply the data table's column names or headers.
UPDATE
global.R
library(rclipboard)
library(shiny)
ui.R:
...
rclipboardSetup(),
...
uiOutput("copy"),
server.R:
output$copy = renderUI({
s = input$orders_rows_selected
rclipButton("copybtm","Copy",data()[s,],icon("clipboard"))
})
Here is how to get a button to copy the selected rows. And there are the column headers too.
datatable(
iris,
rownames = FALSE,
extensions = c("Buttons", "Select"),
options =
list(
select = TRUE,
dom = "Bfrtip",
buttons = list(
list(
extend = "copy",
text = 'Copy',
exportOptions = list(modifier = list(selected = TRUE))
)
)
)
)