Reputation: 735
I would like to create a matrix in which one could insert numeric values. Also, I would like that the number of rows visible depend on an actionButton. The following code herebelow works fine as long as I've got NAs in my matrix, but not if I replace the NA by some numericInput.
Here is the ui.R:
shinyUI(
pageWithSidebar(
headerPanel("test"),
sidebarPanel(
actionButtonGreen("test","add a row")),
mainPanel(
uiOutput("value"))
)
)
And here is the server.R:
shinyServer(function(input,output){
observe({
if (input$test == 0)
return()
isolate({
output$value <-renderTable(
mdat <- matrix(NA, nrow = input$test, ncol = 2, byrow = TRUE)
)
##If I change the NAs to a vector of numericInput, I obtain the following error
##Error: number of items to replace is not a multiple of replacement length
##That's when I replace the NA in the above matrix with
##c(numericInput(inputId="1",label="",value="2"),
## numericInput(inputId="2",label="",value="2"),
## numericInput(inputId="3",label="",value="2"),
## numericInput(inputId="4",label="",value="2"))
})})
} )
Any advice would be greatly appreciated.
Cheers
Upvotes: 3
Views: 4292
Reputation: 1201
I wrote these functions to do the same thing. Hope this helps.
columm <- function(x,checkval) { if (is.na(checkval)) {
return(paste('<td>',x,'</td>', sep=""))
} else {
return(paste('<td style="background-color:lightblue;">',x,'</td>', sep=""))
}
}
num_input <- function(id,checkval,default){ if (!is.na(checkval)) {
return(default)
} else {
return(paste("<input id='",id,"' type='number' value=",default,
" class='myInputstyle'>",sep=""))
}
}
Upvotes: 2
Reputation: 7840
This is what you are trying to insert into your matrix (the value of numericInput(inputId="1",label="",value="2")
) :
[1] "<label for=\"1\"></label>\n<input id=\"1\" type=\"number\" value=\"2\"/>"
attr(,"html")
[1] TRUE
and this is his structure, it's a list of 2 lists with 3 elements :
List of 2
$ :List of 3
..$ name : chr "label"
..$ attribs :List of 1
.. ..$ for: chr "1"
..$ children:List of 1
.. ..$ : chr ""
..- attr(*, "class")= chr "shiny.tag"
$ :List of 3
..$ name : chr "input"
..$ attribs :List of 3
.. ..$ id : chr "1"
.. ..$ type : chr "number"
.. ..$ value: chr "2"
..$ children: list()
..- attr(*, "class")= chr "shiny.tag"
- attr(*, "class")= chr [1:2] "shiny.tag.list" "list"
Your problem is that the function numericInput
returns something that cant fit into you matrix.
Then I suggest you to use directly the html tag in a data frame, and with the sanitize.text.function
function to evaluate the HTML tags as is (and not as strings).
shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("test"),
sidebarPanel(
actionButton("test","add a row")),
mainPanel(
tableOutput("value"))
),
server = function(input,output){
observe({
if (input$test == 0)
return()
isolate({
output$value <-renderTable({
num.inputs.col1 <- paste0("<input id='c1n", 1:input$test, "' class='shiny-bound-input' type='number' value='2'>")
num.inputs.col2 <- paste0("<input id='c2n", 1:input$test, "' class='shiny-bound-input' type='number' value='2'>")
data.frame(num.inputs.col1, num.inputs.col2)
}, sanitize.text.function = function(x) x)
})
})
}
))
Upvotes: 3