Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hyperlink Onclick Not Rendering Inside Reactable Table #150

Closed
DFSAustralia opened this issue May 3, 2021 · 2 comments
Closed

Hyperlink Onclick Not Rendering Inside Reactable Table #150

DFSAustralia opened this issue May 3, 2021 · 2 comments
Labels
bug Something isn't working

Comments

@DFSAustralia
Copy link

I'm trying to create a column in a reactable table (in Shiny) that has hyperlinks, when the hyperlinks are clicked the tag id is assigned to an input variable. My code is below.

Beta = colDef(cell = function(value, index) {
                            tags$a(href = "#", id = master_stats[index, "player_id"], round(value,3), onclick = "Shiny.setInputValue('beta', $(this).attr('id'));")
                        })

When the table is rendered the hyperlinks are successfully created but the onclick event seems to be dropped.

image

If I generate the link outside the reactable table the onclick function is included so this leads me to believe there is something that reactable doesn't like about this?

Any ideas?

@glin
Copy link
Owner

glin commented May 16, 2021

Hi, you've stumbled on a quirk with how reactable uses React to render HTML tags, sorry. In React, the onclick attribute is replaced by a differently-named onClick property that takes a JavaScript function, rather than an expression. React has subtle differences in how HTML attributes are named and used, and reactable hides away those differences as much as possible. However, the event handling attributes like onclick were an oversight, and their differences seem pretty difficult to hide away. This will probably have to be a documented caveat with using HTML tags in reactable. Or maybe we could attempt to convert onclick expressions to onClick functions, but that feels sketchy.

For workarounds, I can think of 3 options:

  1. Use the React way of handling events, an onClick property that takes a JS() function. You don't have to know much about React to use this, but note that there are slight differences vs. native event handling: https://reactjs.org/docs/handling-events.html
  2. Use raw HTML rendering, and the native onclick attributes will work as usual
  3. Use reactable's cell click actions: https://glin.github.io/reactable/articles/examples.html#custom-action

Here's an example that shows each option, and thanks for reporting this.

library(reactable)
library(htmltools)

reactable(
  MASS::Cars93[, 1:5],
  columns = list(
    # Using React to handle click events (onClick function)
    # Note subtle differences and caveats in https://reactjs.org/docs/handling-events.html
    Manufacturer = colDef(
      cell = function(value, index) {
        id <- paste0("Manufacturer-", index)
        onClick <- JS(sprintf("function(e) { console.log('clicked', '%s', e.target.id) }", id))
        tags$button(id = id, onClick = onClick, value)
      }
    ),
    # Using native DOM click events (onclick attribute)
    Model = colDef(
      cell = function(value, index) {
        id <- paste0("Model-", index)
        onclick <- sprintf("console.log('clicked', '%s', this.id)", id)
        sprintf('<button id="%s" onclick="%s">%s</button>', id, onclick, value)
      },
      html = TRUE
    ),
    # Using reactable's cell click actions (onClick function below)
    Type = colDef(
      cell = function(value, index) {
        tags$button(value)
      }
    )
  ),
  onClick = JS("function(rowInfo, colInfo) {
    if (colInfo.id !== 'Type') {
      return
    }
    const id = colInfo.id + '-' + (rowInfo.index + 1)
    console.log('clicked', id)
  }")
)

(Also as a side note, I recommend using buttons instead of links for click actions, even if they have to be styled as links - https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML#onclick_events)

@glin glin added the bug Something isn't working label May 16, 2021
@glin
Copy link
Owner

glin commented Feb 20, 2022

onclick and other common event handler attributes (onchange, oninput) should now work fairly well in the dev version (32d7e23):

  • More HTML attributes are supported when rendering HTML tags, such as onclick (#150).

Here's an example of rendering buttons with onclick attributes, without the workarounds from above.

library(reactable)
library(htmltools)

reactable(
  MASS::Cars93[, 1:5],
  columns = list(
    Model = colDef(
      cell = function(value, index) {
        onclick <- sprintf("console.log('clicked row %s, element', this, event.target)", index)
        tags$button(onclick = onclick, value)
      }
    )
  )
)

@glin glin closed this as completed Feb 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants