1

I have a table that has some data that when double clicked to select/copy/paste ends up with some white space on either side of the test (could be from some of the other items inside the cell).

My solution is to have a button show the right of the text that copies the text when clicked.(thanks to jon-p, I have the buttons iterated through the cells)

My question is how can I add a function that copies the text of the cell that the new button is in.

Also, I can't edit the page directly so I'm using tampermonkey to inject the code.

http://jsfiddle.net/pshock13/kcvbyq9r/

<table>
<thead>
  <th>Tools</th>
  <th>Shipment</th>
  <th>Barcode</th>
  <th>More Info</th>
</thead>
<tbody>
  <tr>
    <td><span>&#x2714; &#x2718;</span></td>
    <td>
      <div class="relative">
        <a href="something.com/Search?searchKey=123456789">123456789</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <a href="na.something.com/results?s=asdfghjkl">asdfghjkl</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <span>9870356542</span>
      </div>
    </td>
  </tr>
  <tr>
    <td><span>&#x2714; &#x2718;</span></td>
    <td>
      <div class="relative">
        <a href="something.com/Search?searchKey=987654321">987654321</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <a href="na.something.com/results?s=qwertyuiop">qwertyuiop</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <span>asfg456sdfg</span>
      </div>
    </td>
  </tr>
  <tr>
    <td><span>&#x2714; &#x2718;</span></td>
    <td>
      <div class="relative">
        <a href="something.com/Search?searchKey=123456789">123456789</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <a href="na.something.com/results?s=asdfghjkl">asdfghjkl</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <span>9870356542</span>
      </div>
    </td>
  </tr>
  <tr>
    <td><span>&#x2714; &#x2718;</span></td>
    <td>
      <div class="relative">
        <a href="something.com/Search?searchKey=987654321">987654321</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <a href="na.something.com/results?s=qwertyuiop">qwertyuiop</a>
      </div>
    </td>
    <td>
      <div class="relative">
      <span>asfg456sdfg</span>
      </div>
    </td>
  </tr>
</tbody>
</table>

var copyBtn = "<span class='copy' onClick='copyText()'>&#128203;</span>"

var shipmentCells = document.querySelectorAll("tbody tr > td:nth-child(2) > div");
for(var i = 0; i < shipmentCells.length; i++){
  //Append the new element to the innerHTML
  shipmentCells[i].innerHTML += copyBtn;
}
Pshock13
  • 101
  • 6

1 Answers1

1

You can use the GM_setClipboard() function to make this easy.

Important:

  1. Don't use onclick.
  2. Using .innerHTML is also poor practice -- doubly so in a userscript.
  3. When used with @require, there is almost no downside to using jQuery, and a lot of gain in coding ease, speed, and simplicity.

Here's a complete working userscript that adds and activates copy buttons. I added some optional formatting and UI, just for giggles:

// ==UserScript==
// @name     _Add copy buttons to a table
// @match    *://YOUR_SERVER.COM/YOUR_PATH/*
// @match    https://output.jsbin.com/vuyewal
// @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant    GM_addStyle
// @grant    GM_setClipboard
// ==/UserScript==
/* global $ */
/* eslint-disable no-multi-spaces */

//-- Add copy button to column 2:
$("td:nth-child(2) > div.relative").after (`<span class='tmCopyBtn'>&#128203;</span>`);

//-- Style it:
GM_addStyle ( `
    .tmCopyBtn { cursor: pointer; }
    /* Also tweak the div style: */
    td:nth-child(2) > div.relative { display: inline-block; margin-right: 1ex;}

    /* Also add blinker effect for better UI: */
    .justCopied { animation: blinkYellow 1s ease-out 2; }
    @keyframes blinkYellow {
        50% { background-color: yellow; }
    }
` );

//-- Activate it:
$("table").on ("click", ".tmCopyBtn", zEvent => {
    //-- Get text of adjacent <div> and strip leading/trialing whitespace:
    var targetDiv   = $(zEvent.target).prev ("div.relative");
    var textToCopy  = targetDiv.text ().trim ();

    GM_setClipboard (textToCopy, "text/plain");

    //-- Feedback to user:
    $(".justCopied").removeClass ("justCopied");
    targetDiv.parent ().addClass ("justCopied");
} );

Anyone can test it against this target page at JS Bin.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Okay, so this works. Sorta. I have a few tools inside the div with the shipID that cover the copy button when they are hovered. To fix this I used .append instead of .after when creating the button, which works fine until you try to copy using the button. Since it is now inside the div with the text. Found solution: .prev ("a"); on that note, I already have jquery 3.3.1 linked for something else in the project, can i leave just that for this to work properly or do I need both? – Pshock13 Nov 13 '18 at 00:28
  • 1
    If you have already `@require`d jQuery 3.3.1, then that's good enough. If you have added it some other way, then you either need both or to remove the jQ 3.3.1. Your script now runs in a sandbox (a requirement and side effect of `GM_setClipboard`). So it will only see what you `@require`. – Brock Adams Nov 13 '18 at 00:34
  • I have it as @required already. And I already had a .css file for other things as I feel it is just easier than using GM_addStyle. – Pshock13 Nov 13 '18 at 00:36