Create options with Constructor (JavaScript)

Miu Taji :

What I want to know

  1. How to also apply the constructor to DOMs.selectTimes.
  2. More efficient ways to clean up my code

What my code is for

I made a script which creates option elements for HTML forms dynamically. I could apply birthYear/birthMonth/birthDay to a constructor. But I can't do it for selectTimes. How can I do it? OR are there any more efficient ways?


Here is my code

(function() {
  /* Fetch DOMs */
  const DOMs = {
    selectYear: document.querySelector('#select-birthyear'),
    selectMonth: document.querySelector('#select-birthmonth'),
    selectDay: document.querySelector('#select-birthday'),
    selectTimes: document.querySelectorAll('.select-time'),
    selects: document.querySelectorAll('.select')
  };

  /* Create options */
  function createOptions() {
    let html;

    // Create time options
    let arrTimes = [
      '10:00',
      '10:30',
      '11:00',
      '11:30',
      '12:00',
      '12:30',
      '13:00',
      '13:30',
      '14:00',
      '14:30',
      '15:00',
      '15:30',
      '16:00',
      '16:30',
      '17:00',
      '17:30',
      '18:00'
    ];

    DOMs.selectTimes.forEach(selectTime => {
      for (let i = 0; i < arrTimes.length; i++) {
        html = `<option value="${arrTimes[i]}">${arrTimes[i]}</option>`;
        selectTime.insertAdjacentHTML('beforeend', html);
      }
    });

    // Constructor for year/month/day
    function OptionLoop(DOM, start, end, unit) {
      this.DOM = DOM;
      this.start = start;
      this.end = end;
      this.unit = unit;
    }

    OptionLoop.prototype.setOptions = function() {
      for (let i = this.start; i <= this.end; i++) {
        html = `<option value="${i}${this.unit}">${i}${this.unit}</option>`;
        this.DOM.insertAdjacentHTML('beforeend', html);
      }
    };

    // Set year/month/day options
    const birthYear = new OptionLoop(DOMs.selectYear, 1960, 2005, '年');
    const birthMonth = new OptionLoop(DOMs.selectMonth, 1, 12, '月');
    const birthday = new OptionLoop(DOMs.selectDay, 1, 31, '日');

    // Create year/month/day options
    birthYear.setOptions();
    birthMonth.setOptions();
    birthday.setOptions();
  }

  /* Initialize */
  function init() {
    let isEmpty = false

    // Fetch how many options each <select> has
    DOMs.selects.forEach(select => {
      if (select.childElementCount <= 1) {
        return isEmpty = !isEmpty;
      }
    });

    // Implement when each <select> has just one <option>
    if (isEmpty) {
      createOptions();
    }
  }

  /* Implement the function when the window is loaded */
  window.addEventListener('load', init);
})();
<select class="select select-time">
  <option value="" disabled selected>START TIME1</option>
</select>

<select class="select select-time">
  <option value="" disabled selected>END TIME1</option>
</select>

<select class="select select-time">
  <option value="" disabled selected>START TIME2</option>
</select>

<select class="select select-time">
  <option value="" disabled selected>END TIME2</option>
</select>

<select id="select-birthyear" class="select">
  <option value="" disabled selected>YEAR</option>
</select>

<select id="select-birthmonth" class="select">
  <option value="" disabled selected>MONTH</option>
</select>

<select id="select-birthday" class="select">
  <option value="" disabled selected>DAY</option>
</select>

Mister Jojo :

You can simply use custom Elments
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements

class myTime extends HTMLSelectElement {
  constructor() {
    super()
    this.OptTimes = [ '10:00', '10:30', '11:00', '11:30', '12:00', '12:30',
                      '13:00', '13:30', '14:00', '14:30', '15:00', '15:30',
                      '16:00', '16:30', '17:00', '17:30', '18:00' ]
  }
  connectedCallback() {
    if (!this.dataset.range) {
      for (let tim of this.OptTimes ) {
        this.add(new Option(tim, tim))
      }
    }
    else {
      let [start, end, unit] = this.dataset.range.split(' ')

      for(let i=start; i<=end; i++) {
        this.add(new Option(`${i} ${unit}`,`${i} ${unit}`))
      }
    }
  }
  //disconnectedCallback() {}
}
customElements.define('my-time', myTime, {extends: 'select'})
<select is="my-time">
  <option value="" disabled selected>START TIME1</option>
</select>

<select  is="my-time">
  <option value="" disabled selected>END TIME1</option>
</select>

<select is="my-time" data-range="1960 2005 年">
  <option value="" disabled selected>YEAR</option>
</select>

<select is="my-time" data-range="1 12 月">
  <option value="" disabled selected>MONTH</option>
</select>

<select is="my-time" data-range="1 31 日">
  <option value="" disabled selected>DAY</option>
</select>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=31803&siteId=1