I have rather simple application (below) where I try to output grouped table using DataTable with the ability to collapse the groups. I found solution in that is implemented in jQuery here but I have no idea how such plex implementation could be moved into R.
Currently, I am able to collapse within a group but not the whole group itself. Any hints how this could be implemented in Shiny?
My application:
library(shiny)
library(DT)
library(shinyjs)
ui <- fluidPage(
# Application title
titlePanel("Collapse/Expand table"),
mainPanel(
DTOutput("my_table")
)
)
server <- function(input, output) {
output$my_table<-DT::renderDataTable({
datatable(mtcars[1:15,1:5],
extensions = 'RowGroup',
options = list(rowGroup = list(dataSrc=c(3)),
pageLength = 20),
callback = JS("
table.on('click', 'tr', function () {
var rowsCollapse = $(this).nextUntil('.group');
$(rowsCollapse).toggleClass('hidden');
});"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
EDIT
Given AEF ment one can adjust the code to specify that even has to take place once table body is clicked. This indeed collapses any rows until next group. The remaining part is to restrict the clicks only onto group rows. The callback should be now:
callback = JS("$('#DataTables_Table_0 tbody').on('click', 'tr', function () {
$(this).nextUntil('.group').toggleClass('hidden');});"))
I have rather simple application (below) where I try to output grouped table using DataTable with the ability to collapse the groups. I found solution in that is implemented in jQuery here but I have no idea how such plex implementation could be moved into R.
Currently, I am able to collapse within a group but not the whole group itself. Any hints how this could be implemented in Shiny?
My application:
library(shiny)
library(DT)
library(shinyjs)
ui <- fluidPage(
# Application title
titlePanel("Collapse/Expand table"),
mainPanel(
DTOutput("my_table")
)
)
server <- function(input, output) {
output$my_table<-DT::renderDataTable({
datatable(mtcars[1:15,1:5],
extensions = 'RowGroup',
options = list(rowGroup = list(dataSrc=c(3)),
pageLength = 20),
callback = JS("
table.on('click', 'tr', function () {
var rowsCollapse = $(this).nextUntil('.group');
$(rowsCollapse).toggleClass('hidden');
});"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
EDIT
Given AEF ment one can adjust the code to specify that even has to take place once table body is clicked. This indeed collapses any rows until next group. The remaining part is to restrict the clicks only onto group rows. The callback should be now:
callback = JS("$('#DataTables_Table_0 tbody').on('click', 'tr', function () {
$(this).nextUntil('.group').toggleClass('hidden');});"))
Share
edited Oct 20, 2024 at 15:23
Jan
10.2k6 gold badges21 silver badges33 bronze badges
asked Jan 24, 2020 at 12:46
An economistAn economist
1,3111 gold badge17 silver badges35 bronze badges
4
-
1
I don't know much about javascript so I haven't been able to figure it out, so I will tell you where I think is the problem: when you click on the grouping rows of the datatable, if you look at the browser's console there will be an error message: Uncaught TypeError: Cannot read property 'row' of undefined. I remend to add the
javascript
tag to your question to see if you can get extra help, maybe a question on github./rstudio/DT? – David Jorquera Commented Jan 24, 2020 at 20:27 -
It seems the problem is that the event handler is attached to the table itself and not to the rows. So its seems teh second argument you give to the
on
function is not respected. – AEF Commented Jan 27, 2020 at 13:58 - Thank you for the ment, indeed you were right. Adjusting the callback allows to collapse any row. Now I just have to figure out how to limit the event to only group rows. – An economist Commented Jan 27, 2020 at 15:05
- Can someone please help with the issue posted here. stackoverflow./questions/60401871/… – Ankita Chowdhury Commented Feb 25, 2020 at 21:00
4 Answers
Reset to default 6 +100It turns out to be a bug of DT's javascript code. There's a click event listener that will record all the info of the clicked cells. However, the RowGroup extension creates a new row that doesn't belong to the original datasets and leads to an error. This error stops the further javascript executions.
In your cases, the tr.group
event doesn't work because of the error thrown from the previous cell-click event.
We've fixed this bug and the dev version of DT should work with the below code:
library(shiny)
library(DT)
ui <- fluidPage(# Application title
titlePanel("Collapse/Expand table"),
mainPanel(DTOutput("my_table")))
callback_js <- JS(
"table.on('click', 'tr.dtrg-group', function () {",
" var rowsCollapse = $(this).nextUntil('.dtrg-group');",
" $(rowsCollapse).toggleClass('hidden');",
"});"
)
server <- function(input, output) {
output$my_table <- DT::renderDT({
datatable(
mtcars[1:15, 1:5],
extensions = 'RowGroup',
options = list(rowGroup = list(dataSrc = 3), pageLength = 20),
callback = callback_js,
selection = 'none'
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Thanks again for you reports!
Ticker to the Github issue of DT: https://github./rstudio/DT/issues/759
Just one other note on this. I noticed that in a standard fluidPage etc, this worked as expected. However, it stopped working when I started using it in an htmlTemplate.
Somewhere along the way, it loses the .hidden
class and I had to manually add it.
.hidden {
display: none !important;
}
Then it worked as expected.
Thanks to the AEF ment I was able to boil down the problem. The event has to occur one user clicks on the body $('#DataTables_Table_0 tbody')
and only on rows with group identifier 'tr.group'
.
The final callback has to be adjusted to take both of those conditions into account.
Therefore application with collapsable rows looks as follows:
library(shiny)
library(DT)
library(shinyjs)
ui <- fluidPage(
# Application title
titlePanel("Collapse/Expand table"),
mainPanel(
DTOutput("my_table")
)
)
server <- function(input, output) {
output$my_table<-DT::renderDataTable({
datatable(mtcars[1:15,1:5],
extensions = 'RowGroup',
options = list(rowGroup = list(dataSrc=c(3)),
pageLength = 20),
callback = JS("
$('#DataTables_Table_0 tbody').on('click', 'tr.group', function () {
var rowsCollapse = $(this).nextUntil('.group');
$(rowsCollapse).toggleClass('hidden');
});"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
As mentioned by @David Joequera in the ments this is a JavaScript error, where one of the default event Handlers of Datatable throws an Error because the row porperty doesn't exist in the Group row.
As a work around we can remove this event handler so that the one for hiding will work.
Also i would remend you to only target the group rows with the event handler so that you can only fully close and open the groups and can not semi hide groups. You can achieve this by simply adding a ".group" to your event Listener Target. Resulting in this code:
table.on('click', 'tr.group', function () {
var rowsCollapse = $(this).nextUntil('.group');
$(rowsCollapse).toggleClass('hidden');
})
In order to remove the event Handler we will need to wait until the table is properly loaded and the problematic event handler is atached so I would remend working with a small timeout. 1000 ms worked fine for me and should not bring any usability issues. so adding this code to the Callbacks should fix the issue:
setTimeout(function(){$('#DataTables_Table_0').off('click.dt','tbody td')},1000);
Be aware that the the ID of the DataTable to delete might change in your final/real solution
Resulting in this code for the demo:
library(shiny)
library(DT)
library(shinyjs)
ui <- fluidPage(
# Application title
titlePanel("Collapse/Expand table"),
mainPanel(
DTOutput("my_table")
),
)
server <- function(input, output) {
output$my_table<-DT::renderDataTable({
datatable(mtcars[1:15,1:5],
extensions = 'RowGroup',
options = list(rowGroup = list(dataSrc=c(3)),
pageLength = 20),
callback = JS("
setTimeout(function(){$('#DataTables_Table_0').off('click.dt','tbody td')},1000);
table.on('click', 'tr.group', function () {
var rowsCollapse = $(this).nextUntil('.group');
$(rowsCollapse).toggleClass('hidden');
});"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744809647a4594989.html
评论列表(0条)