I'm trying to display a csv file and create checkboxes to allow filtering. The app runs without any errors but I get a blank box where the checkboxes would be. How can I get the checkboxes to show up?
library(shiny)
library(DT)
df <- read.csv("new_and_deactivated_accounts.csv", header = TRUE)
ui <- fluidPage(
# Application title
titlePanel("GIS Workload"),
sidebarLayout(
sidebarPanel(
conditionalPanel(
'input.dataset === "df"',
checkboxGroupInput("checkbox", "Select something",
names(df), selected = names(df))
)
),
mainPanel(
tabsetPanel(
id='df',
tabPanel(DT::dataTableOutput("mytable1"))
)
)
)
)
server <- function(input, output) {
output$mytable1 <- DT::renderDataTable({
DT::datatable(df[, input$checkbox, drop = FALSE])
})
}
# Run the application
shinyApp(ui, server)
Here's a portion of what displays, where the checkboxes should be are empty and because it's a semi-private, I opted not to show the data, but included the headers.
They are there, just hidden as you are using a conditional panel and the condition isn't being met.
You can remove this part, or ensure the conditions are being met:
conditionalPanel('input.dataset === "df"',
Here is your full code with that line removed, and mtcars used instead of your data:
library(shiny)
library(DT)
df <- mtcars
ui <- fluidPage(
# Application title
titlePanel("GIS Workload"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("checkbox", "Select something",
names(df), selected = names(df))
),
mainPanel(
tabsetPanel(
id='df',
tabPanel(DT::dataTableOutput("mytable1"))
)
)
)
)
server <- function(input, output) {
output$mytable1 <- DT::renderDataTable({
DT::datatable(df[, input$checkbox, drop = FALSE])
})
}
# Run the application
shinyApp(ui, server)
Here is some generic Shiny code that should help you.
library(shiny)
library(DT)
mymtcars <- mtcars
mymtcars[["Select"]] <- paste0('<input type="checkbox" name="row_selected" value=',1:nrow(mymtcars),' checked>')
mymtcars[["_id"]] <- paste0("row_", seq(nrow(mymtcars)))
callback <- c(
sprintf("table.on('click', 'td:nth-child(%d)', function(){",
which(names(mymtcars) == "Select")),
" var checkbox = $(this).children()[0];",
" var $row = $(this).closest('tr');",
" if(checkbox.checked){",
" $row.removeClass('excluded');",
" }else{",
" $row.addClass('excluded');",
" }",
" var excludedRows = [];",
" table.$('tr').each(function(i, row){",
" if($(this).hasClass('excluded')){",
" excludedRows.push(parseInt($(row).attr('id').split('_')[1]));",
" }",
" });",
" Shiny.setInputValue('excludedRows', excludedRows);",
"});"
)
ui = fluidPage(
verbatimTextOutput("excludedRows"),
DTOutput('myDT')
)
server = function(input, output) {
output$myDT <- renderDT({
datatable(
mymtcars, selection = "multiple",
options = list(pageLength = 5,
lengthChange = FALSE,
rowId = JS(sprintf("function(data){return data[%d];}",
ncol(mymtcars)-1)),
columnDefs = list( # hide the '_id' column
list(visible = FALSE, targets = ncol(mymtcars)-1)
)
),
rownames = FALSE,
escape = FALSE,
callback = JS(callback)
)
}, server = FALSE)
output$excludedRows <- renderPrint({
input[["excludedRows"]]
})
}
shinyApp(ui,server, options = list(launch.browser = TRUE))
Related
I am new to Rshiny and practising how to use reactive values, reactive expressions and selectizeInput. I would like to have all brands printed at once after pressing the button without the sentence "The brands selected are as follows: " to be printed multiple times:
here is my code:
ui <- fluidPage(
titlePanel("This is a Test"),
sidebarLayout(
sidebarPanel(
selectizeInput('brand', label = 'Car brand',
multiple = T, choices = mtcars %>% rownames(),
selected = NULL, width = '100%',
options = list('plugins' = list('remove_button')))
),
mainPanel(
actionButton("show_brands", "Show brands"),
textOutput("brands")
)
)
)
server <- function(input, output, session) {
values <- reactiveValues(
brandname = NULL,
mpgdata = NULL
)
output$brands <- renderText({
allbrands <- values$brandname()
paste("The brands seleted are as follows: ", allbrands)
})
values$brandname <- eventReactive(input$show_brands, {
input$brand
})
}
shinyApp(ui, server)
and here is the output after selecting three of the brands:
We can wrap input$brand in another paste() call:
library(shiny)
ui <- fluidPage(titlePanel("This is a Test"),
sidebarLayout(
sidebarPanel(
selectizeInput(
'brand',
label = 'Car brand',
multiple = TRUE,
choices = rownames(mtcars),
selected = NULL,
width = '100%',
options = list('plugins' = list('remove_button'))
)
),
mainPanel(
actionButton("show_brands", "Show brands"),
textOutput("brands")
)
))
server <- function(input, output, session) {
output$brands <- renderText({
paste("The brands seleted are as follows: ", paste(input$brand, collapse = ", "))
}) |> bindEvent(input$show_brands)
}
shinyApp(ui, server)
PS: There is no need to use reactiveValues
Let's say that I have a shiny app containing a datatable.
library(shiny)
library(tidyverse)
library(datasets)
library(DT)
data <- as.data.frame(USArrests)
#data<- cbind(state = rownames(data), data)
ui <- fluidPage(
dataTableOutput("preview")
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$preview<- renderDataTable(
datatable(data, options = list(searching = T, pageLength = 10, lengthMenu = c(5,10,15, 20), scrollY = "600px", scrollX = T ))
)
}
# Run the application
shinyApp(ui = ui, server = server)
I would like to be able to save what page of the table a user is on in a variable called x.
Would there be any way to go about doing this? Any help is greatly appreciated!
library(shiny)
library(DT)
data <- USArrests
callback <- c(
"Shiny.setInputValue('pageNumber', 1);",
"table.on('init.dt', function(){",
" var pageInfo = table.page.info();",
" Shiny.setInputValue('numberOfPages', pageInfo.pages);",
"});",
"table.on('page.dt', function(){",
" var pageInfo = table.page.info();",
" Shiny.setInputValue('pageNumber', pageInfo.page + 1);",
" Shiny.setInputValue('numberOfPages', pageInfo.pages);",
"});",
"table.on('length.dt', function(){",
" var pageInfo = table.page.info();",
" Shiny.setInputValue('pageNumber', pageInfo.page + 1);",
" Shiny.setInputValue('numberOfPages', pageInfo.pages);",
"});"
)
ui <- fluidPage(
br(),
wellPanel(
textOutput("displayPageNumber")
),
br(),
DTOutput("preview")
)
server <- function(input, output, session){
output[["preview"]] <- renderDT(
datatable(
data,
callback = JS(callback),
options = list(
searching = TRUE,
pageLength = 5,
lengthMenu = c(5, 10, 15, 20),
#scrollY = "600px",
scrollX = TRUE)
)
)
output[["displayPageNumber"]] <- renderText({
paste(
sprintf("You are currenly viewing page %s.", input[["pageNumber"]]),
sprintf("There are %s pages in the table.", input[["numberOfPages"]])
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
I have the shiny app below in which I click on datatable row and display its index next to it. Is it possible to press the Next button and display the index of the next row? The table's next row will be highlighted accordingly everytime as well.
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
title = 'Select Table Rows',
h1('A Server-side Table'),
fluidRow(
column(9, DT::dataTableOutput('x3')),
column(3, verbatimTextOutput('x4')),
actionButton("next","Next row")
)
),
server = function(input, output, session) {
# server-side processing
mtcars2 = mtcars[, 1:8]
output$x3 = DT::renderDataTable({datatable(selection = list(target = "row", mode = "single"),mtcars2 )})
# print the selected indices
output$x4 = renderPrint({
s = input$x3_rows_selected
if (length(s)) {
cat('These rows were selected:\n\n')
cat(s, sep = ', ')
}
})
})
library(shiny)
library(DT)
dat <- iris[1:6,]
callback <- JS(
"$('#btn-next').prop('disabled', true);",
"var selected_row = null;",
"table.on('select', function( e, dt, type, indexes ) {",
" $('#btn-next').prop('disabled', false);",
" selected_row = indexes[0];",
"});",
"table.on('deselect', function( e, dt, type, indexes ) {",
" $('#btn-next').prop('disabled', true);",
"});",
"var nrows = table.rows().count();",
"$('#btn-next').on('click', function() {",
" var next_row = selected_row + 1 < nrows ? selected_row + 1 : 0;",
" table.row(next_row).select();",
"});"
)
ui <- fluidPage(
br(),
DTOutput("dtable"),
br(),
splitLayout(
textOutput("selectedRow"),
actionButton("btn-next", "select next row"),
cellWidths = "150px"
)
)
server <- function(input, output, session) {
output[["dtable"]] <- renderDT({
datatable(
dat,
extensions = "Select",
selection = "none",
callback = callback,
options = list(
columnDefs = list(
list(className = "dt-center", targets = "_all")
),
select = list(style = "single")
)
)
}, server = FALSE)
output[["selectedRow"]] <- renderText({
i <- input[["dtable_rows_selected"]]
paste0(
"Selected row: ",
ifelse(is.null(i), "none", i)
)
})
}
shinyApp(ui, server)
I have included editable table in my shiny app I developed in my organization. Use this simple example to illustrate the issue. This is an extension of this question
In this app, after I edit any cell, the download button just disappear. Does anyone know why that happens? Thanks a lot in advance.
library(shiny)
library(DT)
library(dplyr)
# UI
ui = fluidPage(
selectInput("nrows",
"select n entries",
choices = 100:150,
selected = 100,
multiple = FALSE),
downloadButton("download1", "Download iris as csv"),
DTOutput('tbl'),
checkboxGroupInput(
'datacols',
label='Select Columns:',
choices= c('Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Species'),
selected = c('Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Species'),
inline=TRUE)
)
# SERVER
server = function(input, output) {
dat = reactiveValues()
observe ({
dat$dat = iris[1:input$nrows, ]
})
# render DT
output$tbl = renderDT({
datatable(dat$dat,
editable = "cell",
callback = JS(
"$('div.dwnld').append($('#download1'));",
"var checkboxes = $('input[name=datacols]');",
"checkboxes.each(function(index,value){",
" var column = table.column(index+1);",
" $(this).on('click', function(){",
" if($(this).prop('checked')){",
" column.visible(true);",
" }else{",
" column.visible(false);",
" }",
" });",
"});"
),
extensions = "Buttons",
options = list(
dom = 'B<"dwnld">frtip',
buttons = list("copy")
)
)
})
observeEvent(input[["tbl_cell_edit"]], {
cellinfo <- input[["tbl_cell_edit"]]
dat$dat <<- editData(dat$dat, cellinfo, "tbl")
})
output$download1 <- downloadHandler(
filename = function() {
paste("data_", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(dat$dat %>% select(one_of(input$datacols)), file)
}
)
}
shinyApp(ui, server)
I have a shiny app in which I have a table with 10 rows. What I want to achieve is to download a .txt file with a line of 0 and 1 based on the simple logic-if I choose the row I get 1 and if not I get O-. An example of all the rows selected would be:
#ui.r
library(shiny)
library(DT)
library(tidyverse)
navbarPage(
"Application",
tabPanel("General",
sidebarLayout(
sidebarPanel(
downloadButton("downloadData2", "Download")
),
mainPanel(
DT::dataTableOutput("hot3")
)
)))
#server.r
server <- function(input, output,session) {
hott<-reactive({
if(is.null(input$hot5_rows_selected)|| is.na(input$hot5_rows_selected)){
paste("0",collapse = " ")
}
else{
paste("1",collapse = " ")
}
})
output$downloadData2 <- downloadHandler(
filename = function(){
paste(input$file, ".txt", sep = "")
},
content = function(file) {
writeLines(paste(hott()
), file)
}
)
rt5<-reactive({
DF=data.frame(
Id= 1:10,
stringsAsFactors = FALSE
)
})
output$hot3 <-DT::renderDataTable(
rt5()%>%
rowid_to_column("Row") %>%
mutate(Row = ""),
rownames = FALSE,
extensions = "Select",
options = list(
columnDefs = list(list(className = "select-checkbox", targets = 0, orderable = FALSE)),
select = list(style = "multi", selector = "td:first-child")
)
)
}
The only solution I can see is:
library(shiny)
library(DT)
dat <- data.frame(X = LETTERS[1:10])
ui <- fluidPage(DTOutput("dt"))
server <- function(input, output){
rowSelected <- reactive({
x <- numeric(nrow(dat))
x[input$dt_rows_selected] <- 1
x
})
output$dt <- renderDT(datatable(cbind(id=rowSelected(), dat),
selection = list(mode = "multiple",
selected = (1:nrow(dat))[as.logical(rowSelected())],
target = "row")))
}
shinyApp(ui, server)