Reputation: 362
I want to add a line break in one choice because it is too long. Answers to a similar question about the label of a button say to wrap the string in HTML()
, but the solution does not seem to work for choices
in checkboxGroupInput()
.
library(shiny)
choices_vector <- c(
'Choice 1',
HTML('Choice 2 shoulde be<br />on two lines'),
'Choice 3'
)
ui <- fluidPage(
checkboxGroupInput(
inputId = 'choices_selec',
label = '',
choices = choices_vector
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
This is older example code and is more complicated. It is left here because one answer uses many of the specifics of this example.
ui <- fluidPage(
splitLayout(cellWidths = c(170,80,160),
tagList(uiOutput("example")))
)
server <- function(input, output) {
choices_vector <- c("choice 1","choice 2",HTML("I want a line break here <br/> since the label is too long"),"choice 4")
output$example <- renderUI({
checkboxGroupInput(inputId = "choices_selec",
label = "", choices = choices_vector, selected = F)
})
}
# Run the application
shinyApp(ui = ui, server = server)
I also tried using using paste0
and collapse
(see the following code) and changing uiOutput
for htmlOutput
but the results are the same
server <- function(input, output) {
choices_vector <- c("choice 1","choice 2",paste0(c("I want a line break here ", "since the label is too long"), collapse = "<p/>"),"choice 4")
output$example <- renderUI({
checkboxGroupInput(inputId = "choices_selec",
label = "", choices = choices_vector, selected = F)
})
}
Upvotes: 4
Views: 581
Reputation: 1081
The documentation for checkboxGroupInput()
explains:
The advantage of using [
choiceNames
andchoiceValues
] over a named list for choices is thatchoiceNames
allows any type of UI object to be passed through (tag objects, icons, HTML code, ...), instead of just simple text.
In other words, this works:
checkboxGroupInput(
inputId = 'InputCorrect',
label = 'Correct',
choiceNames = list(
'Choice 1',
HTML('Choice 2 is<br />on two lines'),
'Choice 3'
),
choiceValues = 1:3,
)
but this does not:
checkboxGroupInput(
inputId = 'InputIncorrect',
label = 'Incorrect',
choices = list(
'Choice 1',
HTML('Choice 2 is<br />not on two lines'),
'Choice 3'
)
)
Extra complications to keep in mind when passing a previously-defined list to choiceNames
:
First, use list()
instead of c()
when defining the choiceNames
. Elements of a vector must be the same type. Thus, c('A', HTML('B'), 'C')
does not actually have any HTML
elements. Also, I think R does not support vectors of HTML elements, anyway.
Second, when placing the HTML()
in the list manually is not feasible/desirable, make a character vector and then use lapply()
to change every element to HTML
:
choices_vector = c('Choice 1', 'Choice 2 is<br />not on two lines', 'Choice 3')
choices_vector = lapply(choices_vector, HTML)
(Note the use of lapply
)
library(shiny)
choices_vector = c(
'Choice 1',
'Choice 2 is<br />on two lines',
'Choice 3'
)
ui = fluidPage(
checkboxGroupInput(
inputId = 'InputExistingList',
label = 'Also correct',
choiceNames = lapply(choices_vector, HTML),
choiceValues = 1:length(choices_vector),
)
)
server = function(input, output) {}
shinyApp(ui = ui, server = server)
Upvotes: 0
Reputation: 7330
The problem is checkboxGroupInput
only accepts strings as choices
. There is nothing we can do unless you change the Shiny source code. Try to think out of the box, why do we need to do it at R preprocessing level. We can use js to post-process it on the client-side (browser).
Here's how, do as usual, but just add this very simple js code after the checkbox:
library(shiny)
ui <- fluidPage(
splitLayout(cellWidths = c(170,80,160),
tagList(uiOutput("example")))
)
server <- function(input, output) {
choices_vector <- c("choice 1"="c1","choice 2"="c2", "I want a line break here<br/> since the label is too long"="c3","choice 4"="c4")
output$example <- renderUI({
tagList(
checkboxGroupInput(inputId = "choices_selec",
label = "", choices = choices_vector, selected = F),
tags$script(
"
$('#choices_selec .checkbox label span').map(function(choice){
this.innerHTML = $(this).text();
});
"
)
)
})
observe({
print(input$choices_selec)
})
}
# Run the application
shinyApp(ui = ui, server = server)
This code will allow you to use any HTML tag as string input. The HTML will be parsed once the check box is rendered.
I also add names to the choice vector, so you will have a better way on the server side to know what choices are selected.
Upvotes: 3