Reputation: 2283
Say for example, I have a very basic shiny application where you selectize a letter:
library(shiny)
ui <- fluidPage(
fluidRow(
column(3, selectizeInput("Letters", "Choose a Letter",
choices = LETTERS, multiple = TRUE)
)
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
I need this shiny application to be 508 compliant/accessible. If I run it through a web accessibility test like WAVE, I get an error about a Missing form label for this selectizeInput section.
I believe this is because of a random div that is added that does not have the same ID that the "Choose a letter" label references. The label is for Letters-selectized
and the div that is showing an accessibility error has the ID Letters
. Is there any way to fix this error? I know you can add render
to the options for selectizeInput but I havent found a way to correct this particular div.
Based on comment from ismirsehregal
If I try to add an additional label with tagQuery
for the ID "Letters", I get a duplicate form label error. I believe this is because even though I specify "for" = "Letters"
the output is still for = "Letters-selectized"
library(shiny)
library(htmltools)
ui <- fluidPage(
{queryfluidRow <- tagQuery(fluidRow(
column(3, selectizeInput("Letters", "Choose a Letter",
choices = LETTERS, multiple = TRUE))
)
)
queryfluidRow$find("#Letters")$parent()$prepend(tag("label hidden",list("class" = "control-label","for" = "Letters", "Custom Tag")))$allTags()}
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
The added tagQuery label html looks like the following and produces additional errors. I probably do not understand the underlying html relationship between labels and form control selection. However, I would have assumed setting "for" = "Letters"
in tagQuery
would have assigned the label to the correct ID:
<label hidden="" class="control-label" for="Letters-selectized">Custom Tag</label>
<select id="Letters" class="form-control selectized shiny-bound-input" multiple="multiple" tabindex="-1" style="display: none;"></select>
Upvotes: 5
Views: 274
Reputation: 6921
{shinyjs} allows you i. a. to execute javascript code client-side. You can thus query your label element via its id and set its for
attribute like so:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(), # include shinyjs
fluidRow(
column(3, selectizeInput("Letters", "Choose a Letter",
choices = LETTERS, multiple = TRUE)
)
)
)
server <- function(input, output, session) {
runjs('document.getElementById("Letters-label").setAttribute("for", "letters")')
}
shinyApp(ui = ui, server = server)
BTW, apart from above library, Shiny Awesome lists many more, well, awesome extensions for Shiny apps. Kudos to Nan Xiao.
Upvotes: 2