Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert text input to JSON and copy result to clipboard with one button

This code contains two buttons, the first one submits some text to be converted into JSON and the the second one copies the result to the clipboard. It would be great to be able to do both with one click. Is there a way to combine the two so that when I click the submit button the JSON is automatically copied to the clipboard?

<html>
<body>
    
<form id='foobar'>
    <label for='event_name'>Event Name</label>
  <input type="text" id="event_name" name='event_name' value="Concert"/>
    <label for='venue_name'>Venue Name</label>
    <input type="text" id="venue_name" name="venue_name" value="Theater" />
  <input type='submit' />
</form>

<pre id='output'>Input some value and submit</pre>

<script>
    
document.getElementById('foobar').addEventListener('submit', (e) => {
  e.preventDefault();

  const formData = new FormData(e.target);
  const data = Array.from(formData.entries()).reduce((memo, pair) => ({
    ...memo,
    [pair[0]]: pair[1],
  }), {});
  document.getElementById('output').innerHTML = JSON.stringify(data);
});

// Copy button


    function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}

make_copy_button(document.getElementById("output"));

</script>

</body>
</html>
like image 695
jcp543 Avatar asked Dec 19 '25 10:12

jcp543


2 Answers

Yes its possible. You can simply call selectElementContents() function after the innerHTML is applied to the output and then send that element to your function to be able to copy the content on clicking submit button.

In addition, with one button only you do need the other two functions to create button manually. As the results can now achieved with one button which is when you hit submit - The copy Command will be applied to the whole JSON output.

Live Demo:

let output = document.getElementById('output')
document.getElementById('foobar').addEventListener('submit', (e) => {
  e.preventDefault();

  const formData = new FormData(e.target);
  const data = Array.from(formData.entries()).reduce((memo, pair) => ({
    ...memo,
    [pair[0]]: pair[1],
  }), {});
  output.innerHTML = JSON.stringify(data);
  selectElementContents(output) //copy to clipboard
});

// Copy to clipboard
function selectElementContents(el) {
  // Copy textarea, pre, div, etc.
  if (document.body.createTextRange) {
    // IE
    var textRange = document.body.createTextRange();
    textRange.moveToElementText(el);
    textRange.select();
    textRange.execCommand("Copy");
  } else if (window.getSelection && document.createRange) {
    // Non-Internet Explorer
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    try {
      var successful = document.execCommand('copy');
      var msg = successful ? 'successful' : 'unsuccessful';
      console.log('Copy command was ' + msg);
    } catch (err) {
      console.log('Oops, unable to copy');
    }
  }
}
<html>

<body>

  <form id='foobar'>
    <label for='event_name'>Event Name</label>
    <input type="text" id="event_name" name='event_name' value="Concert" />
    <label for='venue_name'>Venue Name</label>
    <input type="text" id="venue_name" name="venue_name" value="Theater" />
    <input type='submit' value="Submit" />
  </form>

  <pre id='output'>Input some value and submit</pre>

</body>

</html>
like image 169
Always Helping Avatar answered Dec 20 '25 22:12

Always Helping


A more concise example:

function copyJsonToClipboard() {
   //Example object
   const data = {
      eventName: "Concert",
      venueName: "Theater"
   };
   //Converting the object to JSON
   const json = JSON.stringify(data);
   //Copying the JSON to the clipboard
   navigator.clipboard.writeText(json);
}

See JSON.stringify and clipboard.writeText.

like image 35
Stanislas Avatar answered Dec 21 '25 00:12

Stanislas