2016-10-13 2 views
1

Я ищу решение для размещения selectedInputs в ячейках renderDataTable. Я нашел js-решения: https://datatables.net/examples/api/form.html, однако я не знаю, как реализовать это решение в shinyjs как объект renderDataTable. Я был бы признателен за подсказки/идеи/решения, как реализовать редактируемый renderDataTable в блестящем виде.R Shiny selectedInput внутри renderDataTable ячеек

ответ

4

Очень похожа на это: adding a column with TRUE/FALSE and showing that as a checkbox

library(shiny) 
library(DT) 
runApp(list(
    ui = basicPage(
    h2('The mtcars data'), 
    DT::dataTableOutput('mytable'), 
    h2("Selected"), 
    tableOutput("checked") 
), 

    server = function(input, output) { 
    # helper function for making checkbox 
    shinyInput = function(FUN, len, id, ...) { 
     inputs = character(len) 
     for (i in seq_len(len)) { 
     inputs[i] = as.character(FUN(paste0(id, i), label = NULL, ...)) 
     } 
     inputs 
    } 
    # datatable with checkbox 
    output$mytable = DT::renderDataTable({ 
     data.frame(mtcars,Rating=shinyInput(selectInput,nrow(mtcars),"selecter_", 
              choices=1:5, width="60px")) 
    }, selection='none',server = FALSE, escape = FALSE, options = list( 
     paging=TRUE, 
     preDrawCallback = JS('function() { 
Shiny.unbindAll(this.api().table().node()); }'), 
     drawCallback = JS('function() { 
Shiny.bindAll(this.api().table().node()); } ') 
    )) 
    # helper function for reading checkbox 
    shinyValue = function(id, len) { 
     unlist(lapply(seq_len(len), function(i) { 
     value = input[[paste0(id, i)]] 
     if (is.null(value)) NA else value 
     })) 
    } 
    # output read checkboxes 
    output$checked <- renderTable({ 
     data.frame(selected=shinyValue("selecter_",nrow(mtcars))) 
    }) 
    } 
)) 

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

редактировать:

Допустим, данные в таблице, реактивная, так что изменения, и повторно выводит стол. Вам нужно будет явно отвязать согласно @yihui здесь: https://groups.google.com/forum/#!msg/shiny-discuss/ZUMBGGl1sss/zfcG9c6MBAAJ

Так что вам нужно добавить в пользовательский интерфейс:

tags$script(HTML("Shiny.addCustomMessageHandler('unbind-DT', function(id) { 
      Shiny.unbindAll($('#'+id).find('table').DataTable().table().node()); 
     })")) 

, а затем в сервере вы вызвать функцию, когда вы засавить в DataTable с:

session$sendCustomMessage('unbind-DT', 'mytable') 

Параметр colnames - это вектор имен столбцов, поэтому при указании длины один вектор FALSE он дает таблицу с одним столбцом с именем FALSE. Я не уверен в простом удалении имен столбцов из datatables. Это было бы хорошим вопросом SO самостоятельно.

+0

Ваше решение выбирает строку, когда я выбираю selectInput значение. Можно ли отключить выбор строки при выборе значения selectInput? – user3463225

+0

Да, отредактировал мой ответ – Carl

+0

Возможно ли обновить все выбранные входы в таблице, если изменяется значение в первой строке? – user3463225

2

Почему бы не использовать стандартную fucntional из DT (Shiny.bindAll)

Пример (в консоли печати выберите 1-й строки)

library(shiny) 
library(DT) 
mymtcars = mtcars 
mymtcars$id = 1:nrow(mtcars) 
runApp(
    list(ui = fluidPage(

     DT::dataTableOutput("mytable") 
    ) 

    , server = function(input, output, session) { 

    observe({ 
     print(input$row1) 
    }) 

    output$mytable = DT::renderDataTable({ 
     #Display table with select 
     DT::datatable(cbind(Pick=paste0(' 
             <select id="row', mymtcars$id, '"> <option>1</option> 
             <option>2</option></select>',""), mymtcars), 
        options = list(orderClasses = TRUE, 
            lengthMenu = c(5, 25, 50), 
            pageLength = 25 , 

            drawCallback= JS(
            'function(settings) { 
            Shiny.bindAll(this.api().table().node());}') 
            ),selection='none',escape=F) 


    }) 

    }) 
)