Part of the code I used to get the screenshot. The @index part need to be taken out.
<% if on_show? %>
<% if field.value.blank? and dash_if_blank %>
—
<% else %>
<div class="flex">
<% if @index.in?([1,5]) %>
<span class="flex-1"><%= content %></span>
<a href="javascript:void(0)" class=" text-xs">
<%= helpers.svg 'heroicons/outline/clipboard', class: "h-4 inline" %> click to copy
</a>
<% end %>
</div>
<% end %>
This is a JS controller we use on avohq.io (on the hero section)
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
static targets = ['trigger']
copy() {
const initialContent = this.triggerTarget.innerHTML
const str = this.context.element.dataset.text
/* ——— Derived from: https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f
improved to add iOS device compatibility——— */
const el = document.createElement('textarea'); // Create a <textarea> element
let storeContentEditable = el.contentEditable;
let storeReadOnly = el.readOnly;
el.value = str; // Set its value to the string that you want copied
el.contentEditable = true;
el.readOnly = false;
el.setAttribute('readonly', false); // Make it readonly false for iOS compatability
el.setAttribute('contenteditable', true); // Make it editable for iOS
el.style.position = 'absolute';
el.style.left = '-9999px'; // Move outside the screen to make it invisible
document.body.appendChild(el); // Append the <textarea> element to the HTML document
const selected =
document.getSelection().rangeCount > 0 // Check if there is any content selected previously
? document.getSelection().getRangeAt(0) // Store selection if found
: false; // Mark as false to know no selection existed before
el.select(); // Select the <textarea> content
el.setSelectionRange(0, 999999);
document.execCommand('copy'); // Copy - only works as a result of a user action (e.g. click events)
document.body.removeChild(el); // Remove the <textarea> element
if (selected) {
// If a selection existed before copying
document.getSelection().removeAllRanges(); // Unselect everything on the HTML document
document.getSelection().addRange(selected); // Restore the original selection
}
el.contentEditable = storeContentEditable;
el.readOnly = storeReadOnly;
const target = this.triggerTarget
target.innerHTML = 'Copied 👌'
target.classList.add('transition', 'opacity-80', 'bg-green-100')
setTimeout(() => {
target.innerHTML = initialContent
target.classList.remove('opacity-80', 'bg-green-100')
}, 1500);
}
}
This can be an option for existing fields ( like text, text_area and some more text related fields) where click_to_copy: true makes that clipboard button appear.
Feature
We'd love to have a Click to copy field option.
Similar PR https://github.com/avo-hq/avo/issues/2771
Current workarounds
Custom field.
Screenshots or screen recordings
Additional context
Part of the code I used to get the screenshot. The
@index
part need to be taken out.This is a JS controller we use on avohq.io (on the hero section)