5

I have a search form that outputs merchant details (each merchant's name, phone, email address) into a table.
I'm looking to have a copy button next to each one of these fields so users can click on it and copy it to their clipboard (the text gets highlighted when copied). My users will be browsing with IE9 only.

The problem is that there may be more than one set of results, so the script cannot call a specific numbered function like I have done with textarea's below:

function highlightmetasearch01() {
    document.copydata01.text2copy01.select();
     document.copydata01.text2copy01.focus(); 
}
function copymetasearch01() {
    highlightmetasearch01();
    textRange = document.copydata01.text2copy01.createTextRange();
    textRange.execCommand("RemoveFormat");
    textRange.execCommand("Copy");
}

function highlightmetasearch02() {
    document.copydata02.text2copy02.select();
    document.copydata02.text2copy02.focus(); 
}
function copymetasearch02() {
    highlightmetasearch02();
    textRange = document.copydata02.text2copy02.createTextRange();
    textRange.execCommand("RemoveFormat");
    textRange.execCommand("Copy");
}

HTML:

<textarea name="text2copy01">The first textarea.</textarea>
<br />
<button onclick="copymetasearch01();return false;">COPY</button>

<textarea name="text2copy02">The second textarea.</textarea>
<br />
<button onclick="copymetasearch02();return false;">COPY</button>

I was wondering if this would be possible? ...

<td><span>Name from DB here</span> <button onclick="<!--copy and highlight text within most recent span tag-->">COPY</button></td>

<td><span>Phone from DB here</span> <button onclick="<!--copy and highlight text within most recent span tag-->">COPY</button></td>

<td>Other text here that shouldn't be highlighted or copied <span>Email address from DB here</span> <button onclick="<!--copy and highlight text within most recent span tag-->">COPY</button></td>

Or is there a more efficient way to approach this?

Cerbrus
  • 60,471
  • 15
  • 115
  • 132
Zuno
  • 384
  • 1
  • 4
  • 14
  • Forgetting about the practical side, would you like a site to control your clipboard? I would view that site as rude and probably avoid it in future. I would also think that if they are (trying) to do this, what other things are they trying to do without me knowing. – Ed Heal Dec 04 '12 at 19:14

3 Answers3

1

This question:

How do I copy to the clipboard in JavaScript?

...contains a fairly long discussion about copying text to the clipboard with JavaScript. The most upvoted (and in my opinion the correct) answer does not actually do the copying, but makes use of a popup to present a text box with the text already selected, allowing the user to simply CTRL+C to copy.

The reasoning behind this is because for a site to control what is on a user's clipboard can be dangerous and undesirable for the user. Understood that here you are getting the user's permission to do so, but still... If you want to take what the answer in above post suggests and apply it to your site, perhaps include a button which automatically selects the text to copy in the field next to it. For information on selecting text in a field see this post: Programmatically selecting partial text in an input field.

Community
  • 1
  • 1
Levi Botelho
  • 22,763
  • 5
  • 51
  • 94
0

Since it seems like you have the copying method figured out and just need a way to access elements that are dynamically generated, use document.getElementById('text2copy02').createTextRange() instead of document.copydata02.text2copy02.createTextRange(). See the example code below. I hope I understood your problem correctly.

html:

<td><span id="copyMe1">Name from DB here</span> <button onclick="copyMeToClipboard('copyMe1')">COPY</button></td>

<td><span id="copyMe2">Phone from DB here</span> <button onclick="copyMeToClipboard('copyMe2')">COPY</button></td>

js:

function copyMeToClipboard(elementId) {
    document.getElementById(elementId).select();
    document.getElementById(elementId).focus(); 
    textRange = document.getElementById(elementId).createTextRange();
    textRange.execCommand("RemoveFormat");
    textRange.execCommand("Copy");
}
0

I'm going to plug jQuery as a good solution to your problem. I know it's not mentioned in the question, but it makes traversing the DOM tree really easy by letting you use CSS-style selectors. Combine this with a click event handler and you get your "I was wondering if this would be possible?" solution:

// Give your copy buttons the "copier" class
// This will add a click event handler:
$('.copier').click(function() {
    // Find the nearest-parent td to the clicked button:
    var row = $(this).closest('td');

    // Find the first span within that td:
    var txt = row.find('span:first');

    // Do the copying:
    window.clipboardData.setData('Text', txt.text());

    // And the highlighting:
    var range = document.body.createTextRange();
    range.moveToElementText(txt[0]);
    range.select();
});

Now I left the copy and highlight code out (edit: except now I didn't), 'cause it's a little long, but you can find some good (cross-browser) implementations elsewhere on Stack Overflow:

Hope that helps!

Community
  • 1
  • 1
Xavier Holt
  • 13,933
  • 3
  • 40
  • 56
  • Thanks guys, I tried this but it's not working. Sorry I'm a bit of a noob here... – Zuno Dec 04 '12 at 18:34
  • @Zuno - I updated the sample code. Untested, since I don't have IE, but it should work. There were a couple things that would keep copy-n-pasted code from running in those linked examples: The variable `str` doesn't exist for you, and `range.moveToElement()` expects a native DOM node, not its jQuery wrapper (the square brackets unwrap it, so to speak). – Xavier Holt Dec 04 '12 at 19:12
  • Thanks very much but I think I'm being a little stupid here. Changed .copier to .copy and used this HTML with your code above, to no effect: – Zuno Dec 05 '12 at 23:42
  • @Zuno - Hmm. That looks good... Are you sure the buttons already exist when the event-binding script is run? If they don't, move it to the bottom of the file or wrap it in `$(document).ready(function() { /* Do it here! */});` – Xavier Holt Dec 06 '12 at 00:12
  • Am I supposed to be referencing a jquery library here? I ask because I've tried this in almost all possible ways. I've put the script at the top, at the bottom, made it generate when the search results do (at the top and bottom), then changed the script as you suggested and repeated these tests. All of which, upon button click, did nothing. – Zuno Dec 06 '12 at 15:56
  • I've now included jquery using Google's CDN. I can only make the jquery work if I output it with the search results - BUT - by doing this, nothing above the jquery is displayed. I have a search form above the results which behaves like display: none. The HTML for the form is in the source code, but the search results are outputted over it as if it's not there. Tried using both methods you gave. If I place the query at the bottom of the page (static), when searching I get a completely blank page. The jquery is erasing everything above it. – Zuno Dec 06 '12 at 18:02