Search code examples
javascripthtml

Listen on multiple input tags and concatenate inputs to a single output field without need to click a button


With plain JavaScript + HTML, I would like to listen on multiple inputs including a <select>-tag and generate an output text field (which can be copied) without the need to click on a button. If possible, I would like to add the "copy-to-clipboard" sign and functionality to the right of the output text field (e.g. Guthub Pages often provide such a possibility).

Here is the link to fiddle to test and verify what I wrote.

I am looking for:

Some eventListening-mechanic which concatenates input fields to an output string which is displayed and ready to be copied.

function fun() {
  var fn = document.getElementById("fname");
  var ln = document.getElementById("lname");
  var test = document.getElementById("test");
  out = ln.value + "," + fn.value + "," + test.value;
  document.getElementById("out0").innerHTML = out;
  switch (test.value) {
    default: var val = "XXX"
    break;
    case "A":
        var val = "YYY"
      break;
    case "B":
        var val = "ZZZ"
      break;
  }
  document.getElementById("out1").innerHTML = val;
  var text = document.getElementById("textField");
  text.style.display = "block";

}
<label for="fname">First name:</label><br>
<input type="text" id="fname" value=""><br>

<label for="lname">Last name:</label><br>
<input type="text" id="lname" value=""><br><br>

<label for="test">Test</label>
<select id="test">
  <option value="A">AA</option>
  <option value="B">BB</option>
  <option value="C">CC</option>
</select><br><br>
<button class="button" onclick="fun()">Wihtout button?</button>
<div id="textField" style="display: none;"></div>

<span id="out0"></span><br><br>
<span id="out1"></span>


Solution

  • Here is a version using delegation

    Note the copy function itself will not work at SO but will work in a JSFiddle and on your site

    https://jsfiddle.net/mplungjan/hod6svum/

    window.addEventListener('load', () => { // when page loads
      const form = document.getElementById('myForm');
      const textField = document.getElementById("textField");
      const copyButton = document.getElementById("copyButton");
      form.addEventListener('submit', (e) => e.preventDefault()); // stop submission
      copyButton.addEventListener('click', () => {
        const textToCopy = textField.textContent;
        if (textToCopy.trim() === "") return; // nothing to copy
        navigator.clipboard.writeText(textToCopy).then(() => {
          alert('Text copied to clipboard!');
        }).catch(err => {
          console.error('Failed to copy text: ', err);
        });
    
      });
      form.addEventListener('input', (e) => {
        // create the output
        const formData = new FormData(form);
        const output = Array.from(formData.entries()) // Convert to array
          .map(([key, value]) => `${key}: ${value}`) // Format each entry
          .join('\n'); // Join with newlines
        console.log(output)
        textField.textContent = output; // Set the output
      });
    
    })
    .as-console-wrapper { left: auto!important; top: 0; width: 60%; max-height: 157px!important; }
    <form id="myForm">
      <label for="fname">First name:</label><br>
      <input type="text" name="fname" id="fname" value=""><br>
    
      <label for="lname">Last name:</label><br>
      <input type="text" name="lname" id="lname" value=""><br><br>
    
      <label for="test">Test</label>
      <select id="test" name="test">
        <option value="A">AA</option>
        <option value="B">BB</option>
        <option value="C">CC</option>
      </select><br><br>
    </form>
    <div id="textField"></div> <button id="copyButton" type="button" class="button">Copy to clipboard</button>