R DT datatable не сохраняет столбец индекса / счетчика строк после выбора новой страницы при использовании опции обратного вызова - PullRequest
3 голосов
/ 12 марта 2019

Я использую этот вопрос в качестве ссылки для добавления "индекса строки" или "столбца счетчика" (как описано в документации по датам здесь ) к DT::datatable в Блестящее приложение. Намерение состоит в том, чтобы хранить имена строк в константе таблицы (1, 2, 3 ...) независимо от сортировки, применяемой к таблице.

Пользователь NicE ответил на этот вопрос, преобразовав код javascript в документацию с данными для использования в обратном вызове параметров DT::datatable:

output$tbl = renderDataTable({
                        datatable(data, filter = "top", rownames=TRUE,options = list(
                            pageLength = 300, lengthMenu = c(100,200,300,400,500,600)
                    ),
                    callback=JS("table.on( 'order.dt search.dt', function () {
                            table.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
                                  cell.innerHTML = i+1;});}).draw();"))
            })

Это работает нормально, если я запускаю только часть данных (... часть кода локально; однако, он не работает, когда я запускаю в renderDataTable в приложении Shiny (имена строк возвращаются к исходной сортировке, когда вы перейти на страницу, отличную от первой). Согласно комментарию в документации по датированным ссылкам, указанной выше, пользователь DeFKnoL обнаружил, что это не работает должным образом, если вы перемещаетесь между страницами в таблице - это именно та проблема, когда я запускаю свое приложение Shiny Комментарий DeFKnoL гласит, что ("deferRender": true) вызывает проблемы с этим - я попытался изменить это значение на FALSE в параметрах DT::datatable, и это не устраняет проблему.

Я надеюсь, что кто-то может помочь мне преобразовать код javascript этого пользователя во что-то, что я могу добавить в опцию обратного вызова DT::datatable.

Вот код javascript из исходного метода, описанного в документации по датированным данным (которую NicE изменил для использования в обратном вызове):

$(document).ready(function() {
var t = $('#example').DataTable( {
    "columnDefs": [ {
        "searchable": false,
        "orderable": false,
        "targets": 0
    } ],
    "order": [[ 1, 'asc' ]]
} );

t.on( 'order.dt search.dt', function () {
    t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
        cell.innerHTML = i+1;
    } );
} ).draw();

});

А вот обновленный метод DeFKnoL, решающий проблему смены страниц:

$(document).ready(function() {
var t = $('#example').DataTable( {
    "columnDefs": [ {
        "searchable": false,
        "orderable": false,
        "targets": 0
    } ],
    "order": [[ 1, 'asc' ]]
} );

t.on( 'draw.dt', function () {
var PageInfo = $('#example').DataTable().page.info();
     t.column(0, { page: 'current' }).nodes().each( function (cell, i) {
        cell.innerHTML = i + 1 + PageInfo.start;
    } );
} );

});

Как вы, возможно, видите, входные данные NicE JS() не совсем соответствуют документации - и у меня нет опыта работы с javascript - так что мне сложно реализовать это изменение. Возможно, что добавить «встречный столбец» намного проще, чем это, но мне не повезло найти какие-либо методы, кроме исходного вопроса, связанного выше. Любая помощь будет оценена!

1 Ответ

3 голосов
/ 12 марта 2019

Две возможности:

1) использовать server = FALSE:

output$tbl <- renderDT({
  datatable(data, filter = "top", rownames=TRUE, 
            options = list(
              pageLength = 300, lengthMenu = c(100,200,300,400,500,600)
            ),
            callback=JS("table.on( 'order.dt search.dt', function () {
              table.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
              cell.innerHTML = i+1;});}).draw();")
  )
}, server = FALSE)

2) Иначе, вот метод DeFKnoL:

js <- c(
  "table.on('draw.dt', function(){",
  "  var PageInfo = table.page.info();",
  "  table.column(0, {page: 'current'}).nodes().each(function(cell,i){", 
  "    cell.innerHTML = i + 1 + PageInfo.start;",
  "  });",
  "})")

output$tbl <- renderDT({
  datatable(data, filter = "top", rownames=TRUE, 
            options = list(
              pageLength = 300, lengthMenu = c(100,200,300,400,500,600)
            ),
            callback = JS(js)
  )
})
...