Skip to content

Commit 90bfaa0

Browse files
committed
Close #2216: allow highlight() selectize to contain selectize.js options
1 parent 3a33b1a commit 90bfaa0

File tree

4 files changed

+76
-13
lines changed

4 files changed

+76
-13
lines changed

R/highlight.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ highlight <- function(p, on = "plotly_click", off,
115115

116116
# attach HTML dependencies (these libraries are used in the HTMLwidgets.renderValue() method)
117117
# TODO: only attach these when keys are present!
118-
if (selectize) {
118+
if (!identical(selectize, FALSE)) {
119119
p$dependencies <- c(p$dependencies, list(selectizeLib()))
120120
}
121121
if (dynamic) {

R/utils.R

+22-4
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ supply_highlight_attrs <- function(p) {
368368

369369
# defaults are now populated, allowing us to populate some other
370370
# attributes such as the selectize widget definition
371+
# TODO: this is wrong!!! What if set is missing and present?!
371372
sets <- unlist(lapply(p$x$data, "[[", "set"))
372373
keys <- setNames(lapply(p$x$data, "[[", "key"), sets)
373374
p$x$highlight$ctGroups <- i(unique(sets))
@@ -381,12 +382,29 @@ supply_highlight_attrs <- function(p) {
381382
hasKeys <- TRUE
382383

383384
# include one selectize dropdown per "valid" SharedData layer
384-
if (isTRUE(p$x$highlight$selectize)) {
385+
selectize <- p$x$highlight$selectize %||% FALSE
386+
if (!identical(selectize, FALSE)) {
387+
options <- list(items = data.frame(value = k, label = k), group = i)
388+
if (!is.logical(selectize)) {
389+
options <- modify_list(options, selectize)
390+
}
385391
# Hash i (the crosstalk group id) so that it can be used
386392
# as an HTML id client-side (i.e., key shouldn't contain spaces)
387-
p$x$selectize[[rlang::hash(i)]] <- list(
388-
items = data.frame(value = k, label = k), group = i
389-
)
393+
groupId <- rlang::hash(i)
394+
395+
# If the selectize payload has already been built, use that already built payload
396+
# (since it may have been modified at this point), unless there are new keys to consider
397+
oldSelectize <- p$x$selectize[[groupId]]
398+
if (length(oldSelectize) > 0) {
399+
missingKeys <- setdiff(k, oldSelectize$items$value)
400+
if (length(missingKeys) > 0) {
401+
warning("Overwriting the existing selectize payload for group '", i, "'. If you've previously modified this payload in some way, consider modifying it again.")
402+
} else {
403+
options <- oldSelectize
404+
}
405+
}
406+
407+
p$x$selectize[[groupId]] <- options
390408
}
391409

392410
# set default values via crosstalk api

inst/htmlwidgets/plotly.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -521,15 +521,17 @@ HTMLWidgets.widget({
521521
// communication between the widget and direct manipulation events
522522
if (x.selectize) {
523523
var selectizeID = Object.keys(x.selectize)[i];
524-
var items = x.selectize[selectizeID].items;
524+
var options = x.selectize[selectizeID];
525525
var first = [{value: "", label: "(All)"}];
526-
var opts = {
527-
options: first.concat(items),
528-
searchField: "label",
529-
valueField: "value",
530-
labelField: "label",
531-
maxItems: 50
532-
};
526+
var opts = $.extend({
527+
options: first.concat(options.items),
528+
searchField: "label",
529+
valueField: "value",
530+
labelField: "label",
531+
maxItems: 50
532+
},
533+
options
534+
);
533535
var select = $("#" + selectizeID).find("select")[0];
534536
var selectize = $(select).selectize(opts)[0].selectize;
535537
// NOTE: this callback is triggered when *directly* altering

tests/testthat/test-animate-highlight.R

+43
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,49 @@ test_that("group_by.plotly() retains crosstalk set", {
8181
expect_true(all(b$x$data[[1]]$key == row.names(mtcars)))
8282
})
8383

84+
test_that("highlight(selectize) produces a sensible payload", {
85+
p <- mtcars %>%
86+
highlight_key(~cyl, "Choose cylinder") %>%
87+
plot_ly(x = ~wt, y = ~mpg) %>%
88+
add_markers()
89+
90+
# Builds basic payload when selectize=TRUE
91+
b <- p %>%
92+
highlight(selectize = TRUE) %>%
93+
plotly_build()
94+
95+
selectize <- list(
96+
items = data.frame(value = c(6, 4, 8), label = c(6, 4, 8)),
97+
group = "Choose cylinder"
98+
)
99+
100+
expect_length(b$x$selectize, 1)
101+
expect_equal(b$x$selectize[[1]], selectize)
102+
103+
# Copies over any list() options
104+
b2 <- p %>%
105+
highlight(selectize = list(plugins = list("remove_button"))) %>%
106+
plotly_build()
107+
108+
selectize$plugins <- list("remove_button")
109+
110+
expect_length(b2$x$selectize, 1)
111+
expect_equal(b2$x$selectize[[1]], selectize)
112+
113+
# Can also tack on options after building, and plotly_build() won't overwrite
114+
b2$x$selectize[[1]] <- modifyList(
115+
b2$x$selectize[[1]], list(foo = "bar")
116+
)
117+
118+
b2 <- plotly_build(b2)
119+
120+
selectize$foo <- "bar"
121+
122+
expect_equal(b2$x$selectize[[1]], selectize)
123+
124+
125+
})
126+
84127

85128

86129
# Ignore for now https://github.com/ggobi/ggally/issues/264

0 commit comments

Comments
 (0)