Saturday, April 27, 2024
No menu items!
HomeData Analytics and VisualizationShiny : Search Bar with Suggestions

Shiny : Search Bar with Suggestions

Search Bar is a common feature available in any popular website or app. Most of the websites show suggestions in real time as soon as user starts typing in the search bar. It improves user experience significantly and user is able to find the content he/she wants to see in the website. Recently it’s become common ask to have this similar functionality in shiny dashboard. In shiny there are many workarounds available for search bar but no straightforward method to implement it.

Search Bar (Single Selection)

Incase you want user not to select more than one value. It is to prevent multiple selection from dropdown. You can use multiple = FALSE for selection of single item. Option maxItems = ‘1’ removes dropdown icon which is by default shown in the dropdown. To make selectizeInput behave like a search bar, we have used javascript mentioned in onDropdownOpen and onType options.

In the choices argument we have used concatenation of two random letters of alphabet. For example `AB`. Since it is random, it’s not necessary `AB` exists in the dropdown 🙁 You can remove the selected value via backspace.

library(shiny)

ui title = “Search Bar”,
fluidRow(
selectizeInput(
inputId = “searchme”,
label = “Search Bar”,
multiple = FALSE,
choices = c(“Search Bar” = “”, paste0(LETTERS,sample(LETTERS, 26))),
options = list(
create = FALSE,
placeholder = “Search Me”,
maxItems = ‘1’,
onDropdownOpen = I(“function($dropdown) {if (!this.lastQuery.length) {this.close(); this.settings.openOnFocus = false;}}”),
onType = I(“function (str) {if (str === “”) {this.close();}}”)
)
))
)

server
# Show Selected Value in Console
observe({
print(input$searchme)
})

}

shinyApp(ui, server)

Search Bar (Multiple Selection)

In this section we are showing how to select more than one value from dropdown. To make multiple section working, you need to set multiple = TRUE along with the javascript mentioned in onItemAdd option.

library(shiny)

ui title = “Search Bar”,
fluidRow(
selectizeInput(
inputId = “searchme”,
label = “Search Bar”,
multiple = TRUE,
choices = paste0(LETTERS,sample(LETTERS, 26)),
options = list(
create = FALSE,
placeholder = “Search Me”,
onDropdownOpen = I(“function($dropdown) {if (!this.lastQuery.length) {this.close(); this.settings.openOnFocus = false;}}”),
onType = I(“function (str) {if (str === “”) {this.close();}}”),
onItemAdd = I(“function() {this.close();}”)
)
))
)

server
# Show Selected Value in Console
observe({
print(input$searchme)
})

}

shinyApp(ui, server)

Search Bar using Shiny Widgets

shinyWidgets is a great package for widgets implemented for shiny. It offers several controls for interactivity. It has searchInput() widget for search bar but that does not allow suggestions as user enters text. We can customise pickerInput widget but it has limitation of not allowing to remove text via backspace but it shows Clear Text button on top of dropdown to clear selection.

This implementation is a bit messy as compared to above selectizeInput. It requires changes via javascript and CSS. `live-search` = TRUE allows live suggestion in dropdown box.

library(shiny)
library(shinyWidgets)

ui title = “Search Bar”,
fluidRow(
tags$script(HTML(
“var CONTROL_INTERVAL = setInterval(function(){
if($(‘#searchme’).length > 0 ){
$(‘#searchme’).on(‘show.bs.select’, function(){
var input = $(‘.bootstrap-select:has(select[id=”searchme”]) .bs-searchbox > input’);
var opts = $(this).parent().find(‘div[role=”listbox”] ul li’);
var opts0 = $(this).parent().find(‘div[role=”listbox”]’);
opts.hide();
opts0.hide();

input.on(‘input’, function(e){
if ($(this).val() !== “”) {opts.show(); opts0.show();}
else {opts.hide(); opts0.hide();}
});
});

clearInterval(CONTROL_INTERVAL);
}}, 200);

)),

tags$style(HTML(“.bs-select-all {display: none;}
.bs-deselect-all {width: 100% !important;}”)),

pickerInput(
inputId = “searchme”,
label = “Search Bar”,
choices = paste0(LETTERS,sample(LETTERS, 26)),
multiple = TRUE,
options = pickerOptions(title = “Search Me”,
`live-search` = TRUE,
actionsBox = TRUE,
deselectAllText = “Clear Search”)
)
))

server
# Show Selected Value in Console
observe({
print(input$searchme)
})

}

shinyApp(ui, server)

Read MoreListenData

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments