mirror of
https://github.com/rstudio/shiny.git
synced 2026-04-07 03:00:20 -04:00
Merge pull request #411 from yihui/selectize/backspace
Selectize backspace issue
This commit is contained in:
4
NEWS
4
NEWS
@@ -13,6 +13,10 @@ shiny 0.8.0.99
|
||||
selectize.js (https://github.com/brianreavis/selectize.js), which extends
|
||||
the basic select input in many aspects.
|
||||
|
||||
* The `selectInput()` function also gained a new argument `selectize = TRUE`
|
||||
to makes use of selectize.js by default. If you want to revert back to the
|
||||
original select input, you have to call selectInput(..., selectize = FALSE).
|
||||
|
||||
* Upgraded to Bootstrap 2.3.2 and jQuery 1.11.0.
|
||||
|
||||
* Make `tags$head()` and `singleton()` behave correctly when used with
|
||||
|
||||
@@ -686,6 +686,7 @@ choicesWithNames <- function(choices) {
|
||||
#' \code{multiple = TRUE}). If not specified then defaults to the first value
|
||||
#' for single-select lists and no values for multiple select lists.
|
||||
#' @param multiple Is selection of multiple items allowed?
|
||||
#' @param selectize Whether to use \pkg{selectize.js} or not.
|
||||
#' @return A select list control that can be added to a UI definition.
|
||||
#'
|
||||
#' @family input elements
|
||||
@@ -697,11 +698,8 @@ choicesWithNames <- function(choices) {
|
||||
#' "Transmission" = "am",
|
||||
#' "Gears" = "gear"))
|
||||
#' @export
|
||||
selectInput <- function(inputId,
|
||||
label,
|
||||
choices,
|
||||
selected = NULL,
|
||||
multiple = FALSE) {
|
||||
selectInput <- function(inputId, label, choices, selected = NULL,
|
||||
multiple = FALSE, selectize = TRUE) {
|
||||
# resolve names
|
||||
choices <- choicesWithNames(choices)
|
||||
|
||||
@@ -731,21 +729,36 @@ selectInput <- function(inputId,
|
||||
selectTag <- tagSetChildren(selectTag, list = optionTags)
|
||||
|
||||
# return label and select tag
|
||||
tagList(controlLabel(inputId, label), selectTag)
|
||||
res <- tagList(controlLabel(inputId, label), selectTag)
|
||||
if (!selectize) return(res)
|
||||
selectizeIt(inputId, res, NULL, nonempty = !multiple && !("" %in% choices))
|
||||
}
|
||||
|
||||
#' @rdname selectInput
|
||||
#' @param ... arguments passed to \code{selectInput()}
|
||||
#' @param options a list of options; see the documentation of \pkg{selectize.js}
|
||||
#' @param ... Arguments passed to \code{selectInput()}.
|
||||
#' @param options A list of options. See the documentation of \pkg{selectize.js}
|
||||
#' for possible options (character option values inside \code{\link{I}()} will
|
||||
#' be treated as literal JavaScript code; see \code{\link{renderDataTable}()}
|
||||
#' for details)
|
||||
#' for details).
|
||||
#' @note The selectize input created from \code{selectizeInput()} allows
|
||||
#' deletion of the selected option even in a single select input, which will
|
||||
#' return an empty string as its value. This is the default behavior of
|
||||
#' \pkg{selectize.js}. However, the selectize input created from
|
||||
#' \code{selectInput(..., selectize = TRUE)} will ignore the empty string
|
||||
#' value when it is a single choice input and the empty string is not in the
|
||||
#' \code{choices} argument. This is to keep compatibility with
|
||||
#' \code{selectInput(..., selectize = FALSE)}.
|
||||
#' @export
|
||||
selectizeInput <- function(inputId, ..., options = NULL) {
|
||||
selectizeIt(inputId, selectInput(inputId, ..., selectize = FALSE), options)
|
||||
}
|
||||
|
||||
# given a select input and its id, selectize it
|
||||
selectizeIt <- function(inputId, select, options, nonempty = FALSE) {
|
||||
res <- checkAsIs(options)
|
||||
|
||||
tagList(
|
||||
selectInput(inputId, ...),
|
||||
select,
|
||||
singleton(tags$head(
|
||||
tags$link(rel = 'stylesheet', type = 'text/css',
|
||||
href = 'shared/selectize/css/selectize.bootstrap2.css'),
|
||||
@@ -755,7 +768,8 @@ selectizeInput <- function(inputId, ..., options = NULL) {
|
||||
tags$script(src = 'shared/selectize/js/selectize.min.js')
|
||||
)),
|
||||
tags$script(
|
||||
type = 'application/json', `data-for` = inputId,
|
||||
type = 'application/json',
|
||||
`data-for` = inputId, `data-nonempty` = if (nonempty) '',
|
||||
`data-eval` = if (length(res$eval)) HTML(toJSON(res$eval)),
|
||||
if (length(res$options)) HTML(toJSON(res$options)) else '{}'
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ test_that("CSS unit validation", {
|
||||
}
|
||||
|
||||
# Test strings and expected results
|
||||
strings <- c("100x", "10px", "10.4px", ".4px", "1px0", "px", "5", "%", "5%", "auto", "1auto", "")
|
||||
strings <- c("100x", "10px", "10.4px", ".4px", "1px0", "px", "5", "%", "5%", "auto", "1auto", "")
|
||||
expected <- c(NA, "10px", "10.4px", ".4px", NA, NA, NA, NA, "5%", "auto", NA, NA)
|
||||
results <- vapply(strings, validateCssUnit_wrap, character(1), USE.NAMES = FALSE)
|
||||
expect_equal(results, expected)
|
||||
@@ -22,7 +22,7 @@ test_that("Repeated names for selectInput and radioButtons choices", {
|
||||
# tag object, but they get the job done for now.
|
||||
|
||||
# Select input
|
||||
x <- selectInput('id','label', choices = c(a='x1', a='x2', b='x3'))
|
||||
x <- selectInput('id','label', choices = c(a='x1', a='x2', b='x3'), selectize = FALSE)
|
||||
choices <- x[[2]]$children
|
||||
|
||||
expect_equal(choices[[1]]$children[[1]], 'a')
|
||||
|
||||
@@ -85,7 +85,7 @@ span.jslider {
|
||||
|
||||
.crosshair {
|
||||
cursor: crosshair;
|
||||
}
|
||||
}
|
||||
|
||||
.well input[type="text"],
|
||||
.well input[type="number"],
|
||||
@@ -97,3 +97,8 @@ span.jslider {
|
||||
.qt pre, .qt code {
|
||||
font-family: monospace !important;
|
||||
}
|
||||
|
||||
/* consistency with bootstrap.css for selectize.js */
|
||||
.selectize-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@@ -2041,6 +2041,20 @@
|
||||
valueField: 'value',
|
||||
searchField: ['label']
|
||||
}, JSON.parse(config.html()));
|
||||
if (config.data('nonempty') !== undefined) {
|
||||
options = $.extend(options, {
|
||||
onItemRemove: function(value) {
|
||||
if (this.getValue() === "")
|
||||
$("select[id=" + el.id + "]").empty().append($("<option/>", {
|
||||
"value": value, "selected": true
|
||||
})).trigger("change");
|
||||
},
|
||||
onDropdownClose: function($dropdown) {
|
||||
if (this.getValue() === "")
|
||||
this.setValue($("select[id=" + el.id + "]").val());
|
||||
}
|
||||
});
|
||||
}
|
||||
// options that should be eval()ed
|
||||
if (config.data('eval') instanceof Array)
|
||||
$.each(config.data('eval'), function(i, x) {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
\alias{selectizeInput}
|
||||
\title{Create a select list input control}
|
||||
\usage{
|
||||
selectInput(inputId, label, choices, selected = NULL, multiple = FALSE)
|
||||
selectInput(inputId, label, choices, selected = NULL, multiple = FALSE,
|
||||
selectize = TRUE)
|
||||
|
||||
selectizeInput(inputId, ..., options = NULL)
|
||||
}
|
||||
@@ -25,13 +26,16 @@ selectizeInput(inputId, ..., options = NULL)
|
||||
|
||||
\item{multiple}{Is selection of multiple items allowed?}
|
||||
|
||||
\item{...}{arguments passed to \code{selectInput()}}
|
||||
\item{selectize}{Whether to use \pkg{selectize.js} or
|
||||
not.}
|
||||
|
||||
\item{options}{a list of options; see the documentation
|
||||
\item{...}{Arguments passed to \code{selectInput()}.}
|
||||
|
||||
\item{options}{A list of options. See the documentation
|
||||
of \pkg{selectize.js} for possible options (character
|
||||
option values inside \code{\link{I}()} will be treated as
|
||||
literal JavaScript code; see
|
||||
\code{\link{renderDataTable}()} for details)}
|
||||
\code{\link{renderDataTable}()} for details).}
|
||||
}
|
||||
\value{
|
||||
A select list control that can be added to a UI definition.
|
||||
@@ -45,6 +49,16 @@ multiple items from a list of values.
|
||||
(\url{https://github.com/brianreavis/selectize.js}) to extend the basic
|
||||
select input element.
|
||||
}
|
||||
\note{
|
||||
The selectize input created from \code{selectizeInput()} allows
|
||||
deletion of the selected option even in a single select input, which will
|
||||
return an empty string as its value. This is the default behavior of
|
||||
\pkg{selectize.js}. However, the selectize input created from
|
||||
\code{selectInput(..., selectize = TRUE)} will ignore the empty string
|
||||
value when it is a single choice input and the empty string is not in the
|
||||
\code{choices} argument. This is to keep compatibility with
|
||||
\code{selectInput(..., selectize = FALSE)}.
|
||||
}
|
||||
\examples{
|
||||
selectInput("variable", "Variable:",
|
||||
c("Cylinders" = "cyl",
|
||||
|
||||
Reference in New Issue
Block a user