From 754475011260aabcf97e7c1c04bf8becdcbc37fc Mon Sep 17 00:00:00 2001 From: rcst Date: Tue, 25 Nov 2025 09:17:41 +0100 Subject: [PATCH] Fix namespacing for Shiny modules This commit addresses Issue #100. The rank-list widget currently does not get updated when used within a Shiny module. Shiny.sendInputMessage(inputID, message) automatically applies namespacing to inputID (the first parameter), however the widget consists of 2 nested HTML-IDs - the rank-list container and the actual list. Shiny.sendInputMessage only applies namespacing to the provided inputID, but not to inputIDs contained inside the message list-object. In `update_rank_list()`, the way that the provided inputID is processed will make it refer to the container's ID. The rank-list input binding's setValue function has been changed to take this into account and now adds any namespace prefix to the nested input ID. To do this, the namespace has been added explicitly to the message list-object in `update_rank_list()`. Also, `as_rank_list_id()` and `as_bucket_list_id()` both now append (instead of prepend) "-rank-list" to enable Shiny module namespacing as suggested in the respective comment in `methods.R`. Changes: - Updated as_rank_list_id() append "-rank-list" to provided ID. - Improve rank-list JS binding to correctly apply namespacing to the input ID within the message object itself Fixes rstudio/sortable#100 --- R/methods.R | 6 ++++-- R/rank_list.R | 10 ++++++++-- .../plugins/sortable-rstudio/rank_list_binding.js | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/R/methods.R b/R/methods.R index c2fabe7..b5a0606 100644 --- a/R/methods.R +++ b/R/methods.R @@ -25,13 +25,15 @@ print.bucket_list <- function(x, ...){ # The names must be suffix values to allow for modules which use prefix values # https://github.com/rstudio/sortable/issues/100 as_rank_list_id <- function(id) { - paste0("rank-list-", id) + # paste0("rank-list-", id) + paste0(id, "-rank-list") } # TODO: in future, change the order of paste, to enable shiny modules # paste0(id, "-rank-list") as_bucket_list_id <- function(id) { - paste0("bucket-list-", id) + # paste0("bucket-list-", id) + paste0(id, "-bucket-list") } # TODO: in future, change the order of paste, to enable shiny modules # paste0(id, "-bucket-list") diff --git a/R/rank_list.R b/R/rank_list.R index 78a8c43..48a35a3 100644 --- a/R/rank_list.R +++ b/R/rank_list.R @@ -164,9 +164,15 @@ update_rank_list <- function(css_id, text = NULL, labels = NULL, if ( !is.null(labels) && length(labels) > 0) { labels <- as.character(tagList(as_label_tags(labels))) } - message <- dropNulls(list(id = inputId, text = text, labels = labels)) - session$sendInputMessage(inputId, message) + # include namespace in message + # to conveniently correct the nested input IDs + # of a rank-list widget inside rank_list_binding.js + message <- dropNulls(list(id = inputId, + text = text, + labels = labels, + namespace = session$ns(""))) + session$sendInputMessage(inputId, message) } diff --git a/inst/htmlwidgets/plugins/sortable-rstudio/rank_list_binding.js b/inst/htmlwidgets/plugins/sortable-rstudio/rank_list_binding.js index c20e384..153b2a8 100644 --- a/inst/htmlwidgets/plugins/sortable-rstudio/rank_list_binding.js +++ b/inst/htmlwidgets/plugins/sortable-rstudio/rank_list_binding.js @@ -22,7 +22,7 @@ $.extend(ranklistBinding, { } if (data.labels) { - const short_id = data.id.replace(/^rank-list-/, ""); + const short_id = data.namespace + data.id.replace(/-rank-list$/, ""); $('#' + short_id).html(data.labels); const label_ids = $('#' + short_id).children().map((idx, child) => { return $(child).attr("data-rank-id") || $.trim(child.innerHTML);