shiny icon indicating copy to clipboard operation
shiny copied to clipboard

let text(Area)Input set maxlength

Open maxheld83 opened this issue 4 years ago • 1 comments

I like to make sure that character inputs in textInputArea() aren't excessively long (maliciously so?) to protect my compute. I currently do this with https://github.com/rstudio/shinyvalidate/, which is amazing, but this is already bringing the overlong string into R, which somewhat defeats the purpose.

It seems that the idiomatic / better way would be to set these limits in HTML so that they are enforced by the client browser. HTML provides the maxlength attribute for this purpose.

In this S-O people are already using shinyjs::runjs() to set this attribute, though that seems a minor, if needless modification of the DOM.

It might also be worthwhile to expose other attributes, or maybe just a ...?

If there's interest, I'd be happy to draft a PR.

maxheld83 avatar Feb 23 '21 10:02 maxheld83

I've come across this a few times now and I think that a native maxlength parameter would be a nice addition directly in shiny. Thanks for considering.

bhogan-mitre avatar Jan 25 '22 14:01 bhogan-mitre

Since {htmltools} v0.5.2 it is possible to use tagQuery() and its methods to modify HTML before rendering.

Here I provide an example of a wrapper of textInput() that allows to set the maxlength attribute.

textInput2 <- function(inputId, label, value = "", width = NULL, 
                       placeholder = NULL, maxlength = NULL) {
    
    tag <- shiny::textInput(
        inputId = inputId,
        label = label,
        value = value,
        width = width,
        placeholder = placeholder
    )
    
    if (!is.null(maxlength)) {
        htmltools::tagQuery(tag)$
            children("input")$
            addAttrs(maxlength=maxlength)$
            allTags()
    } else {
        tag
    }
    
}

This attribute has some constrains you should be aware of. Also, feedback to users (e.g. showing that the user is reaching the chr limit) needs to be handled in javascript.

If you want to make some reactive updates you can use updateTextInput() normally.

calderonsamuel avatar Jan 27 '23 20:01 calderonsamuel