Reputation: 8404
I have a shiny app in which there are two tables. As you can see the user uses the right datatable and the widgets there in order to display the results in the rhandsontable on the left. The app works as expected except that the fact every time I choose a different Test by the selectInput()
"Label" all the previous changes I have made are lost and the rhandsontable on the left "restarts". I used this in order to keep the modified names but I need to apply a similar logic to the whole app.
Logic of the app:
The user chooses one of the Tests by using the selectInput() "Label". This is the main operation and then he is able to modify its name, for example Test 1 to Test A. Then the user can add items in the Test by the numericInput() "Items in Test". These are the total items. As you will see the number of "Items in Test" is the same with 'Avail' column in hot3 table for the choosen Test. With "Select Items" he can choose specific items to be displayed in the hot5 table. Then the user can click on the hot5 table to select a specific item and the number of selected items (or rows) is displayed in the hot3 table under "Sel" column for this specific Test. The 'Items chosen' just displayes the number of Items selected in "Select Items". Note that every modification that happens to the table is not dependent on the other widgets. That means for example that it is not necessary to change a Label Name.
library(shiny)
library(DT)
library(rhandsontable)
library(tidyverse)
ui <- navbarPage(
"Application",
tabPanel("Booklets",
sidebarLayout(
sidebarPanel(
uiOutput("tex2"),
rHandsontableOutput("hot3")
),
mainPanel(
fluidRow(
wellPanel(
fluidRow(
column(4,
DT::dataTableOutput("hot5")
),
column(4,
fluidRow(
uiOutput("book3"),
uiOutput("book6")
),
fluidRow(
uiOutput("book1"),
uiOutput("book10"),
uiOutput("book11")
)
)
))
)
)
)
)
)
#server
server <- function(input, output, session) {
output$tex2<-renderUI({
numericInput("text2", "#tests", value = 1, min=1)
})
output$book1<-renderUI({
numericInput("bk1",
"Items in test",
value = 1,
min = 1)
})
output$book3<-renderUI({
selectInput("bk3",
"Label",
choices=(paste("Test",1:input$text2)))
})
output$book6<-renderUI({
textInput("bk6", "Change to",
value=NULL
)
})
output$book10<-renderUI({
selectizeInput(
"bk10", "Select Items", choices =1:10000,multiple =T,selected = 1,
options = list(maxItems = input$bk1))
})
output$book11<-renderUI({
textInput("bk11", "Items chosen",
value = nrow(rt5())
)
})
rt4<-reactive({
if(is.null(input$bk6)|input$bk6==""){
if(is.null(input$hot5_rows_selected)|| is.na(input$hot5_rows_selected)){
DF=data.frame(
Sel. = rep(TRUE, input$text2),
Test=paste(1:input$text2),
Label=paste("Test",1:input$text2),
Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
Sel =as.integer(rep.int(0,input$text2)),
stringsAsFactors = FALSE)
}
else{
DF=data.frame(
Sel. = rep(TRUE, input$text2),
Test=paste(1:input$text2),
Label=paste("Test",1:input$text2),
Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
Sel =as.integer(rep.int(0,input$text2)),
stringsAsFactors = FALSE)
}
for(i in 1 : input$text2){
if(DF[i,3]==input$bk3){
DF[i,4]<-input$bk1
DF[i,5]<-length(input$hot5_rows_selected)
}
else{
DF[i,4]<-1
}
}
DF
}
else{
if(is.null(input$hot5_rows_selected)|| is.na(input$hot5_rows_selected)){
DF=data.frame(
Sel. = rep(TRUE, input$text2),
Test=paste(1:input$text2),
Label=paste("Test",1:input$text2),
Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
Sel =as.integer(rep.int(0,input$text2)),
stringsAsFactors = FALSE)
DF[DF==input$bk3]<-input$bk6
DF
}
else{
DF=data.frame(
Sel. = rep(TRUE, input$text2),
Test=paste(1:input$text2),
Label=paste("Test",1:input$text2),
Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
Sel =as.integer(rep.int(0,input$text2)),
stringsAsFactors = FALSE)
DF[DF==input$bk3]<-input$bk6
DF
}
for(i in 1 : input$text2){
if(DF[i,3]==input$bk6){
DF[i,4]<-input$bk1
DF[i,5]<-length(input$hot5_rows_selected)
}
else{
DF[i,4]<-1
}
}
DF
}
})
rt55<-reactive({
DF=data.frame(
Id= input$bk10,
Label=paste("Item",input$bk10),
Pf=0,
stringsAsFactors = FALSE
)
})
rt5<-reactive({
DF=data.frame(
Id= input$bk10,
Label=paste("Item",input$bk10),
Pf=0,
stringsAsFactors = FALSE
)
cbind(id=rowSelected(), DF)
})
rowSelected <- reactive({
x <- numeric(nrow(rt55()))
x[input$hot5_rows_selected] <- 1
x
})
output$hot5 <- renderDT(datatable(rt5()[,-1],
selection = list(mode = "multiple",
selected = (1:nrow(rt5()[,-1]))[as.logical(rowSelected())],
target = "row"),rownames = F)
)
output$hot3 <-renderRHandsontable(
rhandsontable(rt4())
)
}
Upvotes: 0
Views: 250
Reputation: 1054
Made edits based on comments. I think the code works, but its fairly fragile and needs a fair degree of error handling. Resetting entriesafter submit is hit, for instance
library(shiny)
library(DT)
library(rhandsontable)
#library(tidyverse)
ui <- navbarPage(
"Application",
tabPanel("Booklets",
sidebarLayout(
sidebarPanel(
uiOutput("tex2"),
rHandsontableOutput("hot3")
),
mainPanel(
fluidRow(
wellPanel(
fluidRow(
column(4,
DT::dataTableOutput("hot5")
),
column(4,
fluidRow(
uiOutput("book3"),
uiOutput("book6")
),
fluidRow(
uiOutput("book1"),
uiOutput("book10"),
uiOutput("book11")
),
fluidRow(actionButton("submit","submit"))
)
))
)
)
)
)
)
#server
server <- function(input, output, session) {
rv<-reactiveValues()
output$tex2<-renderUI({
numericInput("text2", "#tests", value = 1, min=1)
})
output$book1<-renderUI({
numericInput("bk1",
"Items in test",
value = 1,
min = 1)
})
output$book3<-renderUI({
selectInput("bk3",
"Label",
choices=(paste("Test",1:input$text2)))
})
output$book6<-renderUI({
textInput("bk6", "Change to",
value=NULL
)
})
output$book10<-renderUI({
# changed from selectize
selectizeInput(
"bk10", "Select Items", choices =1:10000,multiple =T,selected = 1,
options = list(maxItems = input$bk1))#changed from
})
output$book11<-renderUI({
textInput("bk11", "Items chosen",
value = nrow(rt5())
)
})
#rt4<-reactive({
observe({
req(input$text2)
rv$rt4 = data.frame(
SNo = rep(TRUE, input$text2),
Test=paste(1:input$text2),
Label=paste("Test",1:input$text2),
Avail=1L,
Sel =as.integer(rep.int(0,input$text2)),
stringsAsFactors = FALSE)
})
observeEvent(input$submit,{
# rt4 <- reactive({
if (is.null( rv$rt4))
return(NULL)
if(!is.null(input$bk6) && input$bk6!=""){
rv$rt4[ rv$rt4$Label==input$bk3, "Avail"] <- input$bk1
rv$rt4[ rv$rt4$Label==(input$bk3), "Sel"] <- length(input$hot5_rows_selected)
rv$rt4[ rv$rt4$Label==input$bk3, "Label"] <- input$bk6
}
# if(!is.null(input$hot5_rows_selected) && input$hot5_rows_selected!=""){
#
# }
})
observeEvent(input$submit,{
updateSelectInput(session,"bk3","Label", choices=rv$rt4$Label)
}
)
rt55<-reactive({
DF=data.frame(
Id= input$bk10,
Label=paste("Item",input$bk10),
Pf=0,
stringsAsFactors = FALSE
)
})
rt5<-reactive({
DF=data.frame(
Id= input$bk10,
Label=paste("Item",input$bk10),
Pf=0,
stringsAsFactors = FALSE
)
cbind(id=rowSelected(), DF)
})
rowSelected <- reactive({
x <- numeric(nrow(rt55()))
x[input$hot5_rows_selected] <- 1
x
})
output$hot5 <- renderDT(datatable(rt5()[,-1],
selection = list(mode = "multiple",
selected = (1:nrow(rt5()[,-1]))[as.logical(rowSelected())],
target = "row"),rownames = F)
)
output$hot3 <-renderRHandsontable({
req(input$text2)
rhandsontable(rv$rt4)
})
}
shinyApp(ui,server)
Upvotes: 1