Karthik
Karthik

Reputation: 31

Populate textbox based on Dropdown selection - JS

Here am not able to add text inside the text box based on the dropdown selection.

example: If I Choose option2 in the dropdown the textbox will filled as option2

(function() {
    'use strict';
    setInterval(function () {
            if (document.getElementById('ddid')) {
                console.log('Found Tag dropdown button');
                return;
            }
            var widgetcontentwrapper = document.getElementsByClassName('widget-content-wrapper');
            if (widgetcontentwrapper.length > 0) {
                console.log('Found widgetcontentwrapper controls');
                var buttonToolbar = widgetcontentwrapper[0].children[0];

                //Create array of options to be added
                var array = ["option1", "option2", "option3", "option4"];

                //Create and append select list
                var selectList = document.createElement("select");
                selectList.setAttribute('class', 'ddclass');
                selectList.setAttribute('id', 'ddid');
                //myParent.appendChild(selectList);
                selectList.addEventListener('change', favTutorial, false);

                var div = document.createElement('div');
                div.setAttribute('class', 'flex-item');
                div.appendChild(selectList);
                buttonToolbar.insertBefore(div, buttonToolbar.firstChild);

                for (var i = 0; i < array.length; i++) {
                    var option = document.createElement("option");
                    option.value = array[i];
                    option.text = array[i];
                    selectList.appendChild(option);
                }
            }
        },
        3000)

    function favTutorial() {
        var mylist = document.getElementsByClassname("ddclass");
        document.getElementsByClassname("input-large").value = mylist.options[mylist.selectedIndex].text;
    }
}
)()
<div class="widget-content-wrapper">
          <div class="arrow"></div>
          <form class="input-compressed"><fieldset>
              <legend class="offscreen">
                Add a Tag
              </legend>
              <div class="editable-field-change">
                <span class="input-append input-smaller"><input class="input-large" data-link="proposedTag" placeholder="Add a tag (any text)..." size="16" type="text">
</span>
              </div>
              <div class="tags">
                <ul class="unstyled editable-list inline-list"></ul>
              </div>
            </fieldset></form>
        </div>

Upvotes: 2

Views: 35

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

There's two problems here. Firstly, the method is getElementsByClassName(), not getElementsByClassname() - note the uppercase 'N'.

Secondly, that method returns an array-like object, not a single Element object. Therefore you can't call value or options on it directly. Given that there's only 1 instance of the element in the question you can just use [0] to access the first element in the set.

(function() {
  'use strict';

  setInterval(function() {
    if (document.getElementById('ddid')) {
      console.log('Found Tag dropdown button');
      return;
    }
    
    var widgetcontentwrapper = document.getElementsByClassName('widget-content-wrapper');
    if (widgetcontentwrapper.length > 0) {
      var buttonToolbar = widgetcontentwrapper[0].children[0];

      //Create array of options to be added
      var array = ["option1", "option2", "option3", "option4"];

      //Create and append select list
      var selectList = document.createElement("select");
      selectList.setAttribute('class', 'ddclass');
      selectList.setAttribute('id', 'ddid');
      //myParent.appendChild(selectList);
      selectList.addEventListener('change', favTutorial, false);

      var div = document.createElement('div');
      div.setAttribute('class', 'flex-item');
      div.appendChild(selectList);
      buttonToolbar.insertBefore(div, buttonToolbar.firstChild);

      for (var i = 0; i < array.length; i++) {
        var option = document.createElement("option");
        option.value = array[i];
        option.text = array[i];
        selectList.appendChild(option);
      }
    }
  }, 3000)

  function favTutorial() {
    var mylist = document.getElementsByClassName("ddclass")[0];
    document.getElementsByClassName("input-large")[0].value = mylist.options[mylist.selectedIndex].text;
  }
})()
<div class="widget-content-wrapper">
  <div class="arrow"></div>
  <form class="input-compressed">
    <fieldset>
      <legend class="offscreen">
        Add a Tag
      </legend>
      <div class="editable-field-change">
        <span class="input-append input-smaller"><input class="input-large" data-link="proposedTag" placeholder="Add a tag (any text)..." size="16" type="text">
</span>
      </div>
      <div class="tags">
        <ul class="unstyled editable-list inline-list"></ul>
      </div>
    </fieldset>
  </form>
</div>

That being said, your code is doing some very odd things. Why do you repeatedly try and create the select element, and exiting from the function when it already exists after the first iteration?

I would assume from the context that this is a rudimentary method of checking the DOM to see if a dynamic element has been created from some external source. If this is the case, use a MutationObserver instead.

Also, avoid generating HTML in your JS code. Put it in <template /> elements and clone it. This way there is never any HTML logic within the JS.

Here's a full working example of this:

(function() {
  'use strict';

  // define MutationObserver to check the DOM for new .widget-content-wrapper elements being created
  var newWidgetContainerObserver = new MutationObserver(mutations => {
    mutations.forEach(m => {
      m.addedNodes.forEach(n => {
        if (n.className === 'widget-content-wrapper')
          createSelectForWidget(n);
      });
    });
  });
  newWidgetContainerObserver.observe(document, { attributes: false, childList: true, characterData: false, subtree: true });

  let widgetContainer = document.querySelector('#widget-container');

  // when a new .widget-content-wrapper node is added to the DOM by external
  // code, append the select to it.
  let createSelectForWidget = node => {
    let selectTemplate = document.querySelector('#dd-template').content.cloneNode(true);
    let container = node.querySelector('.arrow');
    let html = container.appendChild(selectTemplate);
    container.addEventListener('change', favTutorial);
  }

  // event handler for the dynamically created select element, which sets 
  // the value of the related input 
  let favTutorial = e => {
    let select = e.target;
    let container = select.closest('.widget-content-wrapper');
    container.querySelector('.input-large').value = select.value;
  }

  // only for this demo, generates content on button click - mocking the  
  // external process which is updating your DOM
  document.querySelector('#test').addEventListener('click', e => {
    let widgetClone = document.querySelector('#widget-template').content.cloneNode(true);
    widgetContainer.appendChild(widgetClone);
  });
})()
<button id="test">Test - dynamically append new widget</button>

<div id="widget-container"></div>

<template id="widget-template">
  <div class="widget-content-wrapper">
    <div class="arrow"></div>
    <form class="input-compressed">
      <fieldset>
        <legend class="offscreen">Add a Tag</legend>
        <div class="editable-field-change">
          <span class="input-append input-smaller"><input class="input-large" data-link="proposedTag" placeholder="Add a tag (any text)..." size="16" type="text">
  </span>
        </div>
        <div class="tags">
          <ul class="unstyled editable-list inline-list"></ul>
        </div>
      </fieldset>
    </form>
  </div>
</template>

<template id="dd-template">
  <div class="flex-item">
    <select class="ddclass" id="ddid">
      <option value="option1">option1</option>
      <option value="option2">option2</option>
      <option value="option3">option3</option>
      <option value="option4">option4</option>
    </select>
  </div>
</template>

Upvotes: 1

Related Questions