Skip to content

Commit

Permalink
added treecheckInput()
Browse files Browse the repository at this point in the history
  • Loading branch information
pvictor committed May 13, 2020
1 parent 0a373cf commit 63219d9
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 6 deletions.
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ export(collapseTreeview)
export(expandTreeview)
export(make_tree)
export(searchTreeview)
export(treecheckInput)
export(treeviewInput)
importFrom(htmltools,htmlDependencies)
importFrom(htmltools,htmlDependency)
importFrom(htmltools,tags)
importFrom(htmltools,validateCssUnit)
importFrom(jsonlite,toJSON)
importFrom(shiny,addResourcePath)
importFrom(shiny,icon)
importFrom(shiny,registerInputHandler)
62 changes: 62 additions & 0 deletions R/input-treecheck.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#' Tree check Input
#'
#' @inheritParams treeviewInput
#' @param hierarchical When a level is selected, also select all levels below it?
#'
#' @return Server-side: A \code{character} value or a \code{list} depending on the \code{return_value} argument.
#' @export
#'
#' @importFrom htmltools tags validateCssUnit htmlDependencies
#' @importFrom shiny icon
#' @importFrom jsonlite toJSON
#'
#' @example examples/treecheck.R
treecheckInput <- function(inputId,
label = NULL,
choices,
selected = NULL,
hierarchical = TRUE,
levels = 1,
borders = TRUE,
return_value = c("name", "id", "all"),
width = NULL) {
return_value <- match.arg(return_value)
options <- dropNulls(list(
config = c(
list(
data = choices,
levels = levels,
showBorder = borders,
showCheckbox = TRUE,
highlightSelected = FALSE,
propagateCheckEvent = hierarchical,
hierarchicalCheck = hierarchical,
uncheckedIcon = "fa fa-square-o",
partiallyCheckedIcon = "fa fa-minus-square-o",
checkedIcon = "fa fa-check-square-o",
expandIcon = "fa fa-chevron-right",
collapseIcon = "fa fa-chevron-down"
)
),
selected = list1(selected)
))

tags$div(
class = "form-group shiny-input-container",
style = if(!is.null(width)) paste("width:", validateCssUnit(width)),
if (!is.null(label)) {
tags$label(class = "control-label", `for` = inputId, label)
},
tags$div(
id = inputId, class = "treecheck-input",
`data-return` = return_value,
tags$script(
type = "application/json", `data-for` = inputId,
jsonlite::toJSON(options, auto_unbox = TRUE, json_verbatim = TRUE)
)
),
html_dependency_treeview(),
htmlDependencies(icon("home"))
)
}
2 changes: 1 addition & 1 deletion R/input-treeview.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#' \code{"all"} to returned all the tree under the element selected.
#' @param width The width of the input, e.g. \code{'400px'}, or \code{'100\%'}.
#'
#' @return A \code{character} value or a \code{list} depending on the \code{return_value} argument.
#' @return Server-side: A \code{character} value or a \code{list} depending on the \code{return_value} argument.
#' @export
#'
#' @importFrom htmltools tags validateCssUnit
Expand Down
53 changes: 49 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ remotes::install_github("dreamRs/shinytreeview")

## Example

![](man/figures/example-cities.png)
`treeviewInput()` allow to select a value (or several) in a hierarchical structure :

![](man/figures/example-treeview.png)

Code for this example:

```r
library(shiny)
Expand All @@ -31,9 +35,49 @@ ui <- fluidPage(
treeviewInput(
inputId = "tree",
label = "Choose a city:",
choices = make_tree(cities, c("continent", "country", "city")),
choices = make_tree(
cities, c("continent", "country", "city")
),
multiple = FALSE,
prevent_unselect = TRUE
prevent_unselect = TRUE,
width = "100%"
),
verbatimTextOutput(outputId = "result")
)

server <- function(input, output, session) {
output$result <- renderPrint({
input$tree
})
}

if (interactive())
shinyApp(ui, server)
```



`treecheckInput()` allow to check a value (or several) in a hierarchical structure :

![](man/figures/example-treecheck.png)

Code for this example:

