I am writing a Shiny application that will query a database a few times. The queries may take some time, so I am using actionButton to allow the user to control when they are started.
The general flow of the application is:
User loads page, pushes button to load in available choices from the database.
User selects a row from the available choices, and then kicks off a larger query that will take longer.
When the query is done, the user will get nice visualizations and other such things.
I know that you can allow the user to select rows from a DataTable using the selection option, and I am currently using the development build so that single-selection can be enabled. My problem is figuring out how to hide certain conditional panels until the user has made a choice. As far as I can tell, the value of the choice is stored in input$[data frame name]_rows_selected. But, until the values are selected, this value is either NULL, or does not exist.
I cannot figure out how to pass to the condition argument of conditionalPanel() a condition which reflects the internal R logic. I've written a minimal working example below which shows the behavior to which I'm referring.
library(shiny)
library(DT)
# Create sample data
df_sample_data <- data.frame(name = c("John Smith","Jane Cochran","Belle Ralston","Quincy Darcelio"),
color = c("Red","Blue","Red","Green"),
age = c(25,52,31,29))
ui <-
fluidPage(
titlePanel("The Title!"),
sidebarPanel(
h1("Load Data"),
actionButton("load_data","Load Data"),
br(),
conditionalPanel(
h1("Do Thing"),
actionButton("do_thing","Do Thing"),
condition = "input.df_data_rows_selected !== undefined")
),
mainPanel(
dataTableOutput("df_data"),
conditionalPanel(
tableOutput("row_selected"),
condition = "input.df_data_rows_selected !== undefined")
)
)
server <-
function(input, output) {
# This function loads the data (in reality it is a server operation)
uFunc_ReactiveDataLoad <- eventReactive(eventExpr = input$load_data,valueExpr = {
df_data <- df_sample_data
return(list(display_table = datatable(data = df_data[c("name","age")],
options = list(dom = "tip"),
filter = "top",
selection = "single",
colnames = c("Person Name" = "name",
"Person Age" = "age")),
data_table = df_data))
})
output$df_data <- renderDataTable(expr = uFunc_ReactiveDataLoad()$display_table)
output$row_selected <- renderTable(expr = uFunc_ReactiveDataLoad()$data_table[input$df_data_rows_selected,])
}
shinyApp(ui = ui, server = server)
In the current setup, which uses input.df_data_rows_selected !== undefined, the panels are hidden until the data is loaded using the first actionButton. But, I need them to remain hidden unless the user has selected a row. I have tried other things such as:
input.df_data_rows_selected !== null
input.df_data_rows_selected !== 'null'
input.df_data_rows_selected !== ''
input.df_data_rows_selected !== 'NULL'
...and so on, but I have had no luck. How does the NULL value in R get represented in the JavaScript used for the condition argument to conditionalPanel()?
condition = "(typeof input.df_data_rows_selected !== 'undefined' && input.df_data_rows_selected.length > 0)" for both entries seems to work.
condition = "(typeof input.df_data_rows_selected === null")
If anyone is stumbling upon this issue a few years later...
Related
For my shiny app, I am using a pickerInput. When "deselect all" is selected, the output of my datatable shows an error. I am looking to print a string that says " Make sure to select an option!" when deselect all is selected. Do I have to use observeEvent, or can I use an if statement in my server code?
Here is an example of the pickerInput code:
pickerInput("type", "Select Option", choices = c("a","b","c", "d"), selected = c("a","b","c","d"), options = list('actions-box' = TRUE), multiple = T)
Here is an example of the server code:
output$one<- DT::renderDT({DT::datatable(caption = "table", options = list(pageLength = 50),tab1<- rbind(red, blue,green, yellow)%>% filter(num> .450, letter == input$type))
If error you can hide the datatable or return NULL and display a message via shinyalert.
So, I have a checkboxgroupButtons where the user can select one or more options
checkboxGroupButtons("id","select options",
choices = c( "A","B","C" )
,selected = "A"
, checkIcon = list(yes = icon("ok", lib = "glyphicon"))
, direction = "vertical"
)
Then I want a conditional panel, but I want it such that the action depends if user selects "A" or (inclusive) "B". Already tried &&. Tried || but it doesn't logically accepts the inclusion. also tried
input.id.values, but it triggers even if I select "A" and "C".
conditionalPanel( condition = "input.id=='A' || input.id=='B'" , helpText("something") )
How can I set a condition is : "input.id" contained in the list ("A","B")
Thank you
Not sure, but could you try
input.id.every(i => i === 'A' || i === 'B')
Or, if the browser you use does not support =>:
input.id.every(function(i){return i==='A' || i==='B';})
Okay so I have a table like shown...
I want to use PowerBI to create a new column called 'First_Interaction' where it will say 'True' if this was the user's earliest entry for that day. Any entry that came in after the first entry will be set to "False".
This is what I want the column to be like...
Use the following DAX formula to create a column:
First_Interaction =
VAR __userName = 'Table'[UserName]
VAR __minDate = CALCULATE( MIN( 'Table'[Datetime] ), FILTER( 'Table', 'Table'[UserName] = __userName ) )
Return IF( 'Table'[Datetime] = __minDate, "TRUE", "FALSE" )
Power BI dosnt support less than second so your DateTime Column must be a Text value. Take that on consideration for future transformation.
I am trying to use a BigQuery query to populate plots in Shiny. The query includes input values from the ui using selectInput. If the user selects a value that exists in the DB, such as year is 2014, the query works correctly, however, I would like the user to also be able to select "All." "All" should be a selection of all values, however, I am not sure how to express that in the query using selectInput.
server.r
data1 <- eventReactive(input$do_sql, {
bqr_auth(token = NULL, new_user = FALSE, verbose = FALSE)
query = paste('select month, event, partner_name, sum(f0_) from [dataset.table] where year =',input$year1,' and partner_name = \"',input$partner_name,'\"
GROUP by 1,2,3
ORDER by 1 asc
LIMIT 10000', sep="")
bqr_query(projectId, datasetId, query, maxResults =2000)
})
ui.r
(
selectInput("year1",
"Year:",
c("All",2014,2015
))
),
(
selectInput("partner_name",
"Partner:",
c("All",
unique(as.character(data5$partner_name))))
You should slightly change the query you are constructing
So, currently you have
SELECT month, event, partner_name, SUM(f0_)
FROM [dataset.table]
WHERE year = selected_year
AND partner_name = "selected_partner_name"
GROUP BY 1,2,3
ORDER BY 1 ASC
LIMIT 10000
with respectively:
selected_year --> input$year1
selected_partner_name --> input$partner_name
Instead, you should construct below query
SELECT month, event, partner_name, SUM(f0_)
FROM [dataset.table]
WHERE (year = selected_year OR "selected_year" = "All")
AND (partner_name = "selected_partner_name" OR "selected_partner_name" = "All")
GROUP BY 1,2,3
ORDER BY 1 ASC
LIMIT 10000
I am not shiny user at all - so excuse my syntax - below is just my
guess with regard of implementing above suggestion
query = paste('SELECT month, event, partner_name, sum(f0_)
FROM [dataset.table]
WHERE (year =',input$year1,' OR "All" ="',input$year1,'")
AND (partner_name = \"',input$partner_name,'\" OR "All" = \"',input$partner_name,'\")
GROUP by 1,2,3
ORDER by 1 asc
LIMIT 10000', sep="")
Mikhail's solution worked perfectly for character variables, but numerics didn't work correctly. I decided to use a character date range instead of the year numeric I originally used. Thanks.
At one point in my code, I have:
output$summaryTable <- renderTable({
createData()$summary
},align='lll')
However, createData()$summary[2,1] and createData()$summary[2,2] are both very long and thus the table has a very wide scroller. What's the best way to fix it so that it wraps?
Thanks!
if Your question is still valid, here is one solution for Your problem:
output$summaryTable <- DT::renderDataTable({
datatable(createData()$summary,
options = list(columnDefs = list(list(targets = 1,render = JS("function(data, type, row, meta) {","return type === 'display' && data.length > 10 ?","'<span title=\"' + data + '\">' + data.substr(0, 8) + '...</span>' : data;","}")))))})
if the row has more then 10 characters (data.length > 10), dataTable is going to display only 8 (data.substr(0, 8)) of them:
rowwithlongname -> rowwithl...
when you get mouse over the row then the full name is displayed
I cannot replicate your table but it seems that you will have to add some css to format the table the way you want.
You would probably have to add in your ui.r something like:
tags$head(
tags$style(
HTML("#summaryTable table tr td {word-wrap: break-word}")
)
)
I could test for validity of my answer if I could replicate your table.