LoginSignup
3
1

More than 5 years have passed since last update.

ES6的に選択したラジオボタンのチェックを外す方法

Last updated at Posted at 2018-10-05
1 / 10

コンパクトにできたので紹介

内容

  • ES6的、選択ラジオボタンのチェック外し
    • アロー関数
    • class
    • static, get
    • const
    • Array.from()
  • ES6でなくても、クロージャ使えばできる
    • 関数型に慣れてる人はそちらでもどうぞ
    • クロージャがクラス定義と実質的に同等(!?)
    • でも、唯一性が担保されない
  • シングルトンまですると楽

実際

<!-- name属性でグループ化されているので -->
<input type="radio" id="A" name="group0">
<input type="radio" id="B" name="group0">
<input type="radio" id="C" name="group0">
class OffRadio {
  constructor(){
    this.onclick = (evt)=>{
      const sender = evt.target;
      const name = sender.name;
      if (this[name] === sender) { // 具体的には、Aがチェック済みならthis.group0 = Aのノード
        this[name] = null;
        sender.checked = false     // クリックイベントが発生したチェックボックスのチェックを外す
      } else {
        this[name] = sender;       // 例えばBをチェックしたらthis.group0 = Bのノード
      }
    }
  }
  static get onclick(){ // クラス定数でシングルトン
    if (!OffRadio.instance){
      OffRadio.instance = new OffRadio()
    }
    return OffRadio.instance.onclick
  }
  static attach(groupName=document.querySelector('input[type="radio"]')){
    Array.from(document.getElementsByName(groupName)).forEach((e)=>{
      e.addEventListener('click', OffRadio.onclick); //イベントを追加  
    })
  }
}

// 使い方
// OffRadioはプログラム中でインスタンス一つだけで良い
// 静的にHTMLに書き下してある要素には
OffRadio.attach()
// 動的に作った要素には
OffRadio.attach('group0')

まれによくある課題

  • チェックを外したいけど外れない
function offRadio(evt){
  if (this.checked == true) { 
      this.checked = false);
    // クリックして呼び出された時点でcheckedプロパティはtrue
    // 従って、クリックしてもチェックされた状態にならない
    // チェックされたけどイベントハンドラ中で常に解除してる状態
  }
}

チェック済を保持する必要あり


<script type="text/javascript">
   // ラジオボタングループ(name)ごとにプロパティを定義、初期化しておく
   var checkedRadioValue = { 'hogehoge': '', 'foo': '' };

   $('input[type="radio"]').on('click', function() {
       var name = $(this).attr('name');
       var value = $(this).val();

       if (checkedRadioValue[name] === value) {
           checkedRadioValue[name] = '';
           $(this).prop('checked', false);
       } else {
           checkedRadioValue[name] = value;
       }
   });
</script>

クロージャにすればいいんちゃう

function offRadio(){
  var checkedRadioValue = {}
  return function(evt){
    var name = this.name;    
    if (checkedRadioValue[name] === this.id) {
        checkedRadioValue[name] = '';
          this.checked = false
    } else {
        checkedRadioValue[name] = this.id;
    }    
  }
}

// 使い方
const off_radio = offRadio();
Array.prototype.filter.call(document.getElementsByTagName("input"), function(e){
  return e.type == "radio"
}).forEach(function(e){
  e.addEventListener('click', off_radio)
})

なんかうまくない

  • しかし、オブジェクトそのものが{}よな...
    • => クラス化すると宣言不要になる
  • クロージャだけでは、引数で持ち回わるハメに
    • 複数のインスタンス必要なし
    • => シングルトン化

ということでクラス化、ところが

  • thisが衝突するやんけ
    • インスタンスのthis=チェック済状態の保持
    • これまでのthis=イベント発生元
      • ということはevt.targetやな
  • シングルトン化はクラス定数で
    • なお、使用する時点まで、newを遅延(getter)
    • freezeしてもいいかもしれないね

最終

class OffRadio {
  constructor(){
    this.onclick = (evt)=>{
      const sender = evt.target;
      const name = sender.name;
      if (this[name] === sender) { // 具体的には、Aがチェック済みならthis.group0 = Aのノード
        this[name] = null;
        sender.checked = false     // クリックイベントが発生したチェックボックスのチェックを外す
      } else {
        this[name] = sender;       // 例えばBをチェックしたらthis.group0 = Bのノード
      }
    }
  }
  static get onclick(){ // クラス定数でシングルトン
    if (!OffRadio.instance){
      OffRadio.instance = new OffRadio()
    }
    return OffRadio.instance.onclick
  }
  static attach(groupName=document.querySelector('input[type="radio"]')){
    Array.from(document.getElementsByName(groupName)).forEach((e)=>{
      e.addEventListener('click', OffRadio.onclick); //イベントを追加  
    })
  }
}

まとめ

  • ES6的、選択ラジオボタンのチェック外し
    • アロー関数
    • class
    • static, get
    • const
    • Array.from()
  • ES6でなくても、クロージャ使えばできる
    • 関数型に慣れてる人はそちらでもどうぞ
    • クロージャがクラス定義と実質的に同等(!?)
    • でも、唯一性が担保されない
  • シングルトンまですると楽

  • 参照情報は本文中に

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1