Create a Click-to-Copy Utility With JavaScript
This tutorial is a short guide on creating a click-to-copy utility using simple JavaScript, HTML, and CSS.
The click-to-copy utility has become a popular pattern in the programming world over the years. I have often seen it used by developers to quickly copy API keys, code snippets, numbers, and more.
The onset of this pattern in the more technical space has inspired many modern web websites to implement the same design inside their products to increase their users’ overall experience.
What We Are Building
The click-to-copy utility can take many shapes, but we will use a simple text field and button for this tutorial. Once entered, the value of the text field can be copied to your clipboard by clicking the Click-to-Copy button.
1. Start With the HTML Markup
The HTML components of a click-to-copy utility require some form of user input element. In order words, a text input or text area a user can enter the text within.
As I mentioned, you can optionally have an element with preset text already present, like code snippets.
This tutorial will focus on the user input side of that coin.
1 |
<h1 class="heading">Click-to-copy JavaScript Component</h1> |
2 |
<div class="copy-box"> |
3 |
<input type="text" placeholder="Change me" /> |
4 |
<button>Click-to-Copy</button> |
5 |
</div>
|
We start with straightforward HTML consisting of a text input and a button. A div with a .copy-box
class name wraps the controls so we can target it and its contents with CSS.
2. Styling the Utility With CSS
We can transform the utility into a more usable and better-looking UI with some simple CSS.
You’ll notice a .alert
class in the CSS. This element is for a component we will add dynamically with JavaScript.
When a user enters text inside the input and clicks the Click-to-Copy button, the alert will display at the lower end of the browser viewport and shift to the middle of the screen. We use the calc()
CSS property to leverage math to help determine the proper offset.
1 |
.heading { |
2 |
font-size: 14px; |
3 |
text-align: center; |
4 |
padding-top: 1rem; |
5 |
padding-bottom: 1rem; |
6 |
border-bottom: 1px solid #ddd; |
7 |
line-height: 1.5; |
8 |
background: #f8fafc; |
9 |
margin: 0; |
10 |
}
|
11 |
|
12 |
.copy-box { |
13 |
background: #f9fafb; |
14 |
padding: 10px; |
15 |
border-radius: 6px; |
16 |
border: 1px solid #cbd5e1; |
17 |
width: 400px; |
18 |
margin: 60px auto; |
19 |
display: flex; |
20 |
justify-content: space-between; |
21 |
gap: 1rem; |
22 |
position: relative; |
23 |
}
|
24 |
|
25 |
.copy-box input { |
26 |
color: #475569; |
27 |
border: 1px solid #e5e7eb; |
28 |
border-radius: 6px; |
29 |
padding: 10px 12px; |
30 |
font-size: 16px; |
31 |
flex-grow: inherit; |
32 |
flex: 1; |
33 |
}
|
34 |
|
35 |
.copy-box button { |
36 |
border-radius: 6px; |
37 |
appearance: none; |
38 |
background-color: #1d4ed8; |
39 |
color: white; |
40 |
border: none; |
41 |
padding: 10px 12px; |
42 |
cursor: pointer; |
43 |
}
|
44 |
|
45 |
.alert { |
46 |
position: fixed; |
47 |
bottom: 10px; |
48 |
right: calc(50% - (66px / 2)); /* width of half of alert element */ |
49 |
background: black; |
50 |
color: white; |
51 |
padding: 4px 9px; |
52 |
border-radius: 6px; |
53 |
z-index: 10; |
54 |
font-size: 14px; |
55 |
}
|
3. Invoking the Click-to-Copy Functionality With JavaScript
Okay, number three of our holy trinity.
The Constructor Pattern
To set the code up to be reusable, I favor writing JavaScript classes that make use of a constructor pattern. So we can create a new instance each time we need it and use the same functionality on different click-to-copy utilities that might be required on a given website or web page.
This tutorial assumes you have one on the page, but it can extend to account for multiple utilities should you need to scale it.
I’ll start by creating a custom JavaScript class called ClickToCopy
.
1 |
class ClickToCopy {} |
Knowing we have the button element and the input element to target, I’ll create a constructor function that gives us immediate access to each that might get passed during initialization.
We can then set up a new instance following the class for this tutorial.
1 |
class ClickToCopy { |
2 |
constructor(target, content) { |
3 |
this.target = target |
4 |
this.content = content |
5 |
}
|
6 |
}
|
7 |
|
8 |
const target = document.querySelector("button") |
9 |
const content = document.querySelector("input") |
10 |
const copyHelper = new ClickToCopy(target, content) |
11 |
copyHelper.initialize() |
We need to pass the two instances we reference inside the constructor()
function to use the class.
Using the new
keyword, we create a new instance of the ClickToCopy
and assign it to a variable I made called copyHelper
.
Finally, we can call a function I named initialize()
that we’ll add to the class body next.
1 |
class ClickToCopy { |
2 |
constructor(target, content) { |
3 |
this.target = target |
4 |
this.content = content |
5 |
}
|
6 |
|
7 |
initialize() { |
8 |
this.listenForClick() |
9 |
}
|
10 |
|
11 |
listenForClick() { |
12 |
let self = this |
13 |
this.target.addEventListener("click", (e) => { |
14 |
e.preventDefault() |
15 |
self.copy(self.content.value) |
16 |
})
|
17 |
}
|
18 |
|
19 |
copy(text) { |
20 |
const input = document.createElement("input") |
21 |
input.setAttribute("value", text) |
22 |
document.body.appendChild(input) |
23 |
input.select() |
24 |
let copiedResult = document.execCommand("copy") |
25 |
document.body.removeChild(input) |
26 |
|
27 |
const alert = document.createElement("div") |
28 |
alert.classList.add("alert") |
29 |
alert.textContent = "Copied!" |
30 |
// Customize where you might want to display the alert here
|
31 |
// I chose the broader body element for demonstration purposes
|
32 |
document.body.appendChild(alert) |
33 |
|
34 |
setTimeout(() => { |
35 |
document.querySelector(".alert").style.display = "none" |
36 |
document.body.removeChild(alert) |
37 |
}, 1000) |
38 |
|
39 |
// Optionally reset input contents
|
40 |
this.content.value = "" |
41 |
|
42 |
// Return the result that gets copied to the clipboard
|
43 |
return copiedResult |
44 |
}
|
45 |
}
|
Our 3 ClickToCopy Functions
Inside the ClickToCopy
class, I have added three total functions.
-
initialize()
- a function I like to use to call the bulk of the logic from a given class. -
listenForClick()
- a function responsible for listening for the button click in our utility and also calling a function calledcopy()
. -
copy()
- a function that does the actual logic of the utility.
The copy()
function creates a new text input from scratch because we need to mimic the selection of text and copying of text dynamically. Usually, this is a manual practice, but luckily with JavaScript, you can automate it with some work.
The input gets filled with the content provided in the text input. The text is then selected using the JavaScript select()
method. Finally, that text is copied to the user’s clipboard dynamically, and the new text input that gets generated is removed from the page.
When that logic is complete, we add a new alert element to the view to help the user know the text has indeed been copied to their clipboard. This gets removed after about one second using the setTimeout()
function built into JavaScript.
You can optionally reset the input contents if your design calls for it, and I chose to do so for this tutorial.
Conclusion
Hopefully, this simple yet powerful addition will please your end users by reducing the number of mouse clicks or key commands they need to be more productive on your website.
Let’s remind ourselves what we built: