-
Notifications
You must be signed in to change notification settings - Fork 210
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
Allow selection in interactive tables #1909
Conversation
Add an option `ihtml_selection` (default NULL, can be "single" or "multiple") to enable selection in interactive gt tables. When this is on, make it available as an input in Shiny. Closes rstudio#354. Closes rstudio#1368.
So far I've just set up the option. I need to add tests, and then move on to the Shiny side. |
I have a bunch of console.log()s in here right now as I debug. If you run Shiny.bindAll(); in Chrome devtools, this works, but not before then so I'm missing a step somewhere. I'm not actually certain that the unsubscribe() method works, and I'm not yet certain how to test that.
…hacky so I'm not sure this is the final thing yet.
A test app to see it in action: # Launch the ShinyApp (Do not remove this comment)
# To deploy, run: rsconnect::deployApp()
# Or use the blue button on top of this file
library(shiny)
pkgload::load_all(".", helpers = FALSE, attach_testthat = FALSE)
gt_tbl <-
gtcars |>
gt() |>
fmt_currency(columns = msrp, decimals = 0) |>
cols_hide(columns = -c(mfr, model, year, mpg_c, msrp)) |>
cols_label_with(columns = everything(), fn = toupper) |>
data_color(columns = msrp, method = "numeric", palette = "viridis") |>
sub_missing() |>
opt_interactive(use_compact_mode = TRUE, selection = "multiple")
ui <- fluidPage(
gt_output(outputId = "table"),
verbatimTextOutput("selected")
)
server <- function(input, output, session) {
output$table <- render_gt(expr = gt_tbl)
output$selected <- renderPrint({
input$table
})
}
shinyApp(ui = ui, server = server) Add this to preview an alternate UI that I'm playing with (I'll probably add something like this as a separate function): gt_tbl <- opt_css(gt_tbl, "
/* Hide the selection column */
.rt-td-select {
display: none;
}
/* Style for selected rows */
.rt-tr-selected {
background-color: black;
color: white;
}") I'm hoping I can learn a better way to wait for the tables to be "done" via the Discord! |
A more exhaustive demo app, which caught some bugs: # Launch the ShinyApp (Do not remove this comment)
# To deploy, run: rsconnect::deployApp()
# Or use the blue button on top of this file
library(shiny)
pkgload::load_all(".", helpers = FALSE, attach_testthat = FALSE)
ui <- bslib::page_navbar(
bslib::nav_panel(
title = "filter",
shiny::selectInput(
"manufacturer",
"Manufacturer:",
sort(unique(gtcars$mfr))
)
),
bslib::nav_panel(
title = "table",
gt_output(outputId = "gt_table"),
verbatimTextOutput("selected")
),
bslib::nav_panel(
title = "table2",
gt_output(outputId = "gt_table2"),
verbatimTextOutput("selected2")
)
)
server <- function(input, output, session) {
gt_data <- reactive({
req(input$manufacturer)
return(dplyr::filter(gtcars, .data$mfr == input$manufacturer))
})
output$gt_table <- render_gt(expr = {
gt_data() |>
gt() |>
fmt_currency(columns = msrp, decimals = 0) |>
cols_hide(columns = -c(mfr, model, year, mpg_c, msrp)) |>
cols_label_with(columns = everything(), fn = toupper) |>
data_color(columns = msrp, method = "numeric", palette = "viridis") |>
sub_missing() |>
opt_interactive(use_compact_mode = TRUE, selection = "multiple") |>
opt_css(
"/* Hide the selection column */
.rt-td-select {
display: none;
}
/* Style for selected rows */
.rt-tr-selected {
background-color: black;
color: white;
}"
)
})
output$selected <- renderPrint({
gt_data()$model[input$gt_table]
})
output$gt_table2 <- render_gt(expr = {
gtcars |>
gt() |>
fmt_currency(columns = msrp, decimals = 0) |>
cols_hide(columns = -c(mfr, model, year, mpg_c, msrp)) |>
cols_label_with(columns = everything(), fn = toupper) |>
data_color(columns = msrp, method = "numeric", palette = "viridis") |>
sub_missing() |>
opt_interactive(use_compact_mode = TRUE, selection = "multiple") |>
opt_css(
"/* Hide the selection column */
.rt-td-select {
display: none;
}
/* Style for selected rows */
.rt-tr-selected {
background-color: black;
color: white;
}"
)
})
output$selected2 <- renderPrint({
input$gt_table2
})
}
shinyApp(ui = ui, server = server) I'd still like to get tests in place for the Shiny part, since it's much more involved now (but none of the Shiny is currently tested). I also need to test what happens if a gt table is added dynamically. I still feel like there HAS to be a way to get Shiny to see the gt tables without the |
Pulling this back to draft to add an update function. If we're highlighting selections, I want to be able to set the highlight. |
…e used to update the selection in a gt table in Shiny. The gt input also now differentiates between "nothing is selected because this table has just initialized" and "nothing is selected because the user deselected everything," which is very useful for updating related inputs and avoiding loops. I think this is done. Let me know if you'd like more tests or examples (or anything else)! I'd love to use this, so let me know what I need to do to help push it over the goal line!
@rich-iannone I fixed the pkgdown issue. Let me know what else you need! |
Found another corner: sorting sends an event that causes the selection to update (potentially to "nothing selected"), which shouldn't be seen as a change. Fixing. |
Also refactored getValue for readability.
I want to add the ability to pass in selection row numbers, so I needed to make room in the option name for another selection-related option.
Adding pre-selected values is proving tricky using the option system. I don't see a way for an option to be an integer or logical vector, and I'm not sure it would fit there even if it were possible. I can work around that not being there for my use case, so I think I'd rather hold onto that for a future PR. Which is all to say... I think this is ready again! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@rich-iannone Sorry about that! Evidently I never ran that suite of tests after I renamed the fields. I was trying to make room to pass in pre-selected values, and forgot to fix the test after I rolled back almost everything (other than the name of the field). Should be good now, for real this time! |
@jonthegeek thanks for all your work on this! |
Summary
Add an option
ihtml_selection
(default NULL, can be "single" or "multiple") to enable selection in interactive gt tables. When this is on, make it available as an input in Shiny.Related GitHub Issues and PRs
Checklist
testthat
unit tests totests/testthat
for any new functionality.