Свернуть rowGroup Shiny - PullRequest
       29

Свернуть rowGroup Shiny

1 голос
/ 24 января 2020

У меня довольно простое приложение (ниже), где я пытаюсь вывести сгруппированную таблицу, используя DataTable с возможностью свертывания групп. Я нашел решение в том, что оно реализовано в jQuery здесь , но я понятия не имею, как такая сложная реализация может быть перенесена в R.

В настоящее время я могу свернуть внутри группы, но не вся группа сама. Любые намеки, как это может быть реализовано в Shiny?

Мое приложение:

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)

РЕДАКТИРОВАТЬ

С учетом комментариев AEF можно настроить код на укажите, что даже это должно произойти после нажатия на таблицу body . Это действительно сворачивает любые строки до следующей группы. Оставшаяся часть - ограничить клики только по групповым строкам. Обратный вызов должен быть теперь:

callback = JS("$('#DataTables_Table_0 tbody').on('click', 'tr', function () {
 $(this).nextUntil('.group').toggleClass('hidden');});"))

Ответы [ 3 ]

2 голосов
/ 27 января 2020

Оказывается, ошибка в коде DT javascript. Есть слушатель события щелчка, который будет записывать всю информацию о щелчковых ячейках. Однако расширение RowGroup создает новую строку, которая не принадлежит исходным наборам данных и приводит к ошибке. Эта ошибка останавливает дальнейшее выполнение javascript.

В ваших случаях событие tr.group не работает из-за ошибки, возникшей из предыдущего события щелчка ячейки.

Мы исправили эту ошибку, и dev-версия DT должна работать с приведенным ниже кодом:

library(shiny)
library(DT)
ui <- fluidPage(# Application title
  titlePanel("Collapse/Expand table"),
  mainPanel(DTOutput("my_table")))

callback_js <- JS(
  "table.on('click', 'tr.group', function () {",
  "  var rowsCollapse = $(this).nextUntil('.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)

Еще раз спасибо за ваши отчеты!

Ответ на вопрос Github о DT: https://github.com/rstudio/DT/issues/759

0 голосов
/ 27 января 2020

Как упомянул @David Joequera в комментариях, это ошибка JavaScript, когда один из обработчиков событий по умолчанию для Datatable выдает ошибку, поскольку в строке Group отсутствует свойство строки.

В качестве обходного пути мы можем удалить этот обработчик событий, чтобы сработал тот, который скрыт.

Также я бы порекомендовал ориентировать строки группы только с помощью обработчика событий, чтобы можно было только полностью закрыть и открыть группы и не могут скрывать группы. Вы можете достичь этого, просто добавив «.group» к вашему событию Listener Target. В результате получается следующий код:

table.on('click', 'tr.group', function () {
   var rowsCollapse = $(this).nextUntil('.group');
   $(rowsCollapse).toggleClass('hidden');
})

Чтобы удалить обработчик событий, нам нужно подождать, пока таблица будет загружена правильно и обработчик проблемного c подключен, поэтому я бы рекомендовал работать с небольшим тайм-аут. 1000 мс работал нормально для меня и не должен вызывать проблем с юзабилити. поэтому добавление этого кода в обратные вызовы должно решить проблему:

setTimeout(function(){$('#DataTables_Table_0').off('click.dt','tbody td')},1000);

Имейте в виду, что идентификатор удаляемой таблицы данных может измениться в вашем окончательном / реальном решении

В результате этого кода для демо:

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)
0 голосов
/ 27 января 2020

Благодаря комментарию AEF мне удалось свести проблему к минимуму. Событие должно произойти, когда один пользователь нажимает на теле $('#DataTables_Table_0 tbody') и только на строках с идентификатором группы 'tr.group'.

Окончательный обратный вызов должен быть скорректирован с учетом обоих этих условий.

Поэтому приложение со сворачиваемыми строками выглядит следующим образом:

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)
...