Сортировка столбцов флажков из Datatable

У меня есть таблица данных, в которую я добавил несколько столбцов флажков. Я хочу иметь возможность сортировать столбцы по значениям флажков (установленных или нет). Я протестировал много разных вещей и нашел одну часть кода, которая вроде бы работает, но, к сожалению, нет. Вот решение, предложенное здесь: R/Shiny — прокручиваемая таблица данных с флажками и общим количеством.

Я заметил, что когда вы заходите в приложение и устанавливаете флажки, фильтрация не вызывает проблем. Но если вы попытаетесь обновить флажки, сортировка сохранится.

Пример проблемы с флажками:

Чтобы воспроизвести этот пример, вот код:

library(shiny)
library(DT)

ui <- fluidPage(
  br(),
  fluidRow(
    column(
      6,
      DTOutput("dtable")
    ),
    column(
      6,
      verbatimTextOutput("reactiveDF")
    )
  )
)

checkboxColumn <- function(len, col, ...) { # `col` is the column index
  inputs <- character(len)
  for(i in seq_len(len)) {
    inputs[i] <- as.character(
      checkboxInput(paste0("checkb_", col, "_", i), label = NULL, ...)
    )
  }
  inputs
}

dat0 <- data.frame(
  fruit  = c("apple", "cherry", "pineapple", "pear"),
  letter = c("a", "b", "c", "d")
)

dat1 <- cbind(dat0, bool1 = FALSE, bool2 = FALSE)

dat2 <- cbind(
  dat0,
  check1 = checkboxColumn(nrow(dat0), 3),
  check2 = checkboxColumn(nrow(dat0), 4)
)

js <- function(dtid, cols, ns = identity) {
  code <- vector("list", length(cols))
  for(i in seq_along(cols)) {
    col <- cols[i]
    code[[i]] <- c(
      sprintf(
        "$('body').on('click', '[id^=checkb_%d_]', function() {",
        col),
      "  var id = this.getAttribute('id');",
      sprintf(
        "  var i = parseInt(/checkb_%d_(\\d+)/.exec(id)[1]);",
        col),
      "  var value = $(this).prop('checked');",
      sprintf(
        "  var info = [{row: i, col: %d, value: value}];",
        col),
      sprintf(
        "  Shiny.setInputValue('%s', info);",
        ns(sprintf("%s_cell_edit:DT.cellInfo", dtid))
      ),
      "});"
    )
  }
  do.call(c, code)
}

checkboxesColumns <- c(3, 4)

render <- function(col) { 
sprintf('
function(data, type, row, meta) {
  if (type == "sort") { 
    var i = meta.row + 1;
    var $box = $("#checkb_%d_" + i);
    data = $box.prop("checked") ? "true" : "false";
  }
  return data;
}', col)
}

server <- function(input, output, session) {
  
  Dat <- reactiveVal(dat1)
  
  output[["dtable"]] <- renderDT({
    datatable(
      dat2, 
      rownames = TRUE,
      escape = FALSE,
      editable = list(
        target = "cell", disable = list(columns = checkboxesColumns)
      ),
      selection = "none",
      callback = JS(js("dtable", checkboxesColumns)), 
      options = list(
        columnDefs = list(
         list(targets = 3, render = JS(render(3))),
         list(targets = 4, render = JS(render(4)))
        )
      )
    )
  }, server = FALSE)
  
  observeEvent(input[["dtable_cell_edit"]], { 
    info <- input[["dtable_cell_edit"]] # this input contains the info of the edit
    Dat(editData(Dat(), info))
  })
  
  output[["reactiveDF"]] <- renderPrint({ 
    Dat()
  })
  
}

shinyApp(ui, server)

Есть ли какое-нибудь решение этой проблемы?

Поделитесь минимальным воспроизводимым примером проблемы. Сюда входит код и соответствующие данные. Это единственный способ получить помощь здесь, на Stack Overflow.

Ifeanyi Idiaye 30.05.2024 16:29

Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Community 30.05.2024 17:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Идея состоит в том, что мы определяем невидимый числовой столбец для каждого столбца флажка, который содержит значения 0 или 1 в зависимости от того, установлен ли флажок в соответствующей ячейке, и что мы используем эти числовые столбцы для упорядочивания столбцов флажка с помощью orderData.

library(shiny)
library(DT)

ui <- fluidPage(
  br(),
  fluidRow(
    column(
      6,
      DTOutput("dtable")
    ),
    column(
      6,
      verbatimTextOutput("reactiveDF")
    )
  )
)

checkboxColumn <- function(len, col, ...) { # `col` is the column index
  inputs <- character(len)
  for(i in seq_len(len)) {
    inputs[i] <- as.character(
      checkboxInput(paste0("checkb_", col, "_", i), label = NULL, ...)
    )
  }
  inputs
}

dat0 <- data.frame(
  fruit  = c("apple", "cherry", "pineapple", "pear"),
  letter = c("a", "b", "c", "d")
)

dat2 <- cbind(
  dat0,
  check1 = checkboxColumn(nrow(dat0), 3),
  check2 = checkboxColumn(nrow(dat0), 4),
  dummy1 = 0,
  dummy2 = 0
)

checkboxesColumns <- c(3, 4)

render <- function(col) { 
  sprintf('
function(data, type, row, meta) {
  if (type == "sort") { 
    var i = meta.row + 1;
    var $box = $("#checkb_%d_" + i);
    data = $box.prop("checked") ? "true" : "false";
  }
  return data;
}', col)
}

server <- function(input, output, session) {
  
  output[["dtable"]] <- renderDT({
    datatable(
      dat2, 
      rownames = TRUE,
      escape = FALSE,
      editable = list(
        target = "cell", disable = list(columns = checkboxesColumns)
      ),
      selection = "none",
      callback = JS(
        c(
          "table.on('click', 'tbody td',", 
          "  function () {",
          "    var rowIndex = table.row(this).index();",
          "    var colIndex = table.column(this).index();",
          "    var $box = $('#checkb_' + colIndex + '_' + (rowIndex + 1));",
          "    var checkBoxState = $box.prop('checked') ? 1 : 0;",
          "    table.cell({",
          "      row: rowIndex,",
          "      column: colIndex + 2",
          "    }).data(checkBoxState).draw();",
          "  })"
          )
        ),
      options = list(
        columnDefs = list(
          list(targets = 3, render = JS(render(3)), orderData = 5),
          list(targets = 4, render = JS(render(4)), orderData = 6),
          list(targets = 5, visible = FALSE),
          list(targets = 6, visible = FALSE)
        )
      )
    )
  }, server = FALSE)
}

shinyApp(ui, server)

Работает отлично! Я просто добавил reactiveVal, потому что он мне нужен, и объединил два обратных вызова, так что у меня есть значения, и я могу их сортировать :)

Antoine Moniot 04.06.2024 11:01

Другие вопросы по теме