0

I have a javascript form.

I need to make sure that when I select a specific item from the drop-down menu, I have an additional input.

I tried to do it via addEventListener, but so far I have no result.

In the code, this place is located after the comment: "Creating a drop-down menu with prices, transferring data to the form"

What could I have done wrong? How can the error be corrected?

let buttons = document.querySelectorAll('.buy_product_form');
  buttons.forEach(el => {
    el.addEventListener('click', e => {
      let button = e.target;
      let atr = button.dataset.title;
        let id = button.dataset.id;
        let options = button.dataset.options;
        let price = button.dataset.price;
        let item_id = button.dataset.item-id;
        let item = button.dataset.item;
        button.id = id;
 
        /*Creating tag*/
        ......
        ......
        ......
 
        /* Creating a drop-down menu with prices, transferring data to the form */
        if (options !== null) {
          options = JSON.parse(options);
          var select = document.createElement('select');
          select.addEventListener('change', function (e) {
            if('this.options[this.selectedIndex].value' == 0) {
              let input = document.createElement('input');
              this.insertAdjacentElement('afterEnd', input);
            }
          });
          select.id = 'price';
          select.name = 'option_id';
          select.required = true;
 
          for (var prop in options) {
            var option = document.createElement("option");
            option.text = options[prop].name + ' за ' + options[prop].value + ' руб.';
            option.value = options[prop].option_id;
            select.appendChild(option);
          }
          _form.appendChild(select);
 
        /* Hide the dropdown menu */
        } else {
          .........
 
        /* Creating the rest of the form elements */
        var input = document.createElement('input');
        input.id = 'item_id';
        input.type = 'hidden';
        input.name = 'item_id';
        input.value = item_id;
        _form.appendChild(input);
 
        var input = document.createElement('input');
        input.id = 'item';
        input.type = 'hidden';
        input.name = 'item';
        input.value = item;
        _form.appendChild(input);
 
        _form.innerHTML += "\n <div>\n <input class='btn-gray' type=\"submit\" value=\"\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C\" />\n </div>\n <p id=\"req_form\"></p>\n ";
      var pop = new Modal('#' + button.id, _form, function () {
          var name = new Input_Validation('name', /./, 'Это обязательное поле.');
          var email = new Input_Validation('email', /.+@.+\..+/i, 'Это обязательное поле.', 'Укажите действительный адрес электронной почты!');
          var price = new Input_Validation('price', /./i, 'Это обязательное поле.', 'Укажите вариант!');
          var phone = new Input_Validation('phone', /^(\s*)?(\+)?([- _():=+]?\d[- _():=+]?){10,14}(\s*)?$/, 'Это обязательное поле.');
      });
    });
  });

Version 2(Edit 1)

I made all the creation of the form from the start, now all elements are created dynamically.

What is wrong with my addEventListener function?

  let buttons = document.querySelectorAll('.buy_product_form');
  buttons.forEach(el => {
    el.addEventListener('click', e => {
      let button = e.target;
      let atr = button.dataset.title;
        let id = button.dataset.id;
        let options = button.dataset.options;
        let price = button.dataset.price;
        let item_id = button.dataset.item-id;
        let item = button.dataset.item;
        button.id = id;

        /*Creating tag*/
        .........

        /*Creating name field*/
        var _item1 = document.createElement('div');
        _item1.className = 'item';
        _form.appendChild(_item1);

        var _inputName = document.createElement('input');
        _inputName.placeholder = "Ваше имя";
        _inputName.required = true;
        _inputName.type = "text";
        _inputName.name = "name";
        _inputName.id = "name";
        _item1.appendChild(_inputName);

        var _reqNameDiv = document.createElement('div');
        _reqNameDiv.id = "req_name";
        _item1.appendChild(_reqNameDiv);

        /*Creating Email field*/
        ...............
        /*Creating Phone field*/
        .............
        /* Creating a drop-down menu with prices, transferring data to the form */
        if (options !== null) {
          options = JSON.parse(options);
          var select = document.createElement('select');
          select.id = 'price';
          select.name = 'option_id';
          select.required = true;

          for (var prop in options) {
            var option = document.createElement("option");
            option.text = options[prop].name + ' за ' + options[prop].value + ' руб.';
            option.value = options[prop].option_id;
            select.appendChild(option);
          }
          _form.appendChild(select);
          
          select.addEventListener('change', function (e) {
            if(this.options[this.selectedIndex].value == 0) {
              let input = document.createElement('input');
              input.placeholder = "Своя цена";
              input.type = "number";
              input.name = "your_rice";
              input.id = "your_price";
              _form.appendChild(input);
              // this.insertAdjacentElement('afterEnd', input);
            }
          });

        /* Hide the dropdown menu */
        } else {
        ................

        /* Creating the rest of the form elements */
        var input = document.createElement('input');
        input.id = 'item_id';
        input.type = 'hidden';
        input.name = 'item_id';
        input.value = item_id;
        _form.appendChild(input);

        var input = document.createElement('input');
        input.id = 'item';
        input.type = 'hidden';
        input.name = 'item';
        input.value = item;
        _form.appendChild(input);

        var _buttonDiv = document.createElement('div');
        _form.appendChild(_buttonDiv);

        var _button = document.createElement('input');
        _button.className = "btn-gray";
        _button.type = "submit";
        _button.value = "Отправить";
        _buttonDiv.appendChild(_button);

        var _reqForm = document.createElement('p');
        _reqForm.id = "req_form";
        _form.appendChild(_reqForm);

        var pop = new Modal('#' + button.id, _form, function () {
            var name = new Input_Validation('name', /./, 'Это обязательное поле.');
            var email = new Input_Validation('email', /.+@.+\..+/i, 'Это обязательное поле.', 'Укажите действительный адрес электронной почты!');
            var price = new Input_Validation('price', /./i, 'Это обязательное поле.', 'Укажите вариант!');
            var phone = new Input_Validation('phone', /^(\s*)?(\+)?([- _():=+]?\d[- _():=+]?){10,14}(\s*)?$/, 'Это обязательное поле.');
      });
    });
  });
  • `if('this.options[this.selectedIndex].value' == 0)` Well this will always be false, what is it your trying to do here? – Keith Jun 14 '21 at 08:23
  • `_form.innerHTML += ...` recreates all the previously created elements, but doesn't re-attach the events added with `addEventListener`. Also, attaching events to elements collected by `document.querySelectorAll('.buy_product_form');` doesn't add events to the elements which don't exist at the time the iteration is executed. – Teemu Jun 14 '21 at 08:25
  • 1
    Also for dynamically added elements, it's usually better to do event delegation. eg. -> https://developer.mozilla.org/en-US/docs/Web/API/Event/target As you can see in the link, just the 1 event is attached to a UL, and the LI's are left alone, if later another LI is then added dynamically it will also work. – Keith Jun 14 '21 at 08:30
  • @Keith I trying to get select element with value = 0 – Александр Сучков Jun 14 '21 at 09:03
  • @Teemu How can I fix this in my case? – Александр Сучков Jun 14 '21 at 09:08
  • 1
    Use event delegation as Keith has suggested, and either create all the rest of the elements dynamically (like you've already created elements), or use [insertAdjacentHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML) instead of setting `innerHTML`. – Teemu Jun 14 '21 at 09:11
  • @Teemu I make an edit to the form, but my AddEventListener won't work still, how can I makу event delegation in my case? – Александр Сучков Jun 14 '21 at 15:37
  • 1
    Take a look at https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation – Teemu Jun 14 '21 at 15:44
  • @Teemu Thank You now all working But when I change my option on any of them I have another input field, how can I stop it? I need to input release when I have option value equal zero only – Александр Сучков Jun 14 '21 at 16:27

0 Answers0