RStudio Shiny list из проверки строк в таблицах данных

Я хотел бы иметь рабочий пример, подобный этому: https://demo.shinyapps.io/029-row-selection/

Я пробовал использовать этот пример на своем сервере Shiny, на котором запущены Shiny Server v1.1.0.10000, packageVersion: 0.10.0 и Node.js v0.10.21, но он не работает, даже если я загружаю файлы js и css с веб-сайта. Он просто не выбирает строки из таблицы:

# ui.R
library(shiny)

shinyUI(fluidPage(
  title = 'Row selection in DataTables',
  tagList(
          singleton(tags$head(tags$script(src='//cdn.datatables.net/1.10.2/js/jquery.dataTables.js',type='text/javascript'))),
          singleton(tags$head(tags$script(src='//cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css',type='text/css')))
        ),
  sidebarLayout(
    sidebarPanel(textOutput('rows_out')),
    mainPanel(dataTableOutput('tbl')),
    position = 'right'
  )
))

# server.R
library(shiny)

shinyServer(function(input, output) {
  output$tbl <- renderDataTable(
    mtcars,
    options = list(pageLength = 10),
    callback = "function(table) {
      table.on('click.dt', 'tr', function() {
        $(this).toggleClass('selected');
        Shiny.onInputChange('rows',
                            table.rows('.selected').indexes().toArray());
      });
    }"
  )
  output$rows_out <- renderText({
    paste(c('You selected these rows on the page:', input$rows),
          collapse = ' ')
  })
})

Затем я попытался сделать это из другого примера, в котором использовались переключатели для повторной сортировки строк.

В моем модифицированном примере я хочу создать список идентификаторов из выбранных кнопок флажков таблицы dataTables, показанной на веб-странице. Например, выбрав несколько строк из первых 5, я хочу, чтобы мое текстовое поле было: 1,3,4, соответствующим столбцу mymtcars$id, который я добавил в mtcars. Затем я планирую связать действие со значениями текстового поля.

В этом примере у меня это почти есть, но установка флажков не обновляет список в текстовом поле. В отличие от примера shinyapp, я бы хотел, чтобы мои флажки сохраняли статус выбора, если таблица пересортирована. Это может быть сложная часть, и я не знаю, как это сделать. Я также хотел бы добавить текстовое поле «Выбрать / Отменить выбор всех» в верхнем левом углу таблицы, которое выбирает / отменяет выбор всех полей в таблице. Любые идеи?

введите описание изображения здесь

# server.R
library(shiny)

mymtcars = mtcars
mymtcars$id = 1:nrow(mtcars)

shinyServer(function(input, output, session) {

      rowSelect <- reactive({
        if (is.null(input[["row"]])) {
            paste(sort(unique(rep(0,nrow(mymtcars)))),sep=',')
        } else {
            paste(sort(unique(input[["row"]])),sep=',')
        }
      })

  observe({
      updateTextInput(session, "collection_txt",
        value = rowSelect()
        ,label = "Foo:"
      )
  })

      # sorted columns are colored now because CSS are attached to them
      output$mytable = renderDataTable({
              addCheckboxButtons <- paste0('<input type="checkbox" name="row', mymtcars$id, '" value="', mymtcars$id, '">',"")
                  #Display table with checkbox buttons
                  cbind(Pick=addCheckboxButtons, mymtcars[, input$show_vars, drop=FALSE])
          }, options = list(bSortClasses = TRUE, aLengthMenu = c(5, 25, 50), iDisplayLength = 25))

})


# ui.R
library(shiny)

mymtcars = mtcars
mymtcars$id = 1:nrow(mtcars)

shinyUI(pageWithSidebar(
      headerPanel('Examples of DataTables'),
      sidebarPanel(
              checkboxGroupInput('show_vars', 'Columns to show:', names(mymtcars),
                                                        selected = names(mymtcars))
            ),
      mainPanel(
                         dataTableOutput("mytable")
      ,textInput("collection_txt",label="Foo")
              )
      )
)

person 719016    schedule 24.09.2014    source источник


Ответы (4)


Для решения первой проблемы вам потребуется установленная dev-версия shiny и htmltools >= 0.2.6:

# devtools::install_github("rstudio/htmltools")
# devtools::install_github("rstudio/shiny")
library(shiny)
runApp(list(ui = fluidPage(
  title = 'Row selection in DataTables',
  sidebarLayout(
    sidebarPanel(textOutput('rows_out')),
    mainPanel(dataTableOutput('tbl')),
    position = 'right'
  )
)
, server = function(input, output) {
  output$tbl <- renderDataTable(
    mtcars,
    options = list(pageLength = 10),
    callback = "function(table) {
    table.on('click.dt', 'tr', function() {
    $(this).toggleClass('selected');
    Shiny.onInputChange('rows',
    table.rows('.selected').indexes().toArray());
    });
}"
  )
  output$rows_out <- renderText({
    paste(c('You selected these rows on the page:', input$rows),
          collapse = ' ')
  })
}
)
)

введите описание изображения здесь

для вашего второго примера:

