Is it possible for showNotification()
to pop up at the location the mouse was clicked? More specifically, I have a table and I want an actionButton to pop-up near each clicked row.
Here is a reproducible example:
library(shiny)
library(DT)
ui <- fluidPage(
tags$script(HTML("
$(document).on('click', 'table tbody tr', function(e) {
Shiny.setInputValue('click_coords', {x: e.pageX, y: e.pageY}, {priority: 'event'});
});
Shiny.addCustomMessageHandler('adjustNotifPosition', function(message) {
$('.shiny-notification').css({
'top': message.y + 'px',
'left': message.x + 'px'
});
});
")),
tags$style(HTML("
.shiny-notification {
width: 250px;
height: auto;
position: fixed;
background-color: #FFD700; /* Gold background */
color: black;
font-weight: bold;
border: 2px solid black;
border-radius: 15px;
padding: 10px;
text-align: center;
}
")),
DT::dataTableOutput('summary_table')
)
server <- function(input, output, session) {
data <- data.frame(
ID = 1:1000,
Value = rnorm(1000)
)
output$summary_table <- DT::renderDataTable({
datatable(data, selection = 'single')
}, server = FALSE)
observeEvent(input$click_coords, {
if (!is.null(input$summary_table_rows_selected)) {
selected_row <- input$summary_table_rows_selected
# Show the notification
showNotification(
paste("You selected row number", selected_row),
closeButton = TRUE,
duration = NULL,
action = actionButton("go_to_figure_tables", "Go to Figure Tables"),
id = "notif"
)
x_coord <- input$click_coords$x
y_coord <- input$click_coords$y
# Adjust its position
session$sendCustomMessage('adjustNotifPosition', list(x = x_coord, y = y_coord))
}
})
observeEvent(input$go_to_figure_tables, {
# Handle the action here
print("Go to Figure Tables button clicked!")
removeNotification(id = "notif")
})
}
shinyApp(ui, server)
It works okay but if I set the number of entries large enough to have to scroll down, the pop-up doesn't show at the proper place.
If you want to get the correct position also when your table is scrollable, you have to subtract $(document).scrollLeft()
from e.pageX
and $(document).scrollTop()
from e.pageY
.
$(document).on('click', 'table tbody tr', function(e) {
Shiny.setInputValue('click_coords', {
x: e.pageX - $(document).scrollLeft(),
y: e.pageY - $(document).scrollTop()
}, {
priority: 'event'
});
});