want to put the focus and edit the first cell of my dynamic table

want to put the focus and edit the first cell of my dynamic table

jogugiljogugil Posts: 8Questions: 0Answers: 0
edited January 2022 in DataTables

Link to test case:
library(shiny)
library(DT)
library(shinyjs)

JS refocus function

jscode <- " 
  shinyjs.refocus = function(e_id ) {
  alert(e_id);
   alert(eval(tablet_list_var_dtf));
    tbl = document.getElementById('tablet_list_var_dtf');
   alert(eval(tbl.datatable));
    tbl2=document.getElementsByName('tablet_list_var_dtf');
    alert(eval( tbl2 ));
      tbl.focus();
    nodes=tbl.children;
   for (const property in nodes) 
      alert(property);
 
         objectToInspect1 = $(tablet_list_var_dtf).getPrototypeOf($(tablet_list_var_dtf))
    alert(objectToInspect)
    alert(objectToInspect1)
    var scrollStart = tablet_list_var_dtf.scroller.page().start;
    alert('ppp:'+scrollStart);

/*
 tablet_list_var_dtf.datatable.row().focus();  -- not work
 tablet_list_var_dtf.cell(':eq(0)').node().focus();   -- not work
 tablet_list_var_dtf.cell( ':eq(1)', ':eq(0)' ).focus();   -- not work
 tablet_list_var_dtf.cell( ':eq(' + scrollStart + ')', ':eq(0)' ).focus();   -- not work
 table.cell(':eq(0)').focus()   -- not work
 
 document.getElementById(e_id).focus();   -- not work
*/
}"

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,
                  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)

Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:

I want to put focus and edit the first cell of my pivot table when the user clicks a button.

The problem is that Shiny places a table label id name dynamically (datatable_0, Datatable_1, ....). And actually, the name you put in dtoutput is a div tag, which does not contain a cell method, nor a row to position the focus with javascrpt or provide the doublecick and edit the cell 0,0.

I have tried to position myself in different ways:

 tablet_list_var_dtf.datatable.row().focus();  -- not work
 tablet_list_var_dtf.cell(':eq(0)').node().focus();   -- not work
 tablet_list_var_dtf.cell( ':eq(1)', ':eq(0)' ).focus();   -- not work
 tablet_list_var_dtf.cell( ':eq(' + scrollStart + ')', ':eq(0)' ).focus();   -- not work
 table.cell(':eq(0)').focus()   -- not work

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

Edited by Colin - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.

Replies

  • jogugiljogugil Posts: 8Questions: 0Answers: 0

    the error is in all cases :smile:
    Uncaught TypeError: table.cell(...).focus is not a function
    at Object.shinyjs.refocus ((index):52)
    at e.<anonymous> ((index):36)
    at e.value (shinyapp.ts:717)
    at e.<anonymous> (shinyapp.ts:811)
    at e.value (shinyapp.ts:717)
    at e.value (shinyapp.ts:700)
    at WebSocket.i.onmessage (shinyapp.ts:350)

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Uncaught TypeError: table.cell(...).focus is not a function

    .focus() is a jQuery method. You will need to get the node of the first td as a jQuery object. You could simply use something like this:

    $( 'td:eq(0)' ).focus();
    

    This assumes only one table on the page. If you have multiple you can make the selector more specific to select the table you want.

    However, you can use the Datatables API's for the same results using cell().node(). But you need to turn that into a jQuery object. Something like this:

    $( table.cell(':eq(0)').node() ).focus();
    

    This assumes the variable table contains an instance of the Datatable API of the table you are interested in. See the Accessing the API docs for more details.

    Kevin

  • jogugiljogugil Posts: 8Questions: 0Answers: 0
    edited January 2022

    thanks, but not put the focus in cell 0.

    the code is:

    library(shiny)
    library(DT)
    library(shinyjs)
     
    
    # JS refocus function
    jscode <- " 
      shinyjs.refocus = function(e_id ) {
       var table = $('#tablet_list_var_dtf #DataTable_').DataTable();
       var table1 = $('#tablet_list_var_dtf #DataTable_').dataTable();
         table1.$( ('td:eq(0)')  ).focus();
         $( table.cell(':eq(' + 1 + ')', ':eq(0)' ).node() ).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,
     
                      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)
    

    Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

  • jogugiljogugil Posts: 8Questions: 0Answers: 0
    edited January 2022

    pagination

  • jogugiljogugil Posts: 8Questions: 0Answers: 0

    $ (table.cell (': eq (' + 1 + ')', ': eq (0)') .node ()) .focus ();

    The first eq indicates the pagination of the scroll. This way it will always be positioned on the first cell of the visible part of the table.
    But in any case, I can't put the focus on cell 0, much less edit that cell.

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    I'm not familiar with Shiny. Doesn't look like you are using the Editor.

    What are you using to edit the cells?

    Can you focus a table cells without initializing Datatables?

    I think you might need to use tabindex to focus a td. Or are you trying to focus a input?

    Can you provide a running test case example showing the issue so we can help debug?
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    You might also be interested in the KeyTable extension. You can then use cell().focus() and skip the jQuery stuff. Like this:
    http://live.datatables.net/cofirohi/1/edit

    Kevin

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    With Editor, you can call inline() to edit any cell in the table - it would be worth considering that.

    Colin

  • jogugiljogugil Posts: 8Questions: 0Answers: 0

    What I want is that when the user presses a button, the focus goes to the first cell of the table and it is editable so that he can modify the data in that cell.

  • jogugiljogugil Posts: 8Questions: 0Answers: 0

    one of the problems is the selector. the id 'table_list_var_dtf' is not really the id of the table. the table is dynamically created and starts DataTables_Table_ (1) ..
    Once I identify the selector if the focus is positioned on the cell. to edit it I think it would be good to doubleclk on that node, but I don't know how to do it.

  • jogugiljogugil Posts: 8Questions: 0Answers: 0
    edited January 2022

    this is the 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 search the selector 'DataTables_Table_(XXX)' in a dinamic table into shiny...

    thankssss..

Sign In or Register to comment.