Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A dynamically resizing shiny textAreaInput box?

Tags:

r

shiny

I am trying to make a textAreaInput box in shiny that spans 100% of my webpage and resizes when the browser is min/maximised. I can make a simple textInput with this behavior by supplying the argument width = 100%. Supplying the same argument to textAreaInput does not produce the same behavior even though width has the same description on the textInput and textAreaInput man pages. Is this desired behavour or a bug?

A minimal working example -

library(shiny)

shinyApp(
    #UI
    ui = fluidPage(
        fluidRow(
            column(12,
                textAreaInput("big_box", "Big box", value = "", width = '100%', rows = 5, resize = "both")
            )
        ), 
        fluidRow(
            column(12,
                textInput("long_box", "Long box", value = "", width = '100%')
            )
        )
    ),
    #Server
    server = function(input, output) {
    }
)

Example output -

Cheers

like image 605
RoachLord Avatar asked Nov 25 '16 16:11

RoachLord


3 Answers

A simpler workaround is to set the height and width parameters to the parent element, using shiny::tagAppendAttributes function.

For example:

 textAreaInput("big_box", "Big box", value = "", rows = 5, resize = "both") %>%
     shiny::tagAppendAttributes(style = 'width: 100%;')
like image 167
Rafael García Avatar answered Sep 30 '22 17:09

Rafael García


Or you could just override the css by using a header tag within your ui function e.g:

tags$style(HTML("                  
  .shiny-input-container:not(.shiny-input-container-inline) {
  width: 100%;
}"))
like image 44
MrHopko Avatar answered Sep 30 '22 16:09

MrHopko


textAreaInput was recently added to Shiny in version 14, it seems that it is a bug cause by the class shiny-input-container. In shiny.css we can find:

/* Limit the width of inputs in the general case. */

.shiny-input-container:not(.shiny-input-container-inline) {
  width: 300px;
  max-width: 100%;
}

The simplest workaround is to create a new function based on the original without the class shiny-input-container. Below is the new function.

library(shiny)

#based on Shiny textAreaInput
textAreaInput2 <- function (inputId, label, value = "", width = NULL, height = NULL, 
    cols = NULL, rows = NULL, placeholder = NULL, resize = NULL) 
{
    value <- restoreInput(id = inputId, default = value)
    if (!is.null(resize)) {
        resize <- match.arg(resize, c("both", "none", "vertical", 
            "horizontal"))
    }
    style <- paste("max-width: 100%;", if (!is.null(width)) 
        paste0("width: ", validateCssUnit(width), ";"), if (!is.null(height)) 
        paste0("height: ", validateCssUnit(height), ";"), if (!is.null(resize)) 
        paste0("resize: ", resize, ";"))
    if (length(style) == 0) 
        style <- NULL
    div(class = "form-group", 
        tags$label(label, `for` = inputId), tags$textarea(id = inputId, 
        class = "form-control", placeholder = placeholder, style = style, 
        rows = rows, cols = cols, value))
}

shinyApp(
    #UI
    ui = fluidPage(
        fluidRow(
            column(12,
                textAreaInput2("big_box2", "Big box", value = "", width = '100%', rows = 5, resize = "both")
            )
        ), 
        fluidRow(
            column(12,
                textInput("long_box", "Long box", value = "", width = '100%')
            )
        )
    ),
    #Server
    server = function(input, output) {
    }
)
like image 21
Geovany Avatar answered Sep 30 '22 16:09

Geovany