I am trying to make an xlsx sheet of customers orders of certain items. I created a shiny app to input each order in the form of a datatable row which is added to the table on click of "Add" Button. But I face a problem, each time I add a new order (row) an extra cell of row number is generated in all the previous ones like in the picture.
and all row cells are shifted to the right!!
This is my code:
library(shiny)
library(shinythemes)
library(readxl)
library(xlsx)
library(DT)
items <- read_excel("items.xlsx",col_names = F)
colnames(items) <- c("Items", "Euro", "Cost")
ui <- fluidPage(theme = shinytheme('journal'),
sidebarLayout(
sidebarPanel(
tags$img(height = 118, width = 160, src="logo.jpg"),
br(),br(),
textInput('name','Name'),
br(),
selectizeInput(inputId = "item",
label = "Item",
choices = c(items$Items),
options = list(
placeholder = '',
onInitialize = I('function() { this.setValue(""); }'))),
br(),
numericInput('number','Quantity',value = 1,step = 1),
br(),
numericInput('price','Price/pc',value = ''),
br(),
actionButton(inputId = "button", label = "Add", icon = icon("plus"),
style="color: #fff; background-color: #337ab7; border-color: #2e6da4"),
width = 3),
mainPanel(DTOutput('out')))
)
server <- function(input, output,session) {
observeEvent(input$button,{
order <- data.frame(read_excel("Order.xlsx"))
price <- items[items$Items == input$item,][c(2,3)]
order[nrow(order) + 1,] <- c(ifelse(input$name %in% order$Name,'',input$name),input$item,input$number,
price,price[2]* input$number,input$price*input$number,
(input$price*input$number) - (price[2]* input$number))
write.xlsx(order,'order.xlsx')
output$out<- renderDT({datatable(order)})
})
}
shinyApp(ui = ui, server = server)
items.xlsx
Items Euro Cost
some item 2.5 10
some item2 5 20
some item3 4 18
order.xlsx
Name Item Quantity Euro Cost Total cost Total price Gain
can somebody know what is the cause for that and how to solve?
Thanks all
I couldn't recreate your exact app because I had trouble getting xlsx package to load on my system. I recreated a similar working example by saving the two excel files as CSV files and using readr read_csv and write_csv in place of your read_excel and write.xlsx. This version appears to work as you want it to but with csv output instead of excel. Having a read of the xlsx documentation I might have a guess that row names are being written out each time you write.xlsx and this is showing up when you read them back in. Could it be that you need to pass row.names = FALSE to your write.xlsx call?
https://cran.r-project.org/web/packages/xlsx/xlsx.pdf
library(shiny)
library(shinythemes)
library(DT)
library(readr)
items <- readr::read_csv("items.csv",col_names = T)
ui <- fluidPage(theme = shinytheme('journal'),
sidebarLayout(
sidebarPanel(
tags$img(height = 118, width = 160, src="logo.jpg"),
br(),br(),
textInput('name','Name'),
br(),
selectizeInput(inputId = "item",
label = "Item",
choices = c(items$Items),
options = list(
placeholder = '',
onInitialize = I('function() { this.setValue(""); }'))),
br(),
numericInput('number','Quantity',value = 1,step = 1),
br(),
numericInput('price','Price/pc',value = ''),
br(),
actionButton(inputId = "button", label = "Add", icon = icon("plus"),
style="color: #fff; background-color: #337ab7; border-color: #2e6da4"),
width = 3),
mainPanel(DTOutput('out')))
)
server <- function(input, output,session) {
observeEvent(input$button,{
order <- data.frame(read_csv("order.csv"))
price <- items[items$Items == input$item,][c(2,3)]
order[nrow(order) + 1,] <- c(ifelse(input$name %in% order$Name,'',input$name),input$item,input$number,
price,price[2]* input$number,input$price*input$number,
(input$price*input$number) - (price[2]* input$number))
write_csv(order,'order.csv')
output$out<- renderDT({datatable(order)})
})
}
shinyApp(ui = ui, server = server)
Try to perform data reading and data wrangling outside of the observer as shown below.
items <- read.table(text='"Items","Euro","Cost"
some item, 2.5, 10
some item2, 5,20
some item3, 4,18', header=TRUE, sep=",")
ui <- fluidPage(theme = shinytheme('journal'),
sidebarLayout(
sidebarPanel(
tags$img(height = 118, width = 160, src="logo.jpg"),
br(),br(),
textInput('name','Name'),
br(),
selectizeInput(inputId = "item",
label = "Item",
choices = c(items$Items),
options = list(
placeholder = '',
onInitialize = I('function() { this.setValue(""); }'))),
br(),
numericInput('number','Quantity',value = 1,step = 1),
br(),
numericInput('price','Price/pc',value = ''),
br(),
actionButton(inputId = "button", label = "Add", icon = icon("plus"),
style="color: #fff; background-color: #337ab7; border-color: #2e6da4"),
width = 3),
mainPanel(DTOutput('out')))
)
server <- function(input, output,session) {
order <- eventReactive(input$button,{
req(input$number,input$price,input$name)
order <- data.frame(read_excel("order.xlsx"))
price <- items[items$Items == input$item,][c(2,3)]
order[nrow(order) + 1,] <- c(ifelse(input$name %in% order$Name,'',input$name),input$item,input$number,
price,price[2]* input$number,input$price*input$number,
(input$price*input$number) - (price[2]* input$number))
order
})
observeEvent(input$button,{ write.xlsx(order(),'order.xlsx') })
output$out<- renderDT({datatable(order())})
}
shinyApp(ui = ui, server = server)
Related
I stuck in printing dynamic slider values. In the following code I tried to print the dynamic slider values but it's not possible.
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic slider"),
dashboardSidebar(
tags$head(
tags$style(HTML('.skin-blue .main-sidebar {
background-color: #666666;
}'))
),
sidebarMenu(
menuItem("Input data", tabName = 'input_data')
),
fileInput(
"file",
"Choose CSV File",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
checkboxInput("header",
"Header",
value = TRUE),
radioButtons(
"disp",
"Display",
choices = c(Head = "head",
All = "all"),
selected = "head"
),
sliderInput(
inputId = 'slr',
label = 'Slider range',
min = 0,
max = 3,
value = c(0.5,3),
step = 0.5
),
selectInput(
inputId = 'var',
label = 'Variables',
'Names',
multiple = TRUE
),
uiOutput('sliders')
),
dashboardBody(tabItems(
tabItem(tabName = 'input_data',
fluidRow(
box(width = 12,
dataTableOutput('table'),
title = 'Raw data'),
box(width = 6,
verbatimTextOutput('slider1'),
title = 'slider range'),
box(width = 6,
verbatimTextOutput('slider2'),
title = 'dynamic slider value')
)
)
))
)
server <- function(input, output) {
dataset <- reactive({
req(input$file)
read.csv(input$file$datapath,header = input$header)
})
observe(
output$table <- DT::renderDataTable({
if (input$disp == 'head') {
head(dataset())
}
else{
dataset()
}
})
)
observe({
updateSelectInput(inputId = 'var',choices = c(' ',names(dataset())))
})
variables <- reactive({
input$var
})
sli <- reactive({
lapply(1:length(variables()), function(i){
inputName <- variables()[i]
sliderInput(inputName, inputName,
min = 0, max = 1, value = c(0.3,0.7))
})
})
output$sliders <- renderUI({
do.call(tagList,sli())
})
output$slider1 <- renderPrint({
input$slr
})
output$slider2 <- renderPrint({
sli()
})
}
shinyApp(ui = ui, server = server)
Any suggestions will be appreciated, Is there any other method to get dynamic sliders based on selected variables or How can we get the values of the dynamic slider here??
There may be better ways to structure your app, but here is a solution that follows your general approach. There are 4 modifications to what you already have:
There is no need to define the reactive variables when you can just use input$var directly. The proposed solution eliminates this reactive.
Using req(input$var) will prevent components dependent on that selectInput from trying to render when a selection has not been made.
Since input$var defines the id of the dynamic slider, you can use this to retrieve the slider's values (i.e., input[[input$var]]).
Since you have specified "multiple = TRUE", a few nested paste statements are used to create a single string representing the values of all (potentially multiple) dynamic sliders.
The below app includes these modifications, and I believe, achieves what you are trying to accomplish.
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic slider"),
dashboardSidebar(
tags$head(
tags$style(HTML('.skin-blue .main-sidebar {
background-color: #666666;
}'))
),
sidebarMenu(
menuItem("Input data", tabName = 'input_data')
),
fileInput(
"file",
"Choose CSV File",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
checkboxInput("header",
"Header",
value = TRUE),
radioButtons(
"disp",
"Display",
choices = c(Head = "head",
All = "all"),
selected = "head"
),
sliderInput(
inputId = 'slr',
label = 'Slider range',
min = 0,
max = 3,
value = c(0.5,3),
step = 0.5
),
selectInput(
inputId = 'var',
label = 'Variables',
'Names',
multiple = TRUE
),
uiOutput('sliders')
),
dashboardBody(tabItems(
tabItem(tabName = 'input_data',
fluidRow(
box(width = 12,
dataTableOutput('table'),
title = 'Raw data'),
box(width = 6,
verbatimTextOutput('slider1'),
title = 'slider range'),
box(width = 6,
verbatimTextOutput('slider2'),
title = 'dynamic slider value')
)
)
))
)
server <- function(input, output) {
dataset <- reactive({
req(input$file)
read.csv(input$file$datapath,header = input$header)
})
observe(
output$table <- DT::renderDataTable({
if (input$disp == 'head') {
head(dataset())
}
else{
dataset()
}
})
)
observe({
updateSelectInput(inputId = 'var',choices = c(' ',names(dataset())))
})
sli <- reactive({
lapply(1:length(input$var), function(i){
inputName <- input$var[i]
sliderInput(inputName, inputName,
min = 0, max = 1, value = c(0.3,0.7))
})
})
output$sliders <- renderUI({
req(input$var)
do.call(tagList,sli())
})
output$slider1 <- renderPrint({
input$slr
})
output$slider2 <- renderPrint({
req(input$var)
paste(
sapply(
input$var,
function(x) {
paste(x, paste(input[[x]], collapse = ', '), sep = ': ')
}
),
collapse = '; '
)
})
}
shinyApp(ui = ui, server = server)
I have reactive sliders where I want the bars to be red. However, the bars are ignoring my CSS style tags, although the bars do shorten when I put in the argument (compare the first and second bars length in screenshot). How do I get them to follow my tags?
Reproducible example (note: in the final answer, I need both sliders to be red--I only put my code in the first one to show that the section responds just by shortening the slider's length):
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textInput(inputId = "greeting",
label = "Say hi!"),
actionButton(inputId = "submit",
label = "Submit"),
uiOutput("num_slider"),
uiOutput("num_slider2"),
),
mainPanel(DT::DTOutput("table"))
))
server <- function(input, output) {
data <- reactive({
req(input$submit)
if(input$greeting == "hi!") {
tibble(name = c("Justin", "Corey", "Sibley"),
grade = c(50, 100, 100))}
})
output$table <- renderDT({
datatable(data())
})
output$num_slider <- renderUI({
fluidPage(
#Slider ignores the style tags--just makes the bar shorter
tags$style(
".irs-bar {",
" border-color: red;",
" background-color: red;",
"}",
".irs-bar-edge {",
" border-color: red;",
" background-color: red;",
"}"
),
if(length(data()) > 0) {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10))})
})
output$num_slider2 <- renderUI({
if(length(data()) > 0) {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 100,
max = 10000,
value = c(100, 10000))}
})
}
# Run the application
shinyApp(ui = ui, server = server)
Note the different slider bar lengths. That's not a problem, but it shows that the app is responding, in some way, to my code, even if it isn't making them red. I've also tried using shinyWidget's setSliderColor(), but it only works on one slider.
Try this
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textInput(inputId = "greeting",
label = "Say hi!"),
actionButton(inputId = "submit",
label = "Submit"),
uiOutput("num_slider") #,
#uiOutput("num_slider2")
),
mainPanel(DTOutput("table"))
))
server <- function(input, output) {
data <- reactive({
req(input$submit)
if(input$greeting == "hi!") {
tibble(name = c("Justin", "Corey", "Sibley"),
grade = c(50, 100, 100))}
})
output$table <- renderDT({
datatable(data())
})
output$num_slider <- renderUI({
if (is.null(data())) return()
tagList(
tags$head(
tags$style(type="text/css", ".slider1 label{ display: table-cell; text-align: left; vertical-align: middle; }
.slider1 .irs-bar {border-color: red; background-color: orange;}
.slider1 .irs-bar-edge { border-color: red; background-color: red;}")
),
tags$div(id = "slider1", class="slider1", style="width:25vw;",
sliderInput(inputId = "num_filter1",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10))
),
tags$div(id = "slider2", class="slider1", style="width:25vw;",
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10))
)
)
})
# output$num_slider2 <- renderUI({
#
# if(length(data()) > 0) {
# sliderInput(inputId = "num_filter2",
# label = "Filter by Number",
# min = 100,
# max = 10000,
# value = c(100, 10000))}
#
# })
}
# Run the application
shinyApp(ui = ui, server = server)
I have a reproducible example below where only the first tabPanel is working, however when I switch to another panel, I don't get any renders (the toggle becomes un-interactable also). I have looked into conditionalPanel however I see them getting done without the use of mainPanel I was wondering if it possible to have tabs where each tab has its own mainPanel , so I can see a different sidebar and an output contained within different tabs. Any help is welcome!
options(scipen = 99999) #converts the sci numbers to their regular format
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinyalert)
library(esquisse)
library(DT)
library(dplyr)
#library(devtools)
#library(remotes)
#remotes::install_github("dreamRs/esquisse")
library(hrbrthemes)
library(ggthemes)
library(ggplot2)
library(svglite)
ui <- fluidPage(
shinyjs::useShinyjs(), # enables javascript/jQuery enhanchments
# Create Right Side Text
navbarPage(
title= div(HTML("G<em>T</em>")),
#General reports
tabPanel("General Reports",
shinyWidgets::materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
shinyWidgets::prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 1,
"iris"= 2),
icon= icon("check"),
selected = 1,
status = "success",
animation="smooth"
),
br(),
br(),
a(actionButton(inputId = "admin_email", label = "Contact",
icon = icon("envelope", lib = "font-awesome")),
href="mailto:xyz#email.us")
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel1", "Text coming soon."
),
tabPanelBody(
"panel2",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel2_data')),
tabPanel(
"DIY Plot",
esquisse::esquisse_ui(
id = "esquisse2",
header = FALSE,
container = esquisseContainer(
width = "100%", height = "760px", fixed = FALSE
),
controls = c("labs", "parameters", "appearance", "filters", "code")
)
)
)
)
)
)
)
),
# monthly reports
tabPanel("Extra General Reports",
shinyWidgets::materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
shinyWidgets::prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 3,
"mtcars"= 4),
icon= icon("check"),
selected = 3,
status = "success",
animation="smooth"
),
br(),
br(),
a(actionButton(inputId = "admin_email", label = "Contact",
icon = icon("envelope", lib = "font-awesome")),
href="mailto:xyz#email.us")
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel3", "Text coming soon."
),
tabPanelBody(
"panel4",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel4_data')),
tabPanel(
"DIY Plot",
esquisse::esquisse_ui(
id = "esquisse4",
header = FALSE,
container = esquisseContainer(
width = "100%", height = "760px", fixed = FALSE
),
controls = c("labs", "parameters", "appearance", "filters", "code")
)
)
)
)
)
)
)
),
#resizes the navbar tabs/button
tags$head(tags$style(HTML('.navbar-brand {width: 270px; font-size:35px; text-align:left;
font-family: "serif";')))
)
)
server <- function(input, output, session) {
# this event hides the side panel when toggled on/off
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
if(!isTRUE(input$toggleSidebar)) {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-8').addClass('col-sm-12')")
} else {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-12').addClass('col-sm-8')")
}
})
# here we put all the data
data_sets <- list(df1 = data.frame(),
df2 = iris,
df3 = data.frame(),
df4 = mtcars)
# store current dataset in reactive so we can work with plot panels
data_to_use <- reactiveValues(name = "df", data = data.frame())
# modules only need to be called it once but individually for esquisse
esquisse::esquisse_server(id = "esquisse2", data_rv = data_to_use)
esquisse::esquisse_server(id = "esquisse4", data_rv = data_to_use)
observeEvent(input$controller, {
# skip first panel since it is used to display navigation
updateTabsetPanel(session, inputId= "hidden_tabs", selected = paste0("panel", input$controller))
# enswure value is avilable throught selected tabSet
req(input$controller)
# get current data and df name
data_to_use$data <- data_sets[[as.numeric(input$controller)]]
data_to_use$name <- names(data_sets[as.numeric(input$controller)])
# update table and sum. Use server = FALSE to get full table
output[[paste0('panel', input$controller, '_data')]] <- DT::renderDT(server = FALSE, {
DT::datatable(data_to_use$data,
filter = 'top',
extensions = 'Buttons')})
})
}
#runs the app
shinyApp(ui= ui, server= server)
You have two radioButtons, one for each sidebar, but both of them have the inputId = "controller". Same with inputId = "toggleSidebar". InputIds need to be unique in shiny!
I suggest you either use a single sidebar for the entire app, or since both tabs are essentially identical you can also use modules.
I am very new to Shiny and am not sure if I am doing this remotely correct/completely oversimplified. I am trying to pull the column headers from an excel fileInput into a selectInput drop down box.
So essentially I would like the options for the select box be determined by the headers of the file input. Then it would link into my equation in the server, which would perform the calculation based on the dataset in the column (the bit in the server with input$col).
I appreciate any comments/answers,
Thanks
EDIT: at a guess, would I need to use uiOutput and renderUI??
ui
ui <- fluidPage(theme = shinytheme(),
setBackgroundColor("white"),
titlePanel(img(src = "image.png", height = 125, width = 450)),
(h1("review app", style = "color:#337ab7")),
p("Calculate"),
headerPanel(h3("Input data here", style = "color:#337ab7")),
sidebarLayout(
sidebarPanel( position =c("left"), style = "color:#337ab7",
numericInput("SL",
"SL", 1, min=1, max=10),
numericInput("LT", "LT",0, min=0, max = 52),
fileInput("file1", 'choose file',
accept = c(".xlsx") ),
selectInput("col", "Column", choices = unique(colnames(input$file1)
)),
checkboxInput("smooth", "Clean my data", value = FALSE, width = NULL),
actionButton("action_Calc", label = "Refresh & Calculate", icon("redo"),
style="color: #fff; background-color: #337ab7; border-color: #2e6da4"),
),
mainPanel(
tabsetPanel(
tabPanel("SS", h1(textOutput("SS"), style = "color:#337ab7")),
tabPanel("guide", img(src = "guide.png", height = 200, width = 600)),
tabPanel("Mydata", div(tableOutput('contents'), style="font-size:55%"))
))))
server
server <- function(input, output) {
Data <- reactive({
req(input$file1)
inFile <- input$file1
read_excel(inFile$datapath, 1)
})
output$contents <- renderTable(bordered = TRUE, style= "border-color:#337ab7", hover = TRUE, {
Data()
})
values<- reactiveValues()
observe({
input$action_Calc
values$int<- isolate({ if (input$smooth) (round( input$SL*sqrt(input$LT/4)*sd( tsclean(Data()[[input$col]],
replace.missing = TRUE, lambda = NULL)) , digits= 2))
else (round( input$SL*sqrt(input$LT/4)*sd(Data()[[input$col]]), digits = 2)) })})
output$SS <- renderText({paste("Calculated is", values$int)} )
}
shinyApp(ui, server)
updatedSelectInput should do it for you. Below is a minimal example.
To reduce package dependencies I switched to loading .csv rather than .xlsx. Note that the loaded file isn't validated, so if junk goes in you'll get junk out.
library(shiny)
#UI
ui <- fluidPage(
selectInput('mydropdown', label = 'Select', choices = 'No choices here yet'),
fileInput('myfileinput', label = 'Select File', accept = c(".csv"))
)
#Server
server <- function(input, output, session) {
observeEvent(input$myfileinput, {
mytable <- read.csv(input$myfileinput$datapath)
updateSelectInput(session, "mydropdown", label = "Select", choices = colnames(mytable))
})
}
shinyApp(ui = ui, server = server)
I have a question about InsertUI and the respective InputID of the elements.
In the example below, the inputID of selectizeInput "Number_Product1_1" shows the output for the 1. Division in the boxOutput "InputID".
If this InputID is used as input for the boxOutput "Total", no output is displayed.
If more Divisions are added, the quantity of Product1 (in the example below '50') of the 1. division is the output in the boxOutput "Total" of the following divisions. But why is this output not shown for the 1. division?
I am confused. Can someone explain to me why this shift occurs?
Thanks for your inputs!
library(shiny)
library(shinydashboard)
# Define UI
ui <- fluidPage(
titlePanel("Identify Total amount/Divison"),
sidebarLayout(
sidebarPanel(
width = 12,
# Buttons to add/remove a question
actionButton("add", "Add Divison"),
actionButton("remove", "Remove Divison"),
div(id = "questions",
style = "border: 1px solid silver;")
),
mainPanel(
)))
# Define server logic
server <- function(input, output) {
values <- reactiveValues(num_questions = 0)
# Add a division
observeEvent(input$add, ignoreNULL = FALSE, {
values$num_questions <- values$num_questions + 1
num <- values$num_questions
ui = tags$div(
insertUI(
selector = "#questions", where = "beforeEnd",
splitLayout(
cellWidths = c("20%","20%", "20%", "20%", "20%"),
cellArgs = list(style = "padding: 3px"),
id = paste0("question", num),
textAreaInput(inputId = paste0("Division_", num),
label = paste0(num, ". Division:"),
placeholder = "Placeholder"),
selectizeInput(inputId =paste0("Number_Product1_", num),
label = paste0("Product1"), isolate(seq(from = 50, to = 100000, by = 50)), multiple=FALSE),
selectizeInput(inputId =paste0("Number_Product2_", num),
label = paste0("Product2"), isolate(seq(from = 0, to = 100000, by = 50)), multiple=FALSE),
box(
title = "Total", width = 12, background = "black",
input$Number_Product1_1), #### Input from selectizeInput "Product 1"
box(
title = "inputID", width = 12, background = "black",
paste0("Number_Product1_", num)) #### inputID's of the selectizeinput "Product 1"
)))
})
# Remove a division
observeEvent(input$remove, {
num <- values$num_questions
# Don't let the user remove the very first Row
if (num == 1) {
return()
}
removeUI(selector = paste0("#question", num))
values$num_questions <- values$num_questions - 1
})
}
# Run the application
shinyApp(ui = ui, server = server)
I might have to come up with a better explanation, Meanwhile that error is fixed.
My understanding is that within insertUI you are trying to access an id whose value would be created only after insertUI hence I tried to render it separately and assigned the output of it to the box value.
library(shiny)
library(shinydashboard)
# Define UI
ui <- fluidPage(
titlePanel("Identify Total amount/Divison"),
sidebarLayout(
sidebarPanel(
width = 12,
# Buttons to add/remove a question
actionButton("add", "Add Divison"),
actionButton("remove", "Remove Divison"),
div(id = "questions",
style = "border: 1px solid silver;")
),
mainPanel(
)))
# Define server logic
server <- function(input, output) {
values <- reactiveValues(num_questions = 0)
# Add a division
observeEvent(input$add, ignoreNULL = FALSE, ignoreInit = TRUE,{
values$num_questions <- values$num_questions + 1
num <- values$num_questions
#ui = tags$div(
# observe({
insertUI( immediate = TRUE,
selector = "#questions", where = "beforeEnd",
splitLayout(
cellWidths = c("20%","20%", "20%", "20%", "20%"),
cellArgs = list(style = "padding: 3px"),
id = paste0("question", num),
textAreaInput(inputId = paste0("Division_", num),
label = paste0(num, ". Division:"),
placeholder = "Placeholder"),
selectizeInput(inputId =paste0("Number_Product1_", num),
label = paste0("Product1"), isolate(seq(from = 50, to = 100000, by = 50)), multiple=FALSE,
selected = 50),
selectizeInput(inputId =paste0("Number_Product2_", num),
label = paste0("Product2"), isolate(seq(from = 0, to = 100000, by = 50)), multiple=FALSE),
box(
title = "Total", width = 12, background = "black",
print( input$Number_Product1_1),
textOutput("total")
), #### Input from selectizeInput "Product 1"
box(
title = "inputID", width = 12, background = "black",
paste0("Number_Product1_", num)) #### inputID's of the selectizeinput "Product 1"
))
#)
# })
})
#observe({
# require(input$Number_Product1_1)
output$total <- renderText({
input[["Number_Product1_1"]]
})
# })
# Remove a division
observeEvent(input$remove, {
num <- values$num_questions
# Don't let the user remove the very first Row
if (num == 1) {
return()
}
removeUI(selector = paste0("#question", num))
values$num_questions <- values$num_questions - 1
})
}
# Run the application
shinyApp(ui = ui, server = server)
Image: