Nemanja
Nemanja

Reputation: 129

Copy to clipboard after success in ajax call, works in Chrome but not in Firefox

I need to get password from server after clicking on a button, I made it work in Chrome but for some reason it's not working in Firefox. I've made it work with async: false but that is not a good practice. Here is my code:

Button

<button class="btn" onClick="copyPassword(el1)">Ip address</button>'

Script

function copyPassword(el1) {
    var id = el1;
    $.ajax({
        type: 'GET',
        url: 'copypassword',
        data: {
            "_token": "{{ csrf_token() }}",
            "id": id
        },
        success: function(msg) {
            copyToClipboard(msg);
        }
    });
}

function copyToClipboard(text) {
    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val(text).select();
    document.execCommand("copy");
    $temp.remove();
}

This works in Chrome without any warnings, but in Firefox i get this document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.

Is there any way I can make it work like this in Firefox?

Upvotes: 1

Views: 2052

Answers (1)

Azer
Azer

Reputation: 1287

The functionality is not the same across browsers. This is quite common in JS/CSS/HTML.

From MDN:

Browser-specific considerations

Section The clipboard and other APIs involved here are evolving rapidly, so there are variations among browsers in how they work.

In Chrome:

You can write to the clipboard like this in all execution contexts - background pages, content scripts, options pages, and popups. You don't actually need "clipboardWrite", even to write to the clipboard outside a user-generated event handler.

In Firefox:

You can write to the clipboard with execCommand in all execution contexts except background pages. In Firefox you can't select text or focus an input field in background pages, so you can't write to the clipboard with execCommand from a background page. The Clipboard Web API doesn't have this limitation. The "clipboardWrite" permission is only supported from version 51 onward. From version 57 onward, you can copy images to the clipboard using the clipboard.setImageData() API. Support for the Clipboard API's navigator.clipboard.writeText() method was added in Firefox 63. When using content scripts, the Clipboard API is available only for HTTPS pages. As a workaround, use messaging between your content scripts and the background script.

The execCommand('copy') API isn't supported in Safari

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard

EDIT:

Example of how to use a textarea to store and copy the value (works in FireFox):

<textarea id="textholder"></textarea>
<button onclick="copyPassword()">Get message</button>
<button onclick="copyToClipboard()">Add to clipboard</button>
var input = $('#textholder');

function copyPassword() {

    $.ajax({
        type: 'GET',
        url: 'https://jsonplaceholder.typicode.com/todos/1',

        success: function(msg) {
            input.val(msg.title);
        }
    });
}


function copyToClipboard() {
    input.select();
    document.execCommand("copy");
}

I use a test API in this example but just replace with your own AJAX info and it should work fine. The example code works as is it, so feel free to test it out. Good luck!

EDIT 2:

Here's a version of the script that only uses one button, as requested by the owner of the question.

In this version the API call is run automatically, so that the user can copy the message with only one click.

<textarea id="textholder"></textarea>
<button onclick="copyToClipboard()">Add to clipboard</button>
    var input = $('#textholder');

    function copyPassword() {

        $.ajax({
            type: 'GET',
            url: 'https://jsonplaceholder.typicode.com/todos/1',

            success: function(msg) {
                input.val(msg.title);
            }
        });
    }


    function copyToClipboard() {
        input.select();
        document.execCommand("copy");
    }

    document.onload = copyPassword();

In firefox the use of execCommand("copy") has to be triggered by a user event, such as a click. It cannot be used in automatically run code, not even if that code dispatches an event that you listen to. It has to be a user action in the browser and not a piece of code that triggers it.

Upvotes: 2

Related Questions