Search code examples
javascripthtmlformsbrowsertabs

Duplicate Browser Tab Ignores Form Elements Current Values


Issue

When you duplicate a tab in your browser, the current values of form elements are ignored. Tested in the latest versions of Chrome, Firefox and Edge on a Windows 11 computer.

Sample code & demo

var textarea = document.querySelector('textarea');
var p = document.querySelector('p');
var range = document.querySelector('input[type="range"]');
var output = document.querySelector('output');
var checkbox = document.querySelector('input[type="checkbox"]');
var span = document.querySelector('span');
var theme = document.querySelector('select');

function write() {
  p.textContent = textarea.value;
  output.value = range.value;
  span.textContent = checkbox.checked;
  document.body.className = theme.value;
}

textarea.addEventListener('input', write);
range.addEventListener('input', write);
checkbox.addEventListener('change', write);
theme.addEventListener('change', write);

write();
body {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: 1em 0.5em;
}

body.Dark {
  color: white;
  background: black;
}
<textarea>Hello, world!</textarea>
<p></p>
<input type="range">
<output></output>
<input type="checkbox">
<span></span>
<select>
  <option>Light</option>
  <option>Dark</option>
</select>

DEMO

Steps to reproduce the issue

  1. Open the demo page or create your own.
  2. Change the textarea, inputs, and select default values.
  3. Duplicate the tab.

enter image description here

  1. The p, output and span elements don't show the expected text content and the theme is still light.

Question

  1. Why does it happen?
  2. What's the solution?

Solution

    1. Why does it happen?

    Because the form in the browser tab doesn't store current value.


    1. What's the solution?

    Two solutions for solving that:

    1. Using Query Params

    Query params will store the current value as URL Search Params so it can be accessed to refill data when duplicating the browser tab by new URL(document.location).searchParams.

    Code: https://playcode.io/queryparams

    Demo: https://queryparams.playcode.io

    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Duplicate browser tab ignores form elements current values</title>
      <style>
        body {
          display: grid;
          grid-template-columns: repeat(2, max-content);
          gap: 1em 0.5em;
        }
    
        body.Dark {
          color: white;
          background: black;
        }
      </style>
    </head>
    
    <body>
      <textarea>Hello, world!</textarea>
      <p></p>
      <input type="range" />
      <output></output>
      <input type="checkbox" />
      <span></span>
      <select>
          <option>Light</option>
          <option>Dark</option>
        </select>
      <script>
        var textarea = document.querySelector("textarea");
          var p = document.querySelector("p");
          var range = document.querySelector('input[type="range"]');
          var output = document.querySelector("output");
          var checkbox = document.querySelector('input[type="checkbox"]');
          var span = document.querySelector("span");
          var theme = document.querySelector("select");
          let currentParams = new URL(document.location).searchParams;
    
          function createQueryParams() {
            let newParams = new URLSearchParams({
              textarea: textarea.value,
              range: range.value,
              checkbox: checkbox.checked,
              theme: theme.value,
            });
            window.history.pushState("", "", `${location.pathname}?${newParams}`);
          }
    
          function applyQueryParams() {
            textarea.value = currentParams.get("textarea") !== undefined ? currentParams.get("textarea") :  textarea.value;
            range.value = currentParams.get("range") ? currentParams.get("range") : range.value;
            checkbox.checked = currentParams.get("checkbox") ? (currentParams.get("checkbox") == 'true') : checkbox.checked;
            theme.value = currentParams.get("theme") ? currentParams.get("theme") : theme.value;
            write();
          }
    
          function write() {
            textarea.innerHTML = textarea.value;
            p.textContent = textarea.value;
            output.textContent = range.value;
            span.textContent = checkbox.checked;
            document.body.className = theme.value;
            createQueryParams();
          }
    
          textarea.addEventListener("input", write);
          range.addEventListener("input", write);
          checkbox.addEventListener("change", write);
          theme.addEventListener("change", write);
    
          applyQueryParams();
      </script>
    </body>
    
    </html>

    2. Using Session Storage

    Session storage will store the current value as session data so it can be accessed to refill data when duplicating the browser tab by .getItem method.

    Code: https://playcode.io/sessionstorage

    Demo: https://sessionstorage.playcode.io

    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Duplicate browser tab ignores form elements current values</title>
      <style>
        body {
          display: grid;
          grid-template-columns: repeat(2, max-content);
          gap: 1em 0.5em;
        }
    
        body.Dark {
          color: white;
          background: black;
        }
      </style>
    </head>
    
    <body>
      <textarea>Hello, world!</textarea>
      <p></p>
      <input type="range" />
      <output></output>
      <input type="checkbox" />
      <span></span>
      <select>
          <option>Light</option>
          <option>Dark</option>
        </select>
      <script>
        var textarea = document.querySelector("textarea");
          var p = document.querySelector("p");
          var range = document.querySelector('input[type="range"]');
          var output = document.querySelector("output");
          var checkbox = document.querySelector('input[type="checkbox"]');
          var span = document.querySelector("span");
          var theme = document.querySelector("select");
          let currentSession = JSON.parse(sessionStorage.getItem('data')) || {};
          
          function createSessionStorage() {
            let newSession = {
              textarea: textarea.value,
              range: range.value,
              checkbox: checkbox.checked,
              theme: theme.value,
            };
            sessionStorage.setItem('data', JSON.stringify(newSession));
          }
    
          function applySessionStorage() {
            setTimeout(()=>{
              textarea.value = currentSession["textarea"] ? currentSession["textarea"] : textarea.value;
              range.value = currentSession["range"] ? currentSession["range"] : range.value;
              checkbox.checked = currentSession["checkbox"] ? currentSession["checkbox"] : checkbox.checked;
              theme.value = currentSession["theme"] ? currentSession["theme"] : theme.value;
              write();
            },1);
          }
    
          function write() {
            textarea.innerHTML = textarea.value;
            p.textContent = textarea.value;
            output.textContent = range.value;
            span.textContent = checkbox.checked;
            document.body.className = theme.value;
            createSessionStorage();
          }
    
          textarea.addEventListener("input", write);
          range.addEventListener("input", write);
          checkbox.addEventListener("change", write);
          theme.addEventListener("change", write);
    
          applySessionStorage();
      </script>
    </body>
    
    </html>