问题
Hello Stack Overflow,
in recent questions by me I've solved some major issues related to dynamically rendered UI elements and dynamically created observers for those with the help of some amazing people here. see i.e. here: Dynamically rendered UI: how to delete old reactive variables on second run
Now I'm building a part of it that dynamically renders textInput fields. The rendering and monitoring shouldn't be a problem because I can apply the same way of coding as for the actionbuttons we've already made, but the styling of these elements is proving a problem.
As far as I know there are 2 ways to style elements:
add tags$style(.....)
to them like,
1:
tags$style(type="text/css", "#BatchName { width: 520px; position: relative;left: 7%}")
in the UI
or 2:
actionButton(inputId= "Submit", label = icon("upload"),
style="color: blue; color: white;
text-align:center; indent: -2px;
border-radius: 6px; width: 2px"),
The 2nd option also works for the dynamic rendering as seen in the link above, and would work in the example below as well if I was to make actionButtons instead of textInput in the lapply loop in the working example below. However, the style = "......" element inside a textInput() doesn't work.
Does anyone have a solution to also add style dynamically to textinput?
Solutions I've tried but failed:
dynamically making tags$head elements but it's not a ui element as could be made with renderUI() I think
Somehow making textinput accept the style = " ")
argument.
Finally I had a look at the function code of textInput and wondered if plan A or B don't work, whether it would be possible to modify the existing textInput code into my own function with more freedom? textinput is coded like this in the package:
function (inputId, label, value = "", width = NULL, placeholder = NULL)
{
value <- restoreInput(id = inputId, default = value)
div(class = "form-group shiny-input-container", style = if (!is.null(width))
paste0("width: ", validateCssUnit(width), ";"), label %AND%
tags$label(label, `for` = inputId), tags$input(id = inputId,
type = "text", class = "form-control", value = value,
placeholder = placeholder))
}
WORKING EXAMPLE:
library(shiny)
library(shinydashboard)
library(shinyBS)
ui <- dashboardPage(
dashboardHeader(title = "My Test App"),
dashboardSidebar(
sidebarMenu(id = "tabs", menuItem("testpage", tabName = "testpage", icon = icon("book"))
)
),
dashboardBody(
tags$head(tags$style(HTML('.skin-blue .content-wrapper, .right-side {background-color: #ffffff; }, '))),
tabItems(
### test page ###_________
tabItem(tabName = "testpage",
h5("Enter desired nr of elements here"),
textInput(inputId ="NrOfClusters", label = NULL , placeholder = "NULL"),
uiOutput("NameFields")
))))
shinyServer<- function(input, output, session) {
################# start functionality HOME TAB #############################
### create 2 reactive environment lists
values <- reactiveValues(clickcount=0)
DNL <- reactiveValues(el=NULL)
### set initial state of two buttons
values$HL_multi_switch_sf1 <- FALSE
values$HL_all_switch_sf1 <- FALSE
### if the user types in a value, then convert it to a reactive value of this nr
observeEvent (input$NrOfClusters, {
values$nrofelements <- input$NrOfClusters
namelist <- as.character(unlist(DNL$el), use.names = FALSE)
})
AddNameField <- function(idx){
sprintf("highlight_button_sf1-%s-%d",values$nrofelements,idx)
}
#### RENDER DYNAMIC UI and DYNAMIC OBSERVERS
observeEvent(values$nrofelements, {
req(input$NrOfClusters)
nel <- values$nrofelements
DNL$el <- rep(0,nel)
names(DNL$el) <- sapply(1:nel,AddNameField)
output$NameFields <- renderUI({
lapply(1:values$nrofelements, function(ab) {
div(br(), textInput(inputId = AddNameField(ab), label = NULL))
})
})
lapply(1:values$nrofelements, function(ob) {
textfieldname <- AddNameField(ob)
print(textfieldname)
observeEvent(input[[textfieldname]], {
DNL$el[[ob]] <- input[[textfieldname]]
namelist <- as.character(unlist(DNL$el), use.names = FALSE)
print(namelist)
})
})
})
}
options(shiny.reactlog = TRUE)
shinyApp(ui,shinyServer)
来源:https://stackoverflow.com/questions/43982515/how-to-add-style-elements-to-dynamically-rendered-textinput-in-shiny