问题
I am using this question as a reference to add a "row index" or "counter column" (as described in the datatable documentation here) to a DT::datatable
in a Shiny application. The intent is to hold the row names in the table constant (1, 2, 3...) regardless of the sorting that is applied to the table.
The user NicE answered this question by converting the javascript code in the datatable documentation for use in the callback of the DT::datatable
options:
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();"))
})
This works fine if I run only the datatable(... portion of the code locally; however, it does not work when I run within renderDataTable
in the Shiny application (the row names revert to the original sorting when you move to a page other than the first). Per a comment in the datatable documentation linked above, the user DeFKnoL identified that this does not work properly if you move between pages in the table - this is the exact problem when I run my Shiny application. DeFKnoL's comment states that ("deferRender": true) causes issues with this - I have tried changing this to FALSE in the DT::datatable
options and this does not fix the problem.
I am hoping someone can help me convert this user's javascript code into something that I can feed into the callback option of DT::datatable
.
Here is the javascript code from the original method outlined in the datatable documentation (that NicE modified for use in the callback):
$(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();
} );
And here is DeFKnoL's updated method that gets around the issue of changing pages:
$(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;
} );
} );
} );
As you can maybe see, NicE's JS()
input doesn't exactly match the documentation - and I have no experience with javascript - so I'm having a tough time implementing this change. It is possible that adding a "counter column" is much simpler than this, but I've had no luck finding any methods other than the original question linked above. Any help would be appreciated!
回答1:
Two possibilities:
1) use 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) Otherwise, here is DeFKnoL's method:
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)
)
})
来源:https://stackoverflow.com/questions/55115183/r-dt-datatable-not-retaining-row-index-counter-column-after-selecting-new-page-w