現在開発している「Custom DataBase Table」のバージョン2にて、先日Bowerで外部アセットのアップデートをしたら、至るところでエラーが出るようになってしまった。

原因は今回バージョン2のユーザインターフェース用のフレームワークとして導入した「Fuel UX」のバージョンアップで「Checkbox」コンポーネントの仕様が変更されたためだ。

今まで3.5.x系で開発していて、今回のアップデートで3.11.xまでバージョンが上がったのだが、公式サイトを確認してみたところ、3.8.0系から「Checkbox」のマークアップ仕様が変更されていた。

Deprecated checkbox markup
Before v3.8.0, the checkbox control could be bound with $().checkbox(); or data-initialize=”checkbox” to the div.checkbox or the input elements. This is no longer supported. Please update your markup and JavaScript to be bound to the label only.

要約すると、3.8より前のバージョンでは $().checkbox();data-initialize="checkbox" の属性を div.checkbox もしくは input タグに追加することでコンポーネントをバインドしていたが、これからは label タグのみへの属性追加する方式しかサポートしません…とのことだ。

──おいおい、そいつはちょいとダメージ大きいですけど。

ちなみに、今までの Fuel UX でのcheckboxのマークアップ仕様は、

<div class="checkbox">
  <label class="checkbox-custom" data-initialize="checkbox">
    <input class="sr-only" data-toggle="#hereKittyKitty" type="checkbox" value="option1">
    <span class="checkbox-label">I love kittens!</span>
  </label>
</div>
<div id="hereKittyKitty" class="alert bg-info">Great. Meow, too!</div>

──となっている。カレントバージョン3.11.xの時点でも、いまだに公式サイトのスタートアップ用テンプレートでは上記のように紹介されている。

まぁ、これでもUI的には問題なく動くのだが、JavaScriptでcheckboxを制御しようと何かメソッドを呼び出すと、エラーが出てしまうのだ。例えば、上記のHTMLに対して、JavaScript側からチェックを入れるような処理を書いてみる。

$(document).ready(function(){
  $('.checkbox').checkbox('check');
});

バージョン3.8より前ではこのやり方が公式ドキュメントで紹介されてて、もちろんこれで問題なく動いていたんだが、今は──

Uncaught TypeError: Cannot read property 'prop' of undefined

──というエラーが出てしまう。

これを回避するためには、JavaScript(jQuery)側のセレクタ部を下記のように <label> タグにマッチするように修正する必要がある。

$(document).ready(function(){
  if ( ! $('.checkbox-custom').checkbox('isChecked') ) {
    $('.checkbox-custom').checkbox('check');
  }
});

つまりは、<div class="checkbox"> によるラッパーに対してのセレクタマッチでは動かなくなるということだ。
まぁ、究極的には <div class="checkbox"> のラッピングも不要になるので、コーディング量が減るし、ソースの可読性も上がるので、仕様変更の路線としては正しいのだが、今までチェックボックス系の値の取得や制御を $('.checkbox') のセレクタで行っていたこともあって影響範囲がかなり大きいのも事実。
特に、今回私が開発しているUIは、管理画面としてチェックボックスが非常に多いため、被害甚大な感じだ…(T_T)

何か簡単に対応できる方法はないものかと、今までのセレクタ構造のままでも動くように、

<label class="checkbox checkbox-custom" data-initialize="checkbox">
  ...
</label>

──とかしてみたら、コンポーネント自体が崩壊した。

やはり、地道にJavaScript側のセレクタ修正を行っていくしかないようだ。

いやはや、何気に開発終了間近だっただけに、かなりトホホ…な事態になってしまったもんだ。

これがオープンソースの恐ろしいところか…(苦笑)