Thursday, 26 October 2023

Writing to the clipboard onChange of a dropdown element in Safari

I'm trying to write text to the clipboard when a user selects an option from a dropdown menu. The following works for all browsers except Safari:

<select onChange="writeTextToClipboard(this.value);">
  <option value="Text I want to copy">Copy to clipboard</option>
</select>

function writeTextToClipboard(value) {
  navigator.clipboard.writeText(value);
}

I understand that Safari expects a Promise to be passed to the write function of the clipboard object, so following this blog post, I modified my code:

async function writeTextToClipboard(value) {
  // Safari, Chrome
  if(typeof ClipboardItem && navigator.clipboard.write) {
    const type = 'text/plain'
    const blob = new Blob([value], {type})
    const cbi = new ClipboardItem({[type]: blob})
    await navigator.clipboard.write([cbi])
    console.log(`Copied: ${value}`)
  }
  // Firefox
  else {
    navigator.clipboard.writeText(value);
  }
}

This still throws a NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission. on Safari and also breaks on Chrome with NotAllowedError: Invalid Blob types. Am I missing something?

I'm on Safari 17.0

UPDATES:

  • I fixed the issue on Chrome, but it still doesn't work on Safari. I've created a fiddle with a minimal example.
  • I also realized that my example works when it's called in the onClick handler of a button instead of onChange of a select element. I clarified my use-case.
  • The only solution I can think of at the moment is to re-build the dropdown menu with something other than a select element and use the onClick event handler on that, but I'd like to avoid that if possible. Using something other than select for a dropdown is likely creating more challenges in the future to keep it working nicely across browsers and different screen sizes.
  • This has been asked before, but the solutions mentioned in that post are using execCommand() which is deprecated and doesn't work either.


from Writing to the clipboard onChange of a dropdown element in Safari

No comments:

Post a Comment