library(shiny)
mymtcars = mtcars
mymtcars$id = 1:nrow(mtcars)
runApp(
  list(ui = pageWithSidebar(
    headerPanel('Examples of DataTables'),
    sidebarPanel(
      checkboxGroupInput('show_vars', 'Columns to show:', names(mymtcars),
                         selected = names(mymtcars))
      ,textInput("collection_txt",label="Foo")
    ),
    mainPanel(
      dataTableOutput("mytable")
    )
  )
  , server = function(input, output, session) {
    rowSelect <- reactive({
      paste(sort(unique(input[["rows"]])),sep=',')
    })
    observe({
      updateTextInput(session, "collection_txt", value = rowSelect() ,label = "Foo:" )
    })
    output$mytable = renderDataTable({
      addCheckboxButtons <- paste0('<input type="checkbox" name="row', mymtcars$id, '" value="', mymtcars$id, '">',"")
      #Display table with checkbox buttons
      cbind(Pick=addCheckboxButtons, mymtcars[, input$show_vars, drop=FALSE])
    }, options = list(orderClasses = TRUE, lengthMenu = c(5, 25, 50), pageLength = 25)
    , callback = "function(table) {
    table.on('change.dt', 'tr td input:checkbox', function() {
      setTimeout(function () {
         Shiny.onInputChange('rows', $(this).add('tr td input:checkbox:checked').parent().siblings(':last-child').map(function() {
                 return $(this).text();
              }).get())
         }, 10); 
    });
}")
  }
  )
)

введите описание изображения здесь

person jdharrison    schedule 29.09.2014
comment
В итоге я использовал второй пример, который отлично работал без необходимости обновлять программное обеспечение. - person 719016; 01.10.2014
comment
Является ли input [[rows]] значениями выбранной строки / s? Потому что у меня есть аналогичный пример, и я не могу получить значения проверенных строк. Уточните плз. - person OmaymaS; 01.01.2017

Этот ответ был поврежден в блестящей версии 0.11.1, но его легко исправить. Вот обновление, которое сделало это (ссылка):

В renderDataTable() добавлен аргумент escape для экранирования сущностей HTML в таблице данных по соображениям безопасности. Это может привести к поломке таблиц из предыдущих версий shiny, которые используют необработанный HTML в содержимом таблицы, а escape = FALSE может восстановить прежнее поведение, если вы знаете о последствиях для безопасности. (# 627)

Таким образом, чтобы предыдущие решения работали, необходимо указать escape = FALSE в качестве параметра renderDataTable().

person Paul    schedule 13.02.2015
comment
Данная ссылка теперь не работает. Я попытался запустить код как есть и с escape = FALSE, но оба раза получил Warning: Error in datatable: The 'callback' argument only accept a value returned from JS(). Бегущий блестящий 0.13.2. Расследование ... - person hubbs5; 29.12.2016
comment
Я обновил ссылку (они изменили ее с NEWS на NEWS.md). API Shiny постоянно развивается, и я больше не являюсь активным пользователем. Я уверен, что все оценят результаты вашего расследования. - person Paul; 29.12.2016

Я сделал альтернативу для флажков в таблицах на основе предыдущего кода ответа и некоторых настроек JQuery / JavaScript.

Для тех, кто предпочитает фактические данные номерам строк, я написал этот код, который извлекает данные из таблицы и показывает это как выбор. Вы можете отменить выбор, щелкнув еще раз. Он основан на предыдущих ответах, которые мне очень помогли (СПАСИБО), поэтому я тоже хочу поделиться этим.

Ему нужен объект сеанса, чтобы поддерживать вектор в действии (область видимости). На самом деле вы можете получить любую информацию из таблицы, просто погрузитесь в JQuery и измените $ row.find ('td: nth-child (2)') (число - это номер столбца). Мне нужна информация из второго столбец, но это зависит от вас. Цвета выделения будут немного странными, если вы также измените количество видимых столбцов .... цвета выделения имеют тенденцию исчезать ...

Надеюсь, это будет полезно, у меня работает (нужно оптимизировать, но сейчас на это нет времени)

output$tbl <- renderDataTable(
  mtcars,
  options = list(pageLength = 6),
  callback = "function(table) {
  table.on('click.dt', 'tr', function() {

  if ( $(this).hasClass('selected') ) {
    $(this).removeClass('selected');
  } else {
    table.$('tr.selected').removeClass('selected');
    $(this).addClass('selected');
  }

  var $row = $(this).closest('tr'),       
    $tdsROW = $row.find('td'),
    $tdsUSER = $row.find('td:nth-child(2)');

  $.each($tdsROW, function() {               
    console.log($(this).text());        
  });

  Shiny.onInputChange('rows',table.rows('.selected').indexes().toArray());
  Shiny.onInputChange('CELLselected',$tdsUSER.text());
  Shiny.onInputChange('ROWselected',$(this).text());

  });
  }"
)

output$rows_out <- renderUI({
  infoROW <- input$rows
  if(length(input$CELLselected)>0){
    if(input$CELLselected %in%  session$SelectedCell){
      session$SelectedCell <- session$SelectedCell[session$SelectedCell != input$CELLselected]
    }else{
      session$SelectedCell <- append(session$SelectedCell,input$CELLselected)
    }
  }
  htmlTXT <- ""
  if(length(session$SelectedCell)>0){
    for(i in 1:length(session$SelectedCell)){
      htmlTXT <- paste(htmlTXT,session$SelectedCell[i],sep="<br/>")
    }
  }else{htmlTXT <- "please select from the table"}
  HTML(htmlTXT)
})
person irJvV    schedule 06.02.2015

Ответы выше устарели. Я получил ошибку Ошибка в таблице данных: аргумент «обратный вызов» принимает только значение, возвращаемое из JS ().

Вместо этого у меня работает Этот.

person C.Wang    schedule 13.09.2020