Shiny: Tips for splitting output string into (manipulable) single words

335 views Asked by At

In a Shiny App I output a rendered text with the following code:

  output$prediction <- renderText({
    unlist(strsplit(unique(candidates()[,"word"])," "))
  })

The strsplit, however, seems to be irrelevant, as the output is delivered as a single string.

tags$div(
   htmlOutput("prediction", type="button", 
              container = tags$button, 
              class = "btn btn-info")
)

1]

Resulting HTML code:

<div>
        <button class="shiny-html-output btn btn-info shiny-bound-output"
                id="prediction" type="button">
                important interesting boring of people
        </button>
</div>

Desired Output:

2]

I need to be able to apply a button tag to each of the words that compound the output. Or, in other words, the resulting HTML should be:

<div>
<button class="shiny-html-output btn btn-info shiny-bound-output" id="prediction1" type="button">important</button>
<button class="shiny-html-output btn btn-info shiny-bound-output" id="prediction2" type="button">interesting</button>
<button class="shiny-html-output btn btn-info shiny-bound-output" id="prediction3" type="button">boring</button>
<button class="shiny-html-output btn btn-info shiny-bound-output" id="prediction4" type="button">of</button>
<button class="shiny-html-output btn btn-info shiny-bound-output" id="prediction5" type="button">people</button>
</div>

Please take note that the server.R can deliver an undefined number of words, from 1 to 25, and therefore I cannot just make 5 different calls to the server.R file.

1

There are 1 answers

2
greg L On BEST ANSWER

Sounds like what you're really looking for is how to build dynamic UI. My advice would be to take advantage of functions. Write a function that generates the most basic unit of your UI, then compose them to build more complex UI.

In this case, the building blocks would be these word buttons, which are really just divs with button style classes (at least in your example):

wordButton <- function(word) {
  div(word, class = "btn btn-info")
}

From there, you can use for loops or the apply functions. Here's a full example:

library(shiny)

wordButton <- function(word) {
  div(word, class = "btn btn-info")
}

ui <- fluidPage(
  uiOutput("words")
)

server <- function(input, output) {
  words <- reactive({
    c("important", "interesting", "boring", "of", "people")
  })

  output$words <- renderUI({
    lapply(words(), wordButton)
  })
}

shinyApp(ui, server)