I have a tagList
(inputs
) of two inputs: a selectInput
and a checkboxInput
:
inputs = tagList(
selectInput('first', 'FIRST', letters),
checkboxInput(inputId = 'second', label = 'SECOND')
)
str(inputs, max.level = 1)
List of 2
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
..- attr(*, "html_dependencies")=List of 1
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
- attr(*, "class")= chr [1:2] "shiny.tag.list" "list"
I would like to extract the label tag for each input and was wondering if the shiny package had any getters and setters for this?
The closest thing I could find was this article on building custom inputs but the getters are JS functions.
So I attempted to write a function which recurses through the inputs list and extracts the label tag by name:
library(shiny)
library(htmltools)
getLabel2 <- function(children) {
lapply(children, function(x) {
if(inherits(x, 'shiny.tag')) {
if(x$name == 'label') {
return(x)
} else {
chldn = x$children
if(is.list(chldn)) getLabel2(chldn)
}
}
})
}
getLabel <- function(inputs) {
lapply(inputs, function(x) {
if(grepl('shiny-input-container', tagGetAttribute(x, 'class'))) {
tagGetAttribute(x, 'id')
getLabel2(x$children)
} else {
return(x)
}
})
}
Reprex:
#Reprex
inputs = tagList(
selectInput('first', 'FIRST', letters),
checkboxInput(inputId = 'second', label = 'SECOND')
)
labels = getLabel(inputs)
However, there are some problems with this function:
- It returns a list that contains the label tags and
NULL
s in place of non-label tags - how can I modify it so that it returns a list of length 2 (where the first element is the label tag for input 1 and the second element is the label tag for input 2)? - It doesn't check that the label tag being extracted is matched to the corresponding input tag. I wanted to do this by checking that the
for
attribute of the label tag (obtained using thetagGetAttribute(label_tag, 'for')
) matches theid
attribute of the corresponding input tag (obtained using thetagGetAttribute(input_tag, 'id')
) - but I don't know if this is possible since the input tag is not easily identifiable. Is ashiny-input-container
only allowed to have one label tag among its children? If so, then this check isn't necessary.
I would be grateful for any help on this as I don't know what else to try.