-
Notifications
You must be signed in to change notification settings - Fork 31
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
Adds ability to update rank_list
labels and exports update_rank_list
#95
Conversation
|
@schloerke This should be ready for another review |
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! Thank you @yogat3ch
(Did not test)
Thank you. This looks very promising. However, I found one problem: it doesn't seem to be possible to update an empty You can reproduce this using the modified example app at ## ---- update-bucket-list-app -----------------------------------------------
## Example shiny app with bucket list
library(shiny)
library(sortable)
library(magrittr)
ui <- fluidPage(
tags$head(
tags$style(HTML(".bucket-list-container {min-height: 350px;}"))
),
fluidRow(
column(
width = 12,
h2("Update the title"),
actionButton("btnUpdateBucket", label = "Update bucket list title"),
actionButton("btnUpdateLabelsFrom", label = "Add item to 'Drag from here'"),
actionButton("btnUpdateLabelsTo", label = "Add item to 'To here'")
)
),
fluidRow(
column(
h2("Exercise"),
width = 12,
bucket_list(
header = "Drag the items in any desired bucket",
group_name = "bucket_list_group",
orientation = "horizontal",
add_rank_list(
text = "Drag from here",
labels = list(
"1"
),
input_id = "rank_list_from"
),
add_rank_list(
text = "to here",
labels = NULL,
input_id = "rank_list_to"
)
)
)
)
)
server <- function(input, output, session) {
# test updating the bucket list label
counter_bucket <- reactiveVal(1)
counter_label <- reactiveVal(1)
observe({
update_bucket_list(
"bucket_list_group",
header = paste("You pressed the update button", counter_bucket(), "times"),
session = session
)
counter_bucket(counter_bucket() + 1)
}) %>%
bindEvent(input$btnUpdateBucket)
observe({
counter_label(counter_label() + 1)
update_rank_list(
"rank_list_from",
labels = c(input$rank_list_from, counter_label())
)
}) %>%
bindEvent(input$btnUpdateLabelsFrom)
observe({
counter_label(counter_label() + 1)
update_rank_list(
"rank_list_to",
labels = c(input$rank_list_to, counter_label())
)
}) %>%
bindEvent(input$btnUpdateLabelsTo)
observe({
len <- length(input$rank_list_to)
count_word <- if(len == 0) "" else glue::glue("({len})")
update_rank_list(
"rank_list_to",
text = paste0("To here ", count_word),
session = session
)
}) %>%
bindEvent(input$rank_list_to)
}
shinyApp(ui, server) |
Thanks @andrie, I'll look into this soon |
Hi @andrie, |
ad609f2
to
cbcb580
Compare
It looks like the handling of the |
Hey @andrie & @schloerke, I'm trying to hunt down the differences in how the |
@yogat3ch hoping I'll be able to look at it tomorrow |
Awesome, thank you @schloerke |
Ok. So
When these values are set, they are unaware of the Reasoning:
I'm too far removed from the code to remember why I used If the The other workaround that I can think of is to use some form of https://github.com/rstudio/shiny/blob/e7b830755ac6da2773c9ff15fc6f9395c0c4bf87/R/modules.R#LL47C1-L61C2 to recursively look for the root Shiny session given a module's This method could be called within # Given a session_proxy, search `parent` recursively to find the real
# ShinySession object. If given a ShinySession, simply return it.
find_ancestor_session <- function(x, depth = 20) {
if (depth < 0) {
stop("ShinySession not found")
}
if (inherits(x, "ShinySession")) {
return(x)
}
if (inherits(x, "session_proxy")) {
return(find_ancestor_session(.subset2(x, "parent"), depth-1))
}
stop("ShinySession not found")
}
update_bucket_list <- function(css_id,
header = NULL,
labels = NULL,
session = shiny::getDefaultReactiveDomain()) {
rootSession <- find_ancestor_session(session)
inputId <- paste0("bucket-list-", css_id)
message <- dropNulls(list(id = css_id, header = header, labels = labels))
rootSession$sendInputMessage(inputId, message)
} @yogat3ch I'm pretty sure this would work and users would not need to alter their current sortable code. While I'm usually opposed to using internal-like methods, I believe this is the cleanest solution going forward. |
I'm trying my suggestion above and I can not get it to work as I expected. I've run out of time for today. Workaround is to not use modules for sortable. That stinks for an answer, but anything I'm coming up with is to undo what a module provides. This being said, we should prolly fix |
FYI, I'm going to switch my attention to this topic. I'm going to start by reviewing your approach, and have one idea in mind to deal with setting empty By default an argument of My proposal is to use an empty list to indicate this, e.g. I'm going to attempt to get this to work, starting from your PR. |
@yogat3ch , the ideas in this PR are really valuable, and I have been cherry-picking some changes. However, in the process I discovered that there were some problems with this implementation, particularly:
In the end, I found it easier to re-implement the key ideas and will be tracking this in the PR #113. That PR already has fully functional support for Many thanks for your contribution. |
Sorry for the long absence on this, I took a hiatus from data science. Thank you for extracting the working bits and ideas and creating a working implementation @andrie ! |
Fixes #100
Hi
sortable
devs,We needed the ability to update labels on a
sortable
rank list so I managed to get it working withshinyjs
and figured I would adapt the solution to use the more conventional way by sending shiny custom messages.This is my first go at building
customMessageHandler
s for shiny so I hope this is helpful!This PR:
@examples
tags to theupdate_rank_list
docscustomMessageHandler
to update the labels of asortable::rank_list
Any suggestions or is this good to go?