```r
library(shiny)
library(shinytreeview)

data("cities")

ui <- fluidPage(
tags$h3("treeviewInput cities example"),
treecheckInput(
inputId = "tree",
label = "Choose a city:",
choices = make_tree(
cities, c("continent", "country", "city")
),
width = "100%"
),
verbatimTextOutput(outputId = "result")
)
Expand All @@ -44,6 +88,7 @@ server <- function(input, output, session) {
})
}

shinyApp(ui, server)
if (interactive())
shinyApp(ui, server)
```

26 changes: 26 additions & 0 deletions examples/treecheck.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

library(shiny)
library(shinytreeview)

data("cities")

ui <- fluidPage(
tags$h3("treeviewInput cities example"),
treecheckInput(
inputId = "tree",
label = "Choose a city:",
choices = make_tree(
cities, c("continent", "country", "city")
)
),
verbatimTextOutput(outputId = "result")
)

server <- function(input, output, session) {
output$result <- renderPrint({
input$tree
})
}

if (interactive())
shinyApp(ui, server)
112 changes: 112 additions & 0 deletions inst/assets/bootstrap-treeview/treeview-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,115 @@ Shiny.inputBindings.register(
"shinytreeview.treeviewInput"
);



var treecheckInputBinding = new Shiny.InputBinding();
$.extend(treecheckInputBinding, {
find: function(scope) {
return scope.querySelectorAll(".treecheck-input");
},
getId: function(el) {
return el.id;
},
getType: function(el) {
if ($(el).attr("data-return") == "name") {
return "treeview.name";
} else if ($(el).attr("data-return") == "id") {
return "treeview.id";
} else {
return "treeview.all";
}
},
getValue: function(el) {
var tree = $(el).data("treeview");
try {
return tree.getChecked();
} catch (error) {
return null;
}
},
setValue: function(el, value) {},
subscribe: function(el, callback) {
$(el).on("nodeChecked", function(event, data) {
callback();
});
$(el).on("nodeUnchecked", function(event, data) {
callback();
});
},
unsubscribe: function(el) {
$(el).off(".treecheckInputBinding");
},
receiveMessage: function(el, data) {
var tree = $(el).data("treeview");
if (data.hasOwnProperty("search")) {
if (data.search.collapse) {
tree.collapseAll();
}
if (data.search.pattern.length > 1) {
data.search.pattern.map(function(pattern) {
tree.search(pattern, data.search.options);
});
} else {
tree.search(data.search.pattern, data.search.options);
}
}
if (data.hasOwnProperty("expand")) {
if (data.expand.hasOwnProperty("nodeId")) {
var expandedNode = tree.findNodes(
"^" + data.expand.nodeId + "$",
"nodeId"
);
tree.expandNode(expandedNode, data.expand.options);
} else {
tree.expandAll(data.expand.options);
}
}
if (data.hasOwnProperty("collapse")) {
if (data.collapse.hasOwnProperty("nodeId")) {
var collapsedNode = tree.findNodes(
"^" + data.collapse.nodeId + "$",
"nodeId"
);
tree.collapseNode(collapsedNode);
} else {
tree.collapseAll();
}
}
},
getState: function(el) {},
initialize: function(el) {
var element = document.getElementById(el.id);

var options = element.querySelector('script[data-for="' + el.id + '"]');
options = JSON.parse(options.innerHTML);

$(el).treeview(options.config);
var tree = $(el).treeview(true);
$(el).on("rendered ", function(event, data) {
if (options.hasOwnProperty("selected")) {
var selected = tree.search(options.selected, {
ignoreCase: false,
exactMatch: true,
revealResults: false
});
tree.checkNode(selected);
tree.search("", {
ignoreCase: false,
exactMatch: true,
revealResults: false
});
}
var nodes = tree.getNodes().map(function(o) {
return { text: o.text, nodeId: o.nodeId, parentId: o.parentId };
});
Shiny.onInputChange(el.id + "_nodes:treeview.nodes", nodes);
});
}
});
Shiny.inputBindings.register(
treecheckInputBinding,
"shinytreeview.treecheckInput"
);


Binary file removed man/figures/example-cities.png
Binary file not shown.
Binary file added man/figures/example-treecheck.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added man/figures/example-treeview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions man/treecheckInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/treeviewInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 63219d9

Please sign in to comment.