Reputation: 1718
I am using the jQuery plugin ComboTree to display a tree-like select menu in my shiny app.
I am having trouble retrieving those values (e.g. c("Item 2", "Item 2-1")
) to use in some output. So the issue here is to retrieve whatever values are selected from the select menu ($("example").val();
).
ui.r
:
ui <- function(){
fluidPage(
tags$head(
tags$script(src = "comboTreePlugin.js"),
tags$script(src = "icontains.js"),
tags$link(rel = "stylesheet", type = "text/css", href = "comboTreeStyle.css")
),
includeScript("myData.json"),
# layouy content ----
sidebarLayout(
sidebarPanel(width = 3,
tags$input(type = "text", id = "example", placeholder = "Select"),
uiOutput("comboTreeMenu")
),
mainPanel(width = 9)
)
)
}
server.r
:
server <- function(input, output, session){
output$comboTreeMenu <- renderUI({
includeScript("www/example.js")
})
# want to do some manipulation with the resulting selections from the
# combo tree. Something along the lines of:
# selections <- eventReactive(input$click, {
# return(input$comboTreeSelections)
# })
}
example.js
:
comboTree1 = $('#example').comboTree({
source: myData,
isMultiple: true
});
myData.json
:
var myData = [
{
id: 0,
title: 'Item 1 '
}, {
id: 1,
title: 'Item 2',
subs: [
{
id: 10,
title: 'Item 2-1'
}, {
id: 11,
title: 'Item 2-2'
}, {
id: 12,
title: 'Item 2-3'
}
]
}, {
id: 2,
title: 'Item 3'
}
];
I've tried to add an extra piece of js script like so:
selectedValues = $("#example").val();
Shiny.onInputChange("comboTreeSelections", selectedValues);
Thank you!
Upvotes: 2
Views: 1165
Reputation: 9809
This is just a quick fix, as I don't really recommend using a pure jQuery plugin, since you will have to write all the interaction between combotree and Shiny yourself. But when you're only interested in the actual selected items, you could do this:
In comboTreePlugin.js
change the function at line 129 to:
this._elemItemsTitle.on('click', function(e){
e.stopPropagation();
if (_this.options.isMultiple)
_this.multiItemClick(this);
else
_this.singleItemClick(this);
var selItem = comboTree1.getSelectedItemsTitle();
Shiny.onInputChange('selTitle', selItem);
});
This example will only work, when you really click on an item, it wont fire when you select an item by hitting Enter. You would have to copy/paste the last 2 lines above in the keydown
-event handler (code 13).
Then you can access the variable selTitle
with input$selTitle
in Shiny.
Here's a small ShinyApp which prints out the selected titles:
library(shiny)
ui <- {fluidPage(
tags$head(
tags$script(src = "comboTreePlugin.js"),
tags$script(src = "icontains.js"),
tags$link(rel = "stylesheet", type = "text/css", href = "comboTreeStyle.css")
),
includeScript("www/myData.json"),
sidebarLayout(
sidebarPanel(width = 3,
tags$input(type = "text", id = "example", placeholder = "Select"),
uiOutput("comboTreeMenu"),
verbatimTextOutput("selected")
),
mainPanel(width = 9)
)
)}
server <- function(input, output, session){
output$comboTreeMenu <- renderUI({
includeScript("www/example.js")
})
output$selected <- renderPrint({
req(input$selTitle)
print(input$selTitle)
})
}
shinyApp(ui, server)
Upvotes: 1
Reputation: 9809
I found another method, where you dont have to mess with the source code and just inject some javascript.
This will trigger a setInterval
function, when the dropdown is visible/openend and will re-run every 500ms.
library(shiny)
js <- HTML("
$(function() {
var selection = setInterval(function() {
if($('.comboTreeDropDownContainer').is(':visible')) {
var selItem = comboTree1.getSelectedItemsTitle();
Shiny.onInputChange('selTitle', selItem)
}
}, 500);
});
")
ui <- {fluidPage(
tags$head(
tags$script(src = "comboTreePlugin.js"),
tags$script(src = "icontains.js"),
tags$script(js),
tags$link(rel = "stylesheet", type = "text/css", href = "comboTreeStyle.css")
),
includeScript("www/myData.json"),
sidebarLayout(
sidebarPanel(width = 3,
tags$input(type = "text", id = "example", placeholder = "Select"),
uiOutput("comboTreeMenu"),
verbatimTextOutput("selected")
),
mainPanel(width = 9)
)
)}
server <- function(input, output, session){
output$comboTreeMenu <- renderUI({
includeScript("www/example.js")
})
output$selected <- renderPrint({
req(input$selTitle)
print(input$selTitle)
})
}
shinyApp(ui, server)
Upvotes: 1