% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dependencies.R
\docType{data}
\name{selectors}
\alias{selectors}
\alias{ALL}
\alias{ALLSMALLER}
\alias{MATCH}
\title{Pattern-Matching Callback Selectors}
\format{
An object of class \code{name} of length 1.

An object of class \code{name} of length 1.

An object of class \code{name} of length 1.
}
\usage{
ALL

ALLSMALLER

MATCH
}
\description{
Symbols which reference pattern-matching callback selectors with the same names
}
\details{
\code{ALL}, \code{ALLSMALLER} and \code{MATCH} are symbols corresponding to the
pattern-matching callback selectors with the same names. These allow you
to write callbacks that respond to or update an arbitrary or dynamic
number of components. Because they are symbols (see \link{name}) rather than
functions, each has no arguments. For more information, see the \code{callback}
section in \link{Dash}.

For pattern-matching callbacks, the \code{id} field of a component is written
in JSON-like syntax. The resulting \code{id} is then transformed into a dictionary
object when serialized for use by the Dash renderer within the web browser.
The fields are arbitrary keys, which describe the targets of the callback.

For example, when we write \verb{input(id=list("foo" = ALL, "bar" = "dropdown")},
Dash interprets this as "match any input that has an ID list where 'foo'
is 'ALL' and 'bar' is anything." If any of the dropdown
\code{value} properties change, all of their values are returned to the callback.

However, for readability, we recommend using keys like type, index, or id.
\code{type} can be used to refer to the class or set of dynamic components and
\code{index} or \code{id} could be used to refer to the component you are matching
within that set. While your application may have a single set of dynamic
components, it's possible to specify multiple sets of dynamic components
in more complex apps or if you are using \code{MATCH}.

Like \code{ALL}, \code{MATCH} will fire the callback when any of the component's properties
change. However, instead of passing all of the values into the callback, \code{MATCH}
will pass just a single value into the callback. Instead of updating a single
output, it will update the dynamic output that is "matched" with.

\code{ALLSMALLER} is used to pass in the values of all of the targeted components
on the page that have an index smaller than the index corresponding to the div.
For example, \code{ALLSMALLER} makes it possible to filter results that are
increasingly specific as the user applies each additional selection.

\code{ALLSMALLER} can only be used in \code{input} and \code{state} items, and must be used
on a key that has \code{MATCH} in the \code{output} item(s). \code{ALLSMALLER} it isn't always
necessary (you can usually use \code{ALL} and filter out the indices in your callback),
but it will make your logic simpler.
}
\examples{
if (interactive() ) {
  library(dash)

  # Simple example illustrating use of ALL selector
  app <- Dash$new()

  app$layout(htmlDiv(list(
    htmlButton("Add Filter", id="add-filter", n_clicks=0),
    htmlDiv(id="dropdown-container", children=list()),
    htmlDiv(id="dropdown-container-output")
  )))


  app$callback(
    output(id="dropdown-container", property = "children"),
    params = list(
      input(id = "add-filter", property = "n_clicks"),
      state(id = "dropdown-container", property = "children")
    ),
    display_dropdowns <- function(n_clicks, children){
      new_dropdown = dccDropdown(
        id=list(
          "index" = n_clicks,
          "type" = "filter-dropdown"
        ),
        options = lapply(c("NYC", "MTL", "LA", "TOKYO"), function(x){
          list("label" = x, "value" = x)
        })
      )
      children[[n_clicks + 1]] <- new_dropdown
      return(children)
    }
  )

  app$callback(
    output(id="dropdown-container-output", property="children"),
    params = list(
      input(id=list("index" = ALL, "type" = "filter-dropdown"), property= "value")
    ),
    display_output <- function(test){
      ctx <- app$callback_context()
      return(htmlDiv(
        lapply(seq_along(test), function(x){
          return(htmlDiv(sprintf("Dropdown \%s = \%s", x, test[[x]])))
        })
      ))
    }
  )

  app$run_server()

  # Simple example illustrating use of ALLSMALLER selector
  library(dash)

  df <- read.csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv',
                 stringsAsFactors = FALSE)

  app <- Dash$new()

  app$layout(htmlDiv(list(
    htmlButton("Add Filter", id = "add-filter-ex3", n_clicks = 0),
    htmlDiv(id = "container-ex3", children = list())
  )))

  app$callback(
    output('container-ex3', 'children'),
    params = list(
      input('add-filter-ex3', 'n_clicks'),
      state('container-ex3', 'children')
    ),
    display_dropdowns <- function(n_clicks, existing_children){
      new_children <- htmlDiv(list(
        dccDropdown(
          id = list("index" = n_clicks, "type" = "filter-dropdown-ex3"),
          options = lapply(unique(df$country), function(x){
            list("label" = x, "value" = x)
          }),
          value = unique(df$country)[n_clicks + 1]
        ),
        htmlDiv(id = list("index" = n_clicks, "type" = "output-ex3"),
                children = list(unique(df$country)[n_clicks + 1]))
      ))

      existing_children <- c(existing_children, list(new_children))
    }
  )

  app$callback(
    output(id = list("type" = "output-ex3", "index" = MATCH), property = "children"),
    params = list(
      input(id = list("type" = "filter-dropdown-ex3", "index" = MATCH), property = "value"),
      input(id = list("type" = "filter-dropdown-ex3", "index" = ALLSMALLER), property = "value")
    ),
    display_output <- function(matching_value, previous_values){
      previous_values_in_reversed_order = rev(previous_values)
      all_values = c(matching_value, previous_values_in_reversed_order)
      all_values = unlist(all_values)

      dff = df[df$country \%in\% all_values,]
      avgLifeExp = round(mean(dff$lifeExp), digits = 2)

      if (length(all_values) == 1) {
        return(
          htmlDiv(sprintf("\%s is the life expectancy of \%s.",
                  avgLifeExp,
                  matching_value))
        )
      } else if (length(all_values) == 2) {
        return(
          htmlDiv(sprintf("\%s is the life expectancy of \%s.",
                          avgLifeExp,
                          paste(all_values, collapse = " and ")))
        )
      } else {
        return(
          htmlDiv(sprintf("\%s is the life expectancy of \%s, and \%s.",
                  avgLifeExp,
                  paste(all_values[-length(all_values)], collapse = " , "),
                  paste(all_values[length(all_values)])))
        )
      }
    }
  )

  app$run_server()

  # Simple example illustrating use of MATCH selector
  library(dash)

  app <- Dash$new()

  app$layout(htmlDiv(list(
    htmlButton("Add Filter", id="dynamic-add-filter", n_clicks=0),
    htmlDiv(id="dynamic-dropdown-container", children = list())
  )))

  app$callback(
    output(id="dynamic-dropdown-container", "children"),
    params = list(
      input("dynamic-add-filter", "n_clicks"),
      state("dynamic-dropdown-container", "children")
    ),
    display_dropdown <- function(n_clicks, children){
      new_element = htmlDiv(list(
        dccDropdown(
          id = list("index" = n_clicks, "type" = "dynamic-dropdown"),
          options = lapply(c("NYC", "MTL", "LA", "TOKYO"), function(x){
            list("label" = x, "value" = x)
          })
        ),
        htmlDiv(
          id = list("index" = n_clicks, "type" = "dynamic-output"),
          children = list()
        )
      ))

      children <- c(children, list(new_element))
      return(children)
    }
  )

  app$callback(
    output(id = list("index" = MATCH, "type" = "dynamic-output"), property= "children"),
    params = list(
      input(id=list("index" = MATCH, "type" = "dynamic-dropdown"), property= "value"),
      state(id=list("index" = MATCH, "type" = "dynamic-dropdown"), property= "id")
    ),
    display_output <- function(value, id){
      return(htmlDiv(sprintf("Dropdown \%s = \%s", id$index, value)))
    }
  )

  app$run_server()
}
}
\keyword{datasets}
