【JS】ラジオボタンでブロックの開閉を制御するスクリプトをjQueryで組んでみた
2018/02/06
大きいブロックが十数個並ぶようなページで、それぞれのブロックの頭にラジオボタンを置き、その選択値によってブロックを開閉するスクリプトが必要になったので、例によってjQueryで組んでみました。
ラジオボタン制御によるブロック開閉スクリプト
CakePHP2によって生成されたブロックのHTML
「調査」と銘打たれたブロックと、同じく「幹線」のブロックを作成。
「調査」及び「幹線」のラジオボタンのname、id、labelタグのforがCakePHPの書式になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div class="blockHeader"> 調査ブロック <input type="radio" name="data[Request][checkup]" id="RequestCheckup1" value="1" required="required" /><label for="RequestCheckup1">開く</label> <input type="radio" name="data[Request][checkup]" id="RequestCheckup0" value="0" required="required" checked="checked" /><label for="RequestCheckup0">閉じる</label> </div> <article id="request_checkup" class="close"> <!-- ブロック中身(省略) --> </article> <div class="blockHeader"> 幹線 <input type="radio" name="data[Request][trunkline]" id="RequestTrunkline1" value="1" required="required" /><label for="RequestTrunkline1">開く</label> <input type="radio" name="data[Request][trunkline]" id="RequestTrunkline0" value="0" required="required" checked="checked" /><label for="RequestTrunkline0">閉じる</label> </div> <article id="request_trunkline" class="close"> <!-- ブロック中身(省略) --> </article> |
実際に作成したソースとは若干異なりますが、大体こんな感じのHTMLソースになりました。
ここではモデルが「Request」となっていますが、他のモデルでも使えるよう引数でモデル、アクションを渡して使えるようにする必要があります(面倒)。
あと、ブロックを整形している articleタグの id名が「request_checkup」と小文字になっています。
「Request_checkup」という形がとれれば良かったのですが、CSSのID名、クラス名には大文字を使うなという指令だったのでこの形になりました。
なお、ラジオボタンのIDは大文字が混ざっていますが、これはCakePHPで機械的に作成しているため、まけてもらっている結果です(苦笑)
HTMLで読み込み
前後しますが、スクリプトファイルの読み込みと、ページを読み込んだ時の初期動作を指定します。
ファイルは radioToggle.js とし、function名は slideBlockForm() とします。
まずはヘッダに以下を記述
1 2 |
<!-- フォームブロック開閉 --> <script type="text/javascript" src="/js/radioToggle/radioToggle.js"></script> |
引数の設定と送信
2行1セットのスクリプトをブロックの数だけHTMLページの最後の方に記述します。
1 2 3 4 5 6 7 8 9 10 |
<script> // "調査"開閉 $(document).ready(slideBlockForm({data:{model:"Request", action:"checkup"}})); $("[name='data[Request][checkup]']:radio").click({model:"Request", action:"checkup"}, slideBlockForm); // "幹線"開閉 $(document).ready(slideBlockForm({data:{model:"Request", action:"trunkline"}})); $("[name='data[Request][trunkline]']:radio").click({model:"Request",action:"trunkline"}, slideBlockForm); </script> |
3行目、$(document).ready で始まる行は「ページを読み込んだ時に slideBlockForm() を実行する」という内容です。
4行目は「ラジオボタンをクリックした時に slideBlockForm() を実行する」という内容です。
それぞれの slideBlockForm() のカッコの中が引数となりますが、
上は {data:{model:"Request", action:"checkup"}}
下が {model:"Request", action:"checkup"}
と、内容が異なります。
これは、下の行で使っている .click()メソッドが原因というか、理由。
.click()メソッドを用いてデータを渡した場合、データは自動的にイベントオブジェクトのdataプロパティ経由で渡されるからです。
「dataプロパティ経由で渡される」というのが意味不明だったのですが、渡ってきたデータオブジェクトを console.log() してみたらなんとなく分かりました。
PHPでいうところの、2次元配列のような形で渡ってきているだけのことでした。
PHP風に書くならばこんな感じ。
1 2 |
$eo['data']['model']; $eo['data']['action']; |
なので、上の行で用いる引数は {data:{model:"Request", action:"checkup"}} と、dataの配下にセットしています。
ブロック開閉スクリプト
では最後に、ブロック開閉のスクリプト。
ブロックの開閉なので、slideDown、slideUp、slideToggle 辺りを使えばそう難しくなく出来上がると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function slideBlockForm( eo ) { // "model"取得 modelStr = eo.data.model; modelStrLowerCase = modelStr.toLowerCase(); // 小文字化 // "action"取得 actionStr = eo.data.action; // 一旦、フォーム全体を非表示化 $("article#"+modelStrLowerCase+"_"+actionStr+".close").hide(); // ラジオボタンの選択値でフォーム全体の表示/非表示を操作 var num = $("[name='data["+modelStr+"]["+actionStr+"]']:checked").val(); if ( num == 1 ){ $("#"+modelStrLowerCase+"_"+actionStr).slideDown("fast"); } else { $("#"+modelStrLowerCase+"_"+actionStr).slideUp("fast"); } } |
軽く説明すると、「eo」という引数(イベントオブジェクト)を取得し、それらを分解して、[Model][action]という、ラジオボタンのname、label名と同じ名前を作りDOMを制御する、という事をしています。
一行一行はさほど難しいことはしていませんが、引数が若干ややこしく、ここに至るまでには紆余曲折がありましたが、なんとか形になりました。