SELECTの連携を今更ながら書いてみた

寺尾で答えてみた
https://teratail.com/questions/310078
なぜか面白くない。
提示されたコードは見難い。なので最初から自分で好きなように書いた方が楽。
汚いコードを指摘してあげるより、私はこれが楽だ。
本当の意味でのショートコーディングは奥が深い。
オブジェクト指向の書き方も奥が深い。


アンカータグの name 属性は無くなっていたのか!知らなかった。
ちょっとだけ賢くなった。

<!DOCTYPE html> 
<html lang="ja">
<meta charset="UTF-8">
<title>連携SELECT</title>
<style>
li > ol {
  margin: 0; padding: 0;
}
</style>
<body>
<ol>
  <li>第一選択肢
    <p>
      <select name="cat1">
        <option value="" selected>選択してください</option>
        <option value="0">a</option>
        <option value="1">b</option>
      </select>
    </p>

  <li>第二選択肢
    <ol>
      <li>
        <select name="cat2">
          <option value="">選択してください</option>
          <option value="0">a-a</option>
          <option value="1">a-b</option>
        </select>
      <li>
        <select name="cat2">
          <option value="">選択してください</option>
          <option value="2">b-a</option>
          <option value="3">b-b</option>
        </select>
    </ol>

  <li>第三選択肢
    <ol>
      <li>
        <select name="cat3">
          <option value="">選択してください</option>
          <option value="1">a-a-a</option>
          <option value="2">a-a-b</option>
        </select>
      <li>
        <select name="cat3">
          <option value="">選択してください</option>
          <option value="3">a-b-a</option>
          <option value="4">a-b-b</option>
        </select>
      <li>
        <select name="cat3">
          <option value="">選択してください</option>
          <option value="5">b-a-a</option>
          <option value="6">b-a-b</option>
        </select>
      <li>
        <select name="cat3">
          <option value="">選択してください</option>
          <option value="7">b-b-a</option>
          <option value="8">b-b-b</option>
        </select>
    </ol>
  
  <li id="cat4">結果
    <ol>
      <li>まだ全て選択されていません</li>
      <li><a href="exp.co.jp#a-a-a">a-a-a</a>
      <li><a href="exp.co.jp#a-a-b">a-a-b</a>
      <li><a href="exp.co.jp#a-b-a">a-b-a</a>
      <li><a href="exp.co.jp#a-b-a">a-b-b</a>
      <li><a href="exp.co.jp#b-a-a">b-a-a</a>
      <li><a href="exp.co.jp#b-a-b">b-a-b</a>
      <li><a href="exp.co.jp#b-b-a">b-b-a</a>
      <li><a href="exp.co.jp#a-a-a">b-b-b</a>
    </ol>
</ol>
<hr>
<ol>
  <li>第一選択肢
    <p>
      <select name="chk0">
        <option value="" selected>選択してください</option>
        <option value="0">a</option>
        <option value="1">b</option>
      </select>
    </p>

  <li>第二選択肢
    <ol>
      <li>
        <select name="chk1">
          <option value="">選択してください</option>
          <option value="http://www.xxx.co.jp#AA">a-a</option>
          <option value="http://www.xxx.co.jp#AB">a-b</option>
        </select>
      <li>
        <select name="chk1">
          <option value="">選択してください</option>
          <option value="http://www.xxx.co.jp#BA">b-a</option>
          <option value="http://www.xxx.co.jp#BB">b-b</option>
        </select>
    </ol>
</ol>

<script>
class A {
  constructor (name) {
    this.name = name;
    this.reg = new RegExp ('^'+ name + '(\\d+)$');
    this.next (document.querySelector (`*[name^="${name}"]`));
  }

  next (e) {
    let r; 
    if (r = this.reg.exec (e.name))
      this.nextStage (this.name + (Number (r[1]) + 1), Number (e.value || "-1"));
  }

  nextStage (name, no) {
    let
      es = document.querySelectorAll (`*[name="${name}"], #${name}>ol>li`),
      n = no < 0 ? 0: no;
    
    es.forEach ((e, i)=> {
      if ('select-one' === e.type) {
        e.disabled = no != i;
        e.selectedIndex = 0;
      }
      let li = e.closest ('li');
      if (li)
        li.style.display = n == i ? 'block': 'none';
    });

    if (es[0])
      this.next (es[0]);
  }

  handleEvent ({target: e}) {
    this.next (e);
  }
}

class B {
  constructor (...select) {
    this.select = select;
  }

  handleEvent ({target: e}) {
    if (this.select.includes (e) && e.value)
      if (confirm (e.value + 'に移動します'))
        location.href = e.value;
  }
}
//_____

document.addEventListener ('change', new A ('cat'), false);
document.addEventListener ('change', new A ('chk'), false);
document.addEventListener ('change', new B (...document.querySelectorAll ('select[name="chk1"]')), false);
</script>