In the shiny
app below I have already developed a method in which the user types a string in the first textInput()
then he clicks "Begin search"
in the 1st actionButton()
and subsets its dataset based on this string. Then he can click Reset
to reset the dataset.
Now I want to add a 2nd search method in which the user will be able to select also a column, then type a string in the 2nd textInput()
, click Begin Search
on the 2nd actionButton()
and subset the whole dataset based on this column, then clicks Reset
to reset.
#Load libraries needed
library(shiny)
library(shinydashboard)
library(DT)
library(shinyWidgets)
library(purrr)
library(dplyr)
#load ldataset
data_test_1_ <-structure(list(Dimension = c("environmental", "environmental",
"environmental", "environmental", "environmental", "environmental",
"environmental", "environmental", "environmental", "environmental"
), Component = c("air quality", "air quality", "air quality",
"water quality", "environmental hazards", "environmental hazards",
"environmental hazards", "environmental hazards", "environmental hazards",
"physical safety"), Indicator = c("outdoor", "outdoor", "indoor",
NA, "Hazardous waste", "Heavy metals", "Pesticides", "Climate extremes",
"Noise", "Traffic")), row.names = c(NA, 10L), class = c("tbl_df",
"tbl", "data.frame"))
#Dashboard
ui <- dashboardPage(
dashboardHeader(title = "Dataset Inventory"),
#left sidebar part
dashboardSidebar(
#the search box
textInput("tt","Search whole dataset",""),
#the button that triggers search
actionButton("ser","Begin search"),
tags$hr(),
#select column to search
uiOutput("column"),
pickerInput(
inputId = "p3",
label = "Select Column to search",
choices = colnames(data_test_1_),
selected = colnames(data_test_1_[1]),
multiple = F,
options = list(`actions-box` = TRUE)
),
#the search box for column
textInput("tt2","Search column",""),
#the button that triggers search column
actionButton("ser2","Begin search"),
tags$hr(),
#the button that triggers reset
actionButton("res","Reset")
),
#the main body part
dashboardBody(
#the table
div(DT::dataTableOutput("table"), style = "font-size: 80%; width: 100%")
)
)
#the server part
server <- function(input, output,session) {
#a counter that is used for search and reseting
cntrl <- reactiveValues(n = 0)
#the reacive calling of the dynamic datatable
output$table <- renderDataTable({
datatable(data_test_1_)
})
#the observer that activates the search button and searches all the felds of the dataset
observeEvent(input$ser,
{
cntrl$n <- cntrl$n 1
output$table<-renderDataTable({
datatable(d_new <- data_test_1_[apply(data_test_1_, 1, function(x) any(grepl(isolate(input$tt), x))), ],escape = F
)
})
}
)
#the observer that resets the dataset before the searching
observeEvent(input$res,
{
cntrl$n <- 0
updateTextInput(session, "tt", value = "")
output$table <- renderDataTable(datatable(data_test_1_,
escape = F
))
})
}
shinyApp(ui, server)
CodePudding user response:
Is there a specific reason why you want to include searching functionality in the sidebar rather than directly in DT?
The quickest way to filter in DT is by adding the filter
parameter. In any event here's one possible solution.
Rather than creating a new datatable every time a search is made. I've added a reactiveValue
called data_test
that contains the data. Then in each observeEvent all you need to do is modify data_test$d
and renderDataTable will render the data that is pointed to that reactiveValue. I also added filter = "top"
in case you haven't seen that before.
Lastly, in the second observeEvent where you want to search by column. I've set input$p3
to the variable col
. Then wrapped col with the bang bang operator !!
and rlang::sym
.
#the server part
server <- function(input, output,session) {
#a counter that is used for search and reseting
cntrl <- reactiveValues(n = 0)
data_test = reactiveValues(
d = data_test_1_
)
#the reacive calling of the dynamic datatable
output$table <- renderDataTable({
datatable(data_test$d, filter = "top")
})
#the observer that activates the search button and searches all the felds of the dataset
observeEvent(input$ser, {
cntrl$n <- cntrl$n 1
data_test$d = data_test_1_[apply(data_test_1_, 1, function(x) any(grepl(isolate(input$tt), x))), ]
})
observeEvent(input$ser2, {
col = input$p3
data_test$d = data_test_1_ %>%
filter(grepl(isolate(input$tt2), !!sym(col)))
})
#the observer that resets the dataset before the searching
observeEvent(input$res, {
cntrl$n <- 0
updateTextInput(session, "tt", value = "")
data_test$d = data_test_1_ # reset to original data
})
}
shinyApp(ui, server)