Reputation: 491
I want to change the order of focus when the tab key is used to move among objects in Shiny. Currently, the tab key goes from Name to the Next button because they are in the same column. I want the object order to be Name, Prediction 1, Prediction 2, Next button when the tab key is pressed.
The name field and Next button are in one fluidRow column. The two prediction fields are each in separate fluidRow columns.
I know that I can use the tabindex = "##"
tag to change the index order, where ##
is the index order number I want. I think (from here) that I need to modify the .shiny-input-container:not(.shiny-input-container-inline)
CSS. However, I am not sure how to go about it. I have tried several unsuccessful combinations, with a few examples in the commented lines below. In the examples, I use tabindex = "-1"
to make the input modal, just so I could tell whether my attempt worked.
Edit
Since posting my question, I have learned that tabindex
should not be used in the way I have asked, for accessibility reasons (e.g., here and here). I am still interested in approaches other than the nice solution provided by @ismirsehregal, although I suspect they too may have accessibility issues.
MWE
library(shiny)
ui <- fluidPage(
fluidRow(
column(
3,
textInput(inputId = "name", label = "Name"),
actionButton(inputId = "next", label = "Next")
),
column(
3,
#tags$style(HTML(`tabindex` = "-1"))
#tags$style(HTML(.shiny-input-container:not(.shiny-input-container-inline) {`tabindex` = "-1"}))
# I tried to use tags$div and tags$input also but no luck. The
textAreaInput(# I also tried to put the modifications here.
inputId = "pred1", label = "Prediction 1")
),
column(3, textAreaInput(inputId = "pred2", label = "Prediction 2"))
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Created on 2021-10-05 by the reprex package (v2.0.1)
Upvotes: 3
Views: 385
Reputation: 491
I figured out how to add tabindex
by building the objects entirely using tags. The solution is suitable for those who enjoy typing lots of code but it helped me better understand how Shiny builds the objects.
library(shiny)
ui <- fluidPage(
fluidRow(
column(
3,
# Build objects completely using tags.
tags$div(
class = "form-group shiny-input-container",
tags$label("Name",
class = "control-label",
id = "name-label",
`for` = "name"
),
tags$input("name",
id = "name",
type = "text",
class = "form-control",
value = "",
tabindex = "1"
)
),
myButton <- tags$button("Next",
id = "button2",
type = "button",
class = "btn btn-default action-button",
style = "color: #fff; background-color: #9d2235; border-color: #003B5C",
tabindex = "4"
)
),
column(
3,
# Modify object from answer by @ismirsehregal.
# Better method.
tagAppendAttributes(
textAreaInput(
inputId = "pred1",
label = "Prediction 1"),
.cssSelector = "#pred1",
tabindex = 2)
),
column(
3,
tagAppendAttributes(
textAreaInput(
inputId = "pred2",
label = "Prediction 2"),
.cssSelector = "#pred2",
tabindex = 2)
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Created on 2021-10-06 by the reprex package (v2.0.1)
Upvotes: 1
Reputation: 33510
tagAppendAttributes
from library(htmltools)
can be used to set the tabindex
:
library(shiny)
library(htmltools)
ui <- fluidPage(fluidRow(
column(3,
tagAppendAttributes(textInput(inputId = "name", label = "Name"), .cssSelector = "#name", tabindex = 1),
tagAppendAttributes(actionButton(inputId = "next", label = "Next"), .cssSelector = "#next", tabindex = 4)
),
column(3, tagAppendAttributes(textAreaInput(inputId = "pred1", label = "Prediction 1"), .cssSelector = "#pred1", tabindex = 2)),
column(3, tagAppendAttributes(textAreaInput(inputId = "pred2", label = "Prediction 2"), .cssSelector = "#pred2", tabindex = 3)),
))
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Upvotes: 4