shinyCopy2clipboard : Copy to Clipboard in Shiny Apps

Introduction
This post explains how to implement Copy text to clipboard functionality in a Shiny App. This is based on clipboard.js javascript which is a lightweight JS sized only 3KB. We have also included tooltip which shows Copied once clicked on the button. This package is useful when you want to allow user to copy content from shiny app.
Copy to Clipboard in Shiny
Installation
I am glad to release R package named shinyCopy2clipboard for this. You can install it from github. It is not available in CRAN yet.
remotes::install_github("deepanshu88/shinyCopy2clipboard")
Demo
I deployed app on shinyapps.io which has option to copy generated HTML to clipboard. You can see demo here
Basic Example
In the example below we have a text input. We are asking user to enter text in the widget. Entered text will be copied via clicking on the button. If user does not enter text and click on the button it shows "No Text Found".
library(shiny)
library(shinyCopy2clipboard)

# UI
ui <- fluidPage(

  # Setup
  use_copy(),

  # Text Input 1
  textInput("text", "Enter Your Text"),

  # Copy Button 1
  CopyButton(
    "copybtn",
    label = "Copy to clipboard",
    icon = icon("copy"),
    text = "No Text Found"
  )

)

# Server
server <- function(input, output, session) {

  observe({

    req(input$copybtn)
    CopyButtonUpdate(session,
                     id = "copybtn",
                     label = "Copy to clipboard",
                     icon = icon("copy"),
                     text = input$text
    )

  })

}

# Run App
shinyApp(ui = ui, server = server)

In the server we have CopyButtonUpdate( ) which can store strings or values from any widget, be it text input, text area, datatable etc. You just need to store it in reactive expression and pass it in text argument of CopyButtonUpdate( ). You can also change the icon after user press the button.

Customize Button : Showing SVG
Here we are showing SVG instead of text label. That's how it looks - Copy to clipboard
library(shiny)
library(shinyCopy2clipboard)

# UI
ui <- fluidPage(

  # Setup
  use_copy(),

  # Text Input 1
  textInput("text", "Enter Your Text"),

  # Copy Button 1
  CopyButton(
    "copybtn",
    label = HTML('<img src="copy2clipboard-assets/clippy.svg" width="13" alt="Copy to clipboard">'),
    text = "No Text Found"
  )

)

# Server
server <- function(input, output, session) {

  observe({

    req(input$copybtn)
    CopyButtonUpdate(session,
                     id = "copybtn",
                     label = HTML('<img src="copy2clipboard-assets/clippy.svg" width="13" alt="Copy to clipboard">'),
                     text = input$text
    )

  })

}

# Run App
shinyApp(ui = ui, server = server)
To show SVG next to textInput you can use style = argument in copyButton( ) function and wrap both the widgets in form.
library(shiny)
library(shinyCopy2clipboard)

# UI
ui <- fluidPage(
  
  # Setup
  use_copy(),
  
  tags$form(class="form-inline",
  
  # Text Input 1
  textInput("text", "Enter Your Text"),
  
  # Copy Button 1
  CopyButton(
      "copybtn",
      label = HTML('<img src="copy2clipboard-assets/clippy.svg" width="13" alt="Copy to clipboard">'),
      text = "No Text Found",
      style = "margin-left: -7em; margin-top: 1.5em;"
    )
    
  )
  
)

# Server
server <- function(input, output, session) {
  
  observe({
    
    req(input$copybtn)
    CopyButtonUpdate(session,
                     id = "copybtn",
                     label = HTML('<img src="copy2clipboard-assets/clippy.svg" width="13" alt="Copy to clipboard">'),
                     text = input$text
    )
    
  })
  
}

# Run App
shinyApp(ui = ui, server = server)
Show Copy to Clipboard Button in Modal
You need to set modal = TRUE to make it work in modal. Following example shows multiple buttons and modal.
library(shiny)
library(shinyCopy2clipboard)

# The UI
ui <- fluidPage(

  # Load
  use_copy(),

  # Text Input 1
  textInput("text", "Enter Your Text", "Hello World!"),

  # Copy Button 1
  CopyButton(
    "copybtn",
    "Copy to Clipboard",
    icon = icon("copy"),
    text = "No Text Found",
    class = "btn-primary",
    width = "150px"
  ),

  br(),
  br(),

  # Text Input 2
  textInput("text2", "Enter Your Text"),

  # Copy Button 2
  CopyButton(
    "copybtn2",
    "Copy to Clipboard",
    icon = icon("copy"),
    text = "No Text Found",
    class = "btn-primary"
  ),

  br(),
  br(),

  # Button for Modal
  actionButton('mdl', 'Show Button in Modal')

)

# The server
server <- function(input, output, session) {

  observeEvent(input$mdl, {

    shiny::showModal(
      modalDialog(
        textInput("text3", "Enter your comments"),

        CopyButton(
          "copybtn3",
          "Copy to Clipboard",
          icon = icon("copy"),
          text = "No Text Found",
          class = "btn-primary",
          modal = TRUE
        )

      )
    )

  })

  observe({

    CopyButtonUpdate(session,
                     id = "copybtn",
                     label = "Copy to Clipboard",
                     icon = icon("copy"),
                     text = input$text
    )

  })


  observe({
    req(input$copybtn2)
    CopyButtonUpdate(session,
                     id = "copybtn2",
                     label = "Copy to Clipboard",
                     icon = icon("cut"),
                     text = input$text2
    )

  })

  observe({
    req(input$copybtn3)
    CopyButtonUpdate(session,
                     id = "copybtn3",
                     label = "Copy to Clipboard",
                     icon = icon("copy"),
                     text = input$text3,
                     modal = TRUE
    )
  })



}

shinyApp(ui = ui, server = server)
Spread the Word!
Share
Related Posts
About Author:

Deepanshu founded ListenData with a simple objective - Make analytics easy to understand and follow. He has over 10 years of experience in data science. During his tenure, he has worked with global clients in various domains like Banking, Insurance, Private Equity, Telecom and Human Resource.

0 Response to "shinyCopy2clipboard : Copy to Clipboard in Shiny Apps"

Post a Comment

Next → ← Prev
Love this post? Support Us!
Buy Me A Coffee