How to create TextArea as input in a Shiny webapp in R?

回眸只為那壹抹淺笑 提交于 2019-11-28 16:51:43
Joe Cheng

You can add a textarea using tags and it should be picked up by Shiny automatically:

tags$textarea(id="foo", rows=3, cols=40, "Default value")

Or if you're more comfortable with straight HTML you can also do

HTML('<textarea id="foo" rows="3" cols="40">Default value</textarea>')

In either case, input$foo should reflect the textarea's value.

For benefit of others, I will post how I solved the problem using custom UI control following Shiny tutorial

Firstly, I crearted textarea.js file as follows

$(document).on("click", "textarea.inputTextarea", function(evt) {

  // evt.target is the button that was clicked
  var el = $(evt.target);

  // Raise an event to signal that the value changed
  el.trigger("change");
});

var inputTextareaBinding = new Shiny.InputBinding();
$.extend(inputTextareaBinding, {
  find: function(scope) {
    return $(scope).find(".inputTextarea");
  },
  getValue: function(el) {
    return $(el).text();
  },
  setValue: function(el, value) {
    $(el).text(value);
  },
  subscribe: function(el, callback) {
    $(el).on("change.inputTextareaBinding", function(e) {
      callback();
    });
  },
  unsubscribe: function(el) {
    $(el).off(".inputTextareaBinding");
  }
});

Shiny.inputBindings.register(inputTextareaBinding);

Then I added following function in ui.R of shiny webapp before shinyUI() is called

inputTextarea <- function(inputId, value="", nrows, ncols) {
    tagList(
        singleton(tags$head(tags$script(src = "textarea.js"))),
        tags$textarea(id = inputId,
                    class = "inputtextarea",
                    rows = nrows,
                    cols = ncols,
                    as.character(value))
    )
}

Then I used above defined function to create the desired textarea control element in ui.R

shinyUI(pageWithSidebar(

  # Application title
  headerPanel("Test Header Panel"),

  sidebarPanel(),

  mainPanel(
        inputTextarea('exampleTextarea', '',20,35 )
  )
))

May or may not be relevant here, but I made the shinyAce package to wrap up and expose the Ace text editor in Shiny. Ace is primarily used for code editing (complete with syntax highlighting for a variety of languages), but provides a text-area-like interface for writing composing multi-line text/code.

You can check out the example to see if that might be what you're looking for. (Try different "modes" for syntax highlighting and themes for color combinations.)

From version 0.14 shiny has an implementation of textAreaInput.

Steve Ladavich

Building off of Joe's answer (https://stackoverflow.com/a/14452837/5776618), you can also nest tags into your own function to achieve the same output as the standard Shiny built-in input functions.

textareaInput <- function(id, label, value, rows=20, cols=35, class="form-control"){
  tags$div(
    class="form-group shiny-input-container",
    tags$label('for'=id,label),
    tags$textarea(id=id,class=class,rows=rows,cols=cols,value))
  }

This is a way to avoid writing the JS code (if you want to) while still...

  • having a function that calls the same way the built-in Shiny inputs are called, and
  • includes the div, label, and Bootstrap's form-control CSS style (so that it looks like the built-in Shiny input controls)

Using the function is same as if you are using the built-in or if you built a custom UI.

textareaInput("textareaID","Text Area Label", "Insert text here...", rows = 20, cols = 35)

Here's a quick solution that preserves the shiny input feel, but allows custom number of columns:

textareaInput <- function(inputID, label, value="", rows=10, columns=80) {
  HTML(paste0('<div class="form-group shiny-input-container">
    <label for="', inputID, '">', label,'</label>
    <textarea id="', inputID, '" rows="', rows,'" cols="', 
    columns,'">', value, '</textarea></div>'))
}

In your ui.R script, you can add:

textareaInput("shazam", "My text box")


Note: To get a Bootstrap feel to the textarea, you can use:

textareaInput <- function(inputID, label, value="", rows=10) {
  HTML(paste0('<div class="form-group shiny-input-container">
              <label for="', inputID, '">', label,'</label>
              <textarea class="form-control" id="', inputID, 
              '" rows="', rows, '">', value, '</textarea></div>'))
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!