I'm creating a datatable in R which has child rows, manually-defined column names and also hides a few columns.
This seemed fairly trivial based on an example provided in the DT manual https://rstudio.github.io/DT/002-rowdetails.html (i.e. it already shows how to create the child rows and hide some of the columns). However, when I try adding the 'colnames' argument to define the new column names of the non-hidden columns it doesn't behave as expected.
I have tried removing the blank column header text, adding extras to see if it's relating to the original number of columns in the table. If I remove the call to hide certain columns the headers show as they should but I can't delete columns (they need to be hidden) because the table is linked to plot objects that use the data from those hidden columns.
library(DT)
datatable(
cbind(' ' = '⊕', mtcars), escape = -2,
colnames = c(" ", "GEAR COLUMN", "CARB COLUMN"), # This is the only line added to the original DT example.
options = list(
columnDefs = list(
list(visible = FALSE, targets = c(0, 2, 3:10)), # Removing this line solves the header issue but then all columns are shown.
list(orderable = FALSE, className = 'details-control', targets = 1)
)
),
callback = JS("
table.column(1).nodes().to$().css({cursor: 'pointer'});
var format = function(d) {
return '<div style=\"background-color:#eee; padding: .5em;\"> Model: ' +
d[0] + ', mpg: ' + d[2] + ', cyl: ' + d[3] + '</div>';
};
table.on('click', 'td.details-control', function() {
var td = $(this), row = table.row(td.closest('tr'));
if (row.child.isShown()) {
row.child.hide();
td.html('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
}
});"
))
No error messages are provided, it just displays as normal but without all the defined column headers.
I suspect this is a relatively simple thing that makes perfect sense to those experienced in the JS call, but unfortunately that's not my forte.
If you want to rename the gear and the carb columns, you can do
colnames = c("GEAR COLUMN" = "gear", "CARB COLUMN" = "carb")
Related
I want to put the focus and edit the first cell of my dynamic table when the user clicks a button.
the problem is that the id of the table tag is dynamic. actually, the name I put in dtoutput is a div tag, which contains neither cell nor row to position with javascrpt.
The problem is that the identification of the html tag of the table is dynamic. Actually, the name that I put in dtoutput is a div tag, and therefore its javascrpt object does not contain a cell or a row to position.
I have tried to position myself in different ways:
# tablet_list_var_dtf.cell (': eq (0)'). node (). focus ();
# tablet_list_var_dtf.cell (': eq (1)', ': eq (0)') .focus ();
# tablet_list_var_dtf.cell (': eq (' + scrollStart + ')', ': eq (0)') .focus ();
but as I say, really 'tablet_list_var_dtf' is an HTMLDivElement object and therefore it does not have node, cell, row etc ... also I cannot directly use object.focus (), it does not work.
Not only do I want to put the focus, but I want to edit the first cell, force a doubleclick event on said cell ..
I put a summary and executable code of the problem
enter code here
library(shiny)
library(DT)
library(shinyjs)
library(shinyFeedback)
# JS refocus function
jscode <- "
shinyjs.refocus = function(e_id ) {
alert(e_id);
alert(eval(tablet_list_var_dtf));
tablet_list_var_dtf.datatable.row().focus();
var scrollStart = tablet_list_var_dtf.scroller.page().start;
alert('ppp:'+scrollStart);
}"
#tablet_list_var_dtf.cell(':eq(0)').node().focus();
#tablet_list_var_dtf.cell( ':eq(1)', ':eq(0)' ).focus();
#tablet_list_var_dtf.cell( ':eq(' + scrollStart + ')', ':eq(0)' ).focus();
#table.cell(':eq(0)').focus()
#shinyjs.refocus = function(e_id) {
#document.getElementById(e_id).focus();
ui <- fluidPage(
useShinyjs(),
extendShinyjs(text = jscode, functions = c("refocus") ),
# activate shiny feedback
box(wclass = "map",
width = 12,
style = 'padding:0px;',
title = "List of DTF",
uiOutput( ("list_var_dtf"))
) ,
actionButton( ('edit_name_var_dtf'),'edit name var description'),
)
server <- function(input, output, session){
observeEvent(input$edit_name_var_dtf, {
print("edit_name_var_dtf")
js$refocus("tablet_list_var_dtf")
print('js$refocus(table)')
})
output$list_var_dtf <- renderUI({
DTOutput(("tablet_list_var_dtf"))
})
output$tablet_list_var_dtf <- renderDT(
datatable( data = mtcars,
rownames = FALSE,
options = list(
orderClasses = TRUE,
order = list(1, "desc"),
scrollX = TRUE,
scrollY = "37vh",
searchHighlight = TRUE,
scrollCollapse = T,
dom = 'ft',
paging = FALSE,
#callback = JS(jscall),
initComplete = JS("function(settings, json) {",
"$(this.api().table().header()).css({'background-color': '#000', 'color': '#fff'});",
"}")
),
selection = "none" , editable = list(target = "column", disable = list(columns = c(1))))
)
}
shinyApp(ui, server)
This is the js code correct:
jscode <- " shinyjs.refocus = function(e_id){
var table = $('#DataTables_Table_0').DataTable();
var td = table.cell(':eq(0)', ':eq(0)').node();
$(td).attr('tabindex', 0); $(td).dblclick( );
}"
The problem is looking for the 'DataTables_Table_(XXX)' selector in a pivot table in shiny. So the real problem is finding the right selector for the table.
If our component id is 'table_list_var_dtf'
DTOutput('table_list_var_dtf')
you should know that this id is not really the id of the table. But the id of the div that contains the pivot table. Specifically, the table that is created dynamically starts with the name DataTables_Table_ (xxxxxx) . Where (xxxxxx) is the number of tables that have been created dynamically.
Thus, if there are only two tables on the page, the id to look for is: DataTables_Table_ 02
thankssss. jogugil...
Line numbers are displayed by default in R DT packages.
dt <- DT::datatable(iris)
dt
However, this line number will change according to the record by sorting. This is the correct move.
But I need line numbers that are unaffected by sorting. Is it possible to do this with the R DT package?
library(DT)
datatable(iris,
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();")
)
It took me a loot of time to figure out why the documentation on the Index table didn't work on R but it turns out they were using a shorthand for table as t., here is a working example based on https://datatables.net/examples/api/counter_columns.html
Changed the JS part to allow for exportation as csv
library(DT)
dt <- DT::datatable(iris,options = list(
columnDefs = list(list(searchable= FALSE,
orderable =FALSE,
targets= 0)),
order = list(1,"asc")),
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;
table.cell(cell).invalidate('dom');
});
}).draw();
"))
dt
I have a shiny app where I would like to modify the data displayed and/or the attributes of a cell based on the value of the same cell in the previous row.
In my code I have formatted whole rows based on the value of data[0] in rowCallback.
output$result <- DT::renderDataTable(tabledata(),
class = c('compact'),
rownames = FALSE,
server = FALSE,
escape = TRUE,
extensions = options = list(
rowCallback=JS("
function (row, data, index) {
var string=data[1], substring = 'sub total';
if (data[0]=='Grand Total') {
$(row).css('background-color', '#DEDEDE'), $(row).css('font-weight', 'bold') ;
}
else if (data[0].includes('sub total')) {
$(row).css('font-weight', 'bold');
}
}"
)
)
)
Can I achieve a modification of the data[0] cell based on the value of the same cell in the previous row using one of the callback functions?
So I changed tack and used the following drawCallback call
drawCallback=JS(" function ( settings ) {
var api = this.api();
var mydata = api.rows( {page:'current'} ).data();
var last=null;
api.column(0,{page:'current'}).data().each( function ( value, index ) {
if ( value == last) {
mydata[index][0] = ''
api.rows({ page: 'current' }).invalidate();
}
last=value;
});
}"
)
I am experimenting with gWidgets in R and simply trying to open a new gwindow for different values of selected option in gradio. There are 3 options and the last two work fine. When I select the first option, the error displayed is as follows.
Error in tkobj$env : $ operator is invalid for atomic vectors
I have tried to include the choices as a list too, but the error remains. The rest of the code is as follows. Any suggestions would be helpful.
library(gWidgets)
library(base)
options("guiToolkit"="tcltk")
win1<-gwindow("Welcome to OCCUR", visible = TRUE)
g0<-ggroup(container = win1)
g1 <- ggroup(container = win1)
g2 <-ggroup (container = win1)
l1<-glabel(text = "Please select one.",editable = FALSE,
container = g0,toolkit = guiToolkit())
#radio buttons
radiob<- gradio(c("Customer Data", "Sales Analysis",
"Market Basket Analysis"), horizontal = FALSE, container = g1)
#exit ok buttons
b1<- gbutton("Let's go", container = g2 , handler = newwin)
newwin <- function(svalue){
if(svalue(radiob)=="Customer Data"){
win2<-gmenu("1 ", visible = TRUE)
}
if(svalue(radiob)=="Sales Analysis"){
win2<-gwindow("1", visible = TRUE)
}
else{
win2<-gwindow(" 3", visible = TRUE)
}
}
b2<- gbutton("Exit", container=g2, handler = exit)
exit<-function(h,...){
dispose(win1)
}
How can I create mouseover text for column names in R shiny data table display.
I'm trying to provide some text for users to understand the column names.
I checked in DT package also and I couldn't find a solution.
I can create labels for column names and display all of them when a user checks a box, this takes a lot of real estate and I don't want that.
Any tips?
To expand my comment above, here is an example showing what I meant by using the title attributes:
library(DT)
sketch = htmltools::withTags(table(
class = 'display',
thead(
tr(
th('', title = 'Row Names'),
th('Sepal.Length', title = 'The Sepal Length'),
th('Sepal.Width', title = 'The Sepal Width'),
th('Petal.Length', title = 'The Petal Length'),
th('Petal.Width', title = 'The Petal Width'),
th('Species', title = 'Iris Species')
)
)
))
datatable(iris, container = sketch)
And here is another approach using JavaScript (jQuery) to add the title attributes:
library(DT)
datatable(iris, callback = JS("
var tips = ['Row Names', 'The Sepal Length', 'The Sepal Width',
'The Petal Length', 'The Petal Width'],
header = table.columns().header();
for (var i = 0; i < tips.length; i++) {
$(header[i]).attr('title', tips[i]);
}
"))
You can probably accomplish that using optionsin the renderDataTable() function in Shiny. From the documentation page of DT in Shiny, something like this should work.
renderDataTable(head(iris, 20), options = list(
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).on({
mouseenter: function () {
//stuff to do on mouse enter
},
mouseleave: function () {
//stuff to do on mouse leave
}
});",
"}")
))