31

I am trying to create simple webapp where I want to take in multiline input from user using HTML textarea control. Is there any out of the box way of creating such an input control in Shiny?

Help page of textInput doesn't show much options

textInput {shiny}   R Documentation
Create a text input control

Description

Create an input control for entry of unstructured text values

Usage

  textInput(inputId, label, value = "")
Arguments

inputId 
Input variable to assign the control's value to

label   
Display label for the control

value   
Initial value

Value

A text input control that can be added to a UI definition.

Examples

textInput("caption", "Caption:", "Data Summary")
CHP
  • 16,981
  • 4
  • 38
  • 57

6 Answers6

40

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.

vrajs5
  • 4,066
  • 1
  • 27
  • 44
Joe Cheng
  • 8,001
  • 42
  • 37
  • 1
    While it points in right direction, it's wasn't directly clear where to add above lines. I just went about creating custom control. – CHP Jan 22 '13 at 06:36
  • 1
    The above lines (either one or the other, not both) should be added wherever you want the textarea to appear. The custom control will work but the built-in textarea binding should work a little better, IMHO: it subscribes to `keyup` and `input` events as well, and applies 250ms debounce. – Joe Cheng Feb 22 '13 at 19:00
  • 3
    Is there an easy way to add a label to the `textarea` as is done with `textInput`? – jpd527 Feb 24 '14 at 17:50
  • 1
    @jpd527 - I know this is a bit old, but Shiny does this by putting the label and the input item inside a
    element. You could accomplish this using tags.
    – srvanderplas May 06 '15 at 15:40
26

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 )
  )
))
CHP
  • 16,981
  • 4
  • 38
  • 57
  • You mention a shiny tutorial, but I haven't found one on creating custom controls. Which shiny tutorial was that? – Mike Wise Jun 09 '16 at 12:56
16

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.)

Jeff Allen
  • 17,277
  • 8
  • 49
  • 70
  • That sounds great. Is there an example showing how to run the code typed in the editor ? – Stéphane Laurent Oct 15 '13 at 20:12
  • There is not just yet... but that's next on my todo list for the project. There should be an example posted this month. – Jeff Allen Oct 15 '13 at 20:30
  • Currently, the contents of `input$yourEditorsName` is the text as a character string ? – Stéphane Laurent Oct 23 '13 at 09:42
  • Thus would it be possible to run this code in `server.R` by doing `code <- textConnection(input$yourEditorsName); source(code); close(code)` ? – Stéphane Laurent Oct 23 '13 at 14:45
  • That would likely work. The approach I was envisioning would probably follow the `eval` model: http://stackoverflow.com/questions/1743698/r-eval-expression – Jeff Allen Oct 23 '13 at 14:51
  • Thank you, nice with `eval(parse())`: http://glimmer.rstudio.com/stla/testShinyAce1/. I don't find the code of your example, is it available ? – Stéphane Laurent Oct 23 '13 at 22:14
  • That one's actually not mine. All my code will be available here: https://github.com/trestletech/shinyAce/tree/master/inst/examples – Jeff Allen Oct 23 '13 at 22:17
  • Thank you, that's helpful. Is there a way to change the characters size ? – Stéphane Laurent Oct 24 '13 at 17:37
  • Not currently. Please create an issue for any request and I'll take a look. https://github.com/trestletech/shinyAce/issues – Jeff Allen Oct 24 '13 at 17:45
  • Ok. Nice :) I'm making an app for my statistician colleagues, so it's faster for me to let them modifying some pieces of code in the Ace editor, instead of creating a UI widget for each parameter. – Stéphane Laurent Oct 24 '13 at 18:19
5

From version 0.14 shiny has an implementation of textAreaInput.

alko989
  • 7,688
  • 5
  • 39
  • 62
3

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)
Community
  • 1
  • 1
Steve Ladavich
  • 3,472
  • 20
  • 27
2

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>'))
}
Megatron
  • 15,909
  • 12
  • 89
  • 97