Copy to clipboard help [Solved]

Hi all

I have a copy to clipboard function working ok, though just not quite how I’d like it. As things stand, if I click the input element, the value is copied.

The problem is, I need another button to copy the text from the input, not sure how to connect the trigger(HIT ME) so when I click this it will copy the input.

Advice on the best approach?
I thought I needed to amend the focus() though not sure what to change.

JS

$(function() {
  $('.copy-to-clipboard input').click(function() {
    $(this).focus();
    $(this).select();
    document.execCommand('copy');
    $(".copied").text("Copied to clipboard").show().fadeOut(1200);
  });
});

HTML

<div class='copied'></div>

<div class="copy-to-clipboard">
  <input readonly type="text" value="Input One">
  <span class="trigger">COPY</span>
</div>

<div class="copy-to-clipboard">
  <input readonly type="text" value="Input Two">
  <span class="trigger">COPY</span>
</div>

JSFiddle example

Thanks, Barry

Instead of defining the function inside click, define it as a variable. (var myclickfunction = function…)
then bind the click events to call that variable. ($(‘theselector’).click(myclickfunction)
As far as the focus, just change $(this) to $(‘thecorrectselector’). Nothing forces you to ‘stay within your element’ so to speak.[EDIT: Ignore this. Read the OP wrong.]

Alternative: Dont bind to the input, bind to the whole div, and then select the input within that div ($(this).find(‘input’))

Cool :sunglasses:
I think this is the sort of thing I’ve been looking for, just not sure how to add this to the code.

Small example?

I thought I would need to:

$('.copy-to-clipboard .trigger').click(function() {
    $(this).focus(); //change this to focus on the input?
...
}

Thanks, Barry

Remove the word “input” from your first selector.
Add “.find(‘input’)” to both of the $(this) statements.
Done.
EDIT: And dont mix your quote marks as i did the first time i posted that.

  $('.copy-to-clipboard').click(function() {
    $(this).find('input').focus();
    $(this).find('input').select();

(I’m not… entirely sure that you need the Focus either.)

1 Like

Good shout :grinning:
Its working, updated fiddle

The updated code, looking good?

$(function() {
  $('.copy-to-clipboard').click(function() {
    $(this).find('input').focus();
    $(this).find('input').select();
    document.execCommand('copy');
    $(".copied").text("Copied to clipboard").show().fadeOut(1200);
  });
});

After much searching today, it seemed like I needed to use the input element to make the copy function work.
Ideally, I was hoping to just copy a href or text within a div to the clipboard.

Wondering if the above approach will still work like this, I might need to hide the input element and copy it while its hidden so my design is not altered.

Will run some more tests now.

Update:

I think your right!

Just ran the below and this seems to work ok.
But I need the select() else does not work.

$(function() {
  $('.copy-to-clipboard').click(function() {
    $(this).find('input');
    $(this).find('input').select();
    document.execCommand('copy');
    $(".copied").text("Copied to clipboard").show().fadeOut(1200);
  });
});

I’ve been working on this all day, you fixed it in 2 minutes :upside_down: :nerd:

Barry

This line does nothing now, you can erase it :wink:

Good to know it’s working!

Cool, just seen your update, thanks.

Last question :sunglasses:

What if I only want the trigger to copy the input?
Else if I click anywhere within the .copy-to-clipboard div the input will always be be copied.

I could have other content within this container.

I tried:
$('.copy-to-clipboard .trigger').click(function() {}

Though this did not work.

Thanks,
Barry

You’re right - I did specifically tailor it to the example you gave me. Narrow answer, because it was the ‘simplest’.

If you’ve got other content in the div, we’re gonna start running into the concept of levels. So, instead of finding downwards, we find UPWARD, and THEN downward.

Let’s assume you only assign “trigger” class to things you want to trigger the copy. (As an aside, You might want a different name, as trigger is a function name in jQuery. It wont -affect- anything, but it may be confusing to type $('.trigger').trigger() at some point in the future.)

I will -assume- that all .trigger elements are somewhere INSIDE .copy-to-clipboard elements.

$('.trigger').click(function () {
 //other stuff
 $(this).closest('.copy-to-clipboard').find('input').select() 

.closest() goes UP the DOM tree, starting at the element (this). Somewhere above that element there is a <div> with the class copy-to-clipboard. So Closest stops and says “Found it! It’s this thing.” Then find receives that, and goes diving back DOWN inside that element’s children to find the input element (note: if you have more than 1 input in the div, change this selector to be more specific.). select() you already know.

1 Like

Perfect! :smile:

Update code:

$(function() {
  $('.copyme').click(function() {
    $(this).closest('.copy-to-clipboard').find('input').select();
    document.execCommand('copy');
    $(".copied").text("Copied to clipboard").show().fadeOut(1200);
  });
});

Updated fiddle

Yes good call, I’ve changed this to copyme

And thanks for the detailed information, really helps :nerd:

Cool, that should wrap things up for now, cheers @m_hutley

1 Like

One last question if you get chance, if not no worries :expressionless:

Instead of copying the input, how would I select and copy the href of a link?

<div class="copy-to-clipboard">
  <a class="abc" href="http://google.com">google.com</a>
  <span class="copyme">COPY</span>
</div>

I tried:

$(function() {
  $('.copyme').click(function() {
    $(this).closest('.copy-to-clipboard').find('.abc').attr('href').select();
    document.execCommand('copy');
    $(".copied").text("Copied to clipboard").show().fadeOut(1200);
  });
});

error:

Uncaught TypeError: $(…).closest(…).find(…).attr(…).select is not a function

Barry

Remember that hidden input idea you had a few posts ago?

$(this).closest('.copy-to-clipboard').find('input').val($(this).closest('.copy-to-clipboard').find('.abc').attr('href')).select();

That… may or may not work, you may need to split up the .val() and the .select().

var target =  $(this).closest('.copy-to-clipboard').find('input');
target.val($(this).closest('.copy-to-clipboard').find('.abc').attr('href'));
target.select();

I’ve just realized what could work.
Tired and tested seems like this could do the job with our current code.

Simply css change:

Hide the input off screen :slight_smile:

.copy-to-clipboard input {
  border: none;
  background: transparent;
  text-indent:-999px
}

I’ll run further tests with this, at least I have a fall back if I can’t get things to work.
I even think just hiding the input could be the best option, in this instance anyhow.

Good stuff!

And thanks for getting back, a productive night :+1:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.