Search code examples
javascripthtmlfunctionsharepoint-onlinecopy-paste

Copy field to clipboard and keeping all formatting with Javascript


I'm using SharePoint pages and script editor to build a copy button for quick copy/pasting of templates used on SharePoint. The current code I'm using works perfectly except it doesn't copy over for formatting.

For the context of this particular code, I followed these steps to build it.

  1. Create a SharePoint page with a body of text.
  2. Publish the page
  3. Right-click on that page to inspect it using Google's Developer Console (seen here)
  4. Copy the outerHTML for the div that the text field sets in
  5. Pull the DIV ID from that code
  6. Edit the SharePoint Page again (seen here)
  7. Add DIV ID to JavaScript code into Script Editor
  8. Publish page
  9. Copy button works (seen here)

Using the JavaScript code below, I was hoping the copy function would copy over the formatting of the text in the SharePoint field.

Fair warning: I do not know anything about JavaScript. Someone was able to build this code for me, and I only know a little about how the code works outside of what I've displayed here. I don't know where to begin troubleshooting, and when I research other coding, I don't know where to begin with adding modifications to this code. I'm sorry in advance if I need some handholding.

My impression is that there is only a line or two of code, at most, that I can add to the existing code so that it keeps formatting like text size, bold, underline, hyperlinks, etc.

Any help with this would be greatly appreciated.

function myFunction(divId) {
  const copyDiv = document.getElementById(divId);

  if (copyDiv) {
    const textToCopy = copyDiv.innerText;
    navigator.clipboard.writeText(textToCopy)
      .then(() => {
        let tooltip = document.getElementById("myTooltip");
        tooltip.innerHTML = "Copied";
        setInterval(() => {
          tooltip.innerHTML = "Copy Template"
        }, 1000);
      })
      .catch(err => {
        console.error('Could not copy text: ', err);
      });
  } else {
    console.error('Element to copy from could not be found');
  }
}
<div>
  <button onclick="myFunction('2ed477e2-32d7-4f46-a4a9-0a55cdba22f5')" onmouseout="outFunc()">
    <span class="tooltiptext" id="myTooltip">Copy Template</span>
  </button>
</div>


<div class="ControlZone ControlZone--clean a_b_50a7110f" data-automation-id="CanvasControl" id="2ed477e2-32d7-4f46-a4a9-0a55cdba22f5">
  <div class="ControlZone--control">
    <div data-sp-feature-tag="Rich Text Editor" class="rte-webpart rte--ck5 rte--read-ck5 headerFontSizeLegacy" data-sp-feature-instance-id="2ed477e2-32d7-4f46-a4a9-0a55cdba22f5" dir="auto">
      <div data-automation-id="textBox" class="ck-content rteEmphasis root-161 rte-deprecated-styles">
        <div>
          <h2 id="bigger-text">Bigger Text<span class="c_b_1310c973"></span></h2>
          <a class="c_b_1310c973 e_b_1310c973 focusBorder-147" role="link" aria-label="Permalink for Bigger Text" data-sp-anchor-id="bigger-text" href="https://garmin.sharepoint.com/sites/PSSharedSupport-PSCommunityTeam/Architect-Wiki/SitePages/Test-Page.aspx#bigger-text"
            target="_self" style="left: 140px; top: 118px;"><i class="f_b_1310c973 g_b_1310c973 css-146" aria-hidden="true"></i></a>
        </div>
        <p>This is the text field from which the copy button is copied. As of now, it will not copy over formatting like <strong>bold</strong>, <i>italicized</i>, and <u>underlined</u> text formatting.</p>
      </div>
    </div>
  </div>
</div>

Solution

    1. You are getting the innerText of the complete div. That results in ONLY the TEXT of the p is copied.
    2. We need to save both TEXT and HTML as blobs with the mime-types of text and html, then the recipient can choose to paste as text or as formatted text.

    const myFunction = (divId) =>  {
      const copyDiv = document.getElementById(divId);
    
      if (copyDiv) {
        const elementToCopy = copyDiv.querySelector('p'); // otherwise we will copy the whole div
        navigator.clipboard.write([new ClipboardItem({
         'text/plain': new Blob([elementToCopy.innerText], {type: 'text/plain'}),
         'text/html': new Blob([elementToCopy.innerHTML], {type: 'text/html'})
        })])
        .then(() => {
          let tooltip = document.getElementById("myTooltip");
          tooltip.innerHTML = "Copied";
          setInterval(() => {
            tooltip.innerHTML = "Copy Template"
          }, 1000);
        })
        .catch(err => {
          console.error('Could not copy text: ', err);
        });
      } else {
        console.error('Element to copy from could not be found');
      }
    }
    

    Here is what I get in outlook

    enter image description here