0

I have form that collect datas when SAVE button is pressed from three inputs. First two is already loaded on the site, but last appears when DVD-disk is selected in <select>. So PHP code see values from first two inputs, but not from the last one. I added name and id to all of them. Inputs are in the main container that is in form.

Expected output: echo ($DVDdisk) show data

Real output: Undefined index: DVDsize

let selector = document.getElementById("selector");

let main = document.getElementById("input-main-add");

let div = document.createElement('div');

let h2 = document.createElement('H2');

let input = document.createElement('input');

selector.addEventListener("change", (e) => {
  if (selector.value == "DVD") {
    div.classList.add('input-add-holder');
    main.appendChild(div);
    h2.textContent = 'Enter size:';
    h2.style.display = 'inline-block';
    div.appendChild(h2);
    input.setAttribute("name", "DVDsize");
    input.setAttribute("id", "DVDsize");
    div.appendChild(input);
  }
});
<form method="POST" action="add.php">
  <button class="accept-btn" type="submit">SAVE</button>
  <!-- + -->
  <button class="decline-btn">CANCEL</button>
  <!-- + -->
  </div>
  </div>
  <div class="input-main-add" id="input-main-add">
    <!-- + -->
    <div class="input-add-holder">
      <H2 style="display:inline-block">SKU: </H2>
      <input class="something" name="SKU" id="SKU"></input>
    </div>
    <div class="input-add-holder">
      <H2 style="display:inline-block">Name: </H2>
      <input class="something" name="name" id="name"></input>
    </div>
    <div class="input-add-holder">
      <H2 style="display:inline-block">Type Switcher: </H2>
      <select name="selector" id="selector">
        <option value="DVD" id="DVD" name="DVD">DVD-Disk</option>
        <option value="book" id="book" name="book">Book</option>
        <option value="furniture" id="furniture" name="furniture">Furniture</option>
      </select>
    </div>
  </div>
</form>

PHP code:

<?php
    $SKU = $_POST["SKU"];
    $name = $_POST["name"];
    $DVDsize = $_POST["DVDsize"];
    echo ($SKU);
    echo ($name);
    echo ($DVDsize);
?>
Barmar
  • 741,623
  • 53
  • 500
  • 612
OneCupOfTea
  • 5
  • 1
  • 3
  • 1
    It looks like it should work. If you check the Payload in the Network tab, do you see it sending DVDsize? – Barmar Apr 05 '22 at 17:39
  • what's the output of print_r($_POST)? – Kolja Apr 05 '22 at 17:42
  • Why don't you just put the `DVDSize` input in the original HTML? Then just hide or show it depending on the selection. – Barmar Apr 05 '22 at 17:48
  • 1
    The input `DVDsize` did not send to the server because it's need **Type Switcher** to be change to **DVD**. You have selected **DVD-Disk** by default so the change event did not happens. You have to manually [trigger change event](https://stackoverflow.com/a/28324400/128761) on select box. See `select.dispatchEvent(new Event('change'));` from answer in the link. – vee Apr 05 '22 at 17:48
  • so u have input a val in `DVDSize` after re-select `Type = DVD` ? but PHP side still echo undefine index ? – WolfCode Apr 05 '22 at 18:11

1 Answers1

1

Your JS listen for change event on Type Switcher select box that the selected value must be DVD-Disk but your default value of this select box is DVD-Disk which is already selected.

So, this event will never happens when you just load the page, fill form (without change select box) and submit.
If this event never happens, it means input name DVDSize will not rendered and not send to server. That's why your PHP doesn't see this input.

You have to manually trigger change event for select box once DOM ready.

let selector = document.getElementById("selector");

let main = document.getElementById("input-main-add");

let div = document.createElement('div');

let h2 = document.createElement('H2');

let input = document.createElement('input');

selector.addEventListener("change", (e) => {
  if (selector.value == "DVD") {
div.classList.add('input-add-holder');
main.appendChild(div);
h2.textContent = 'Enter size:';
h2.style.display = 'inline-block';
div.appendChild(h2);
input.setAttribute("name", "DVDsize");
input.setAttribute("id", "DVDsize");
div.appendChild(input);
  }
});


// manually trigger change event.
let selectTypeSwitcher = document.getElementById('selector');
if (selectTypeSwitcher) {
    selectTypeSwitcher.dispatchEvent(new Event('change'));
}
<form method="POST" action="add.php">
  <button class="accept-btn" type="submit">SAVE</button>
  <!-- + -->
  <button class="decline-btn">CANCEL</button>
  <!-- + -->
  </div>
  </div>
  <div class="input-main-add" id="input-main-add">
    <!-- + -->
    <div class="input-add-holder">
      <H2 style="display:inline-block">SKU: </H2>
      <input class="something" name="SKU" id="SKU"></input>
    </div>
    <div class="input-add-holder">
      <H2 style="display:inline-block">Name: </H2>
      <input class="something" name="name" id="name"></input>
    </div>
    <div class="input-add-holder">
      <H2 style="display:inline-block">Type Switcher: </H2>
      <select name="selector" id="selector">
        <option value="DVD" id="DVD" name="DVD">DVD-Disk</option>
        <option value="book" id="book" name="book">Book</option>
        <option value="furniture" id="furniture" name="furniture">Furniture</option>
      </select>
    </div>
  </div>
</form>

Run the code above while open network inspector and you will see DVDSize input send to the server.

vee
  • 4,506
  • 5
  • 44
  • 81
  • It works here, but not in my side. I don't know why. When I edit something in css and after that refreshing my page, nothing happens.Works only with Ctrl + Shift + R hotkey. I'm using XAMPP. – OneCupOfTea Apr 06 '22 at 12:06
  • @OneCupOfTea Make sure that manual trigger is working [when Dom content is loaded](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event). Try to do some `console.log('message')` before `dispatchEvent()` to see that script was called or not. – vee Apr 06 '22 at 15:06
  • @OneCupOfTea CTRL+Shift+R is force refresh the page, that means your JS, CSS file did not load the new one but cached one. You have to add something to that in the URL. For example: from currently you maybe using `myscript.js` now add some querystring like this `myscript.js?update=20220407`. Do the same with CSS. – vee Apr 06 '22 at 18:33