もっと便利に!jQueryでラクラクサイト制作(実践サンプル付き)

第15回チェックする項目の選択・未選択を画像でわかりやすくする

チェック項目を選択・未選択のエリアにわける

前回はテキストボックスに入力したパスワードを見えるようにする方法をご紹介しました。

今回ご紹介するのは、チェックボックスをもっと視覚的にわかりやすいようにする方法をご紹介します。選択・未選択をそれぞれの表示域にわける方法です。

選択・未選択の表示域を分ける
選択・未選択の表示域を分ける

仕組みを考える

今回は仕組みから考えてみましょう。

  1. 選択・未選択エリアに同じ数のリストをそれぞれ用意
  2. 最初に表示させるもの以外を非表示に
  3. クリックをしたら、その要素は非表示にし、同じリスト位置(○番目)の要素を表示させる
  4. 選択エリアに入れる場合は同じ位置(○番目)のチェックボックスをチェック状態に、未選択位置に入れる場合はその逆をチェック状態にする

順を追って見ていくことにしましょう。

まずはHTMLを設定します。選択・未選択部分はリストにし、表示は画像で行うことにします。また、フォームの一部ということを想定して、input群だけを入れておくことにします。

使用するHTML

今回のサンプルでは、あらかじめ一つだけはチェック状態にしているところのから作成してみることにします。

HTML
<ul class="add">
<li class="off"><img src="images/A1.png" width="108" height="43" alt="選択A" /></li>
<li class="on"><img src="images/B1.png" width="108" height="43" alt="選択B" /></li>
<li class="on"><img src="images/C1.png" width="108" height="43" alt="選択C" /></li>
<li class="on"><img src="images/D1.png" width="108" height="43" alt="選択D" /></li>
<li class="on"><img src="images/E1.png" width="108" height="43" alt="選択E" /></li>
</ul>

<ul class="delete">
<li class="on"><img src="images/A2.png" width="108" height="43" alt="選択A" /></li>
<li class="off"><img src="images/B2.png" width="108" height="43" alt="選択B" /></li>
<li class="off"><img src="images/C2.png" width="108" height="43" alt="選択C" /></li>
<li class="off"><img src="images/D2.png" width="108" height="43" alt="選択D" /></li>
<li class="off"><img src="images/E2.png" width="108" height="43" alt="選択E" /></li>
</ul>

<input type="checkbox" name="test" value="選択A" checked="checked" />
<input type="checkbox" name="test" value="選択B" />
<input type="checkbox" name="test" value="選択C" />
<input type="checkbox" name="test" value="選択D" />
<input type="checkbox" name="test" value="選択E" />

HTMLを見てもらうとわかると思うのですが、各リストに「on」もしくは「off」のclassをつけています。これはかなり面倒な方法ではありますが、最初に表示させるしないを、わかりやすくするために、HTMLであらかじめ振り分けています。

HTMLをよりシンプルにして作成するのであれば、リスト群のどちらか一方で、振り分けとなるonもしくはoffのどちらかだけをつけて、それを元に他のをスクリプト側で自動でoffなどをつけるほうが効率的ではあります。

今回は、まず最初はあえてその部分はスクリプト側に入れず、HTML側に入れておいて作成することにしました。

実際のサイト制作においてでは、利用する部分が多いようであれば、スクリプト側で自動で振り分けをすべきですが、今回のように、一部でしか利用せず、しかも項目数も少ないような場合、HTML側であらかじめ入れておいても作業量はそれほど変わらないので、まずは手動でHTMLにclassをつけました。

また、⁠off」部分とinputタグ部分を表示させなくする方法も、CSS側で行ってしまうことにします。

CSS
ul li.off , input{
    display:none;
}

これで、現状はHTMLとCSSだけで、表示させてたい部分だけが表示されている状態になります。

スクリプトを考える

続いて次はスクリプトです。先日、jQueryの最新版1.4がリリースされましたので、せっかくなので、今回はその最新版のjQuery1.4を利用してスクリプトを書いていくことにします。

まずは、表示されている部分をクリックしたら動作するようにするようにします。

Script
jQuery(function($){
    $('li','ul').click(function(){
        ○○・・・
    });
});

続いてクリックした要素が、リストの何番目なのかを変数に入れておきます。

.index()
var num = $(this).index();

1.4から.index()のメソッドが使い安くなっており、上記のようなスクリプトで、クリックした位置を確認できます。

次は、クリックした領域ではない方に要素を表示するスクリプトです。同じ位置の要素を表示させるには、下のスクリプトようにします。

$(this).parent().siblings('ul').children().eq(num).show()

このままだとわかりづらいですが、日本語になおしてみると「これ(リスト)の親要素と同階層にあるリスト群の子要素のうちのnum番目の要素を表示させる。」となります。

これにプラスして、クリックした要素を費用時にする必要があるのと、それぞれ「on」「off」のclassを変更するスクリプトも加えます。それらを加えると、先ほどの一行はさらに長くなりますが、下のようになります。

$(this).hide().attr('class','off').parent().siblings('ul').children().eq(num).show().attr('class','on');

あと残りは、選択エリアに入った際のチェックボックスの挙動です。選択エリアに入れた際の同じ位置のinputにchecked属性をつけるようにします。

$('input').eq(num).attr('checked',function(){
     if(this.checked){
         return '';
     } else {
         return 'checked';
     };
});

上記の一行目「.attr」の使い方は1.4からの方法です。属性の値に関数を割り当てられるようになり、より柔軟に値を変化させられるようになっています。今回は、そのinputのchecked属性がすでに入っているかどうかの判定をして、入っているならchecked属性を削除し、入っていないなら追加するという内容になっています。

スクリプトは以上です。これをまとめてみましょう。

ここまでのスクリプトをまとめたもの
jQuery(function($){
     $('li','ul').click(function(){
         var num = $(this).index();
         $(this).hide().attr('class','off').parent().siblings('ul').children().eq(num).show().attr('class','on');
         $('input').eq(num).attr('checked',function(){
             if(this.checked){
                 return '';
             } else {
                 return 'checked';
             };
         });
     });
});

上記のサンプルを試してください。点線より上が未選択、下が選択中のエリアになります。クリックした際に、実際にinputにchecked属性がついているかどうかは、Firebugのコンソールで、下記スクリプトをそれぞれクリックした後に実行してみてください。

checked属性がついたかどうかをFirebugのコンソールで確認する
console.log($('input:checked').length);

選択中のエリアに入っている数だけinputのchecked属性がついているのがわかると思います。

プラグインにする

上記の例では各リストに「on」「off」を書き入れなくてはなりませんでした。数が増えることでマークアップが大変になるので、それらを書かなくとも実行できるようにしてみます。

このプラグインにしてみる際に、利用する際に以下のような条件だけは入れておくこととします。

プラグイン利用の条件

  • 選択・未選択エリアはulでマークアップする。また最初に出てくる方を未選択エリアとする。
  • 最初から選択エリアに入れておくことはできないものとする
  • 2つのul(選択・未選択用の)と、フォーム用のinputをdivなどでまとめる

以上のような条件をつけて利用するようにします。なので、マークアップも少しだけ変えておきます。

HTML
<div class="imgSelect">
<h3>未選択</h3>
<ul>
<li><img src="images/A1.png" width="108" height="43" alt="選択A" /></li>
<li><img src="images/B1.png" width="108" height="43" alt="選択B" /></li>
<li><img src="images/C1.png" width="108" height="43" alt="選択C" /></li>
<li><img src="images/D1.png" width="108" height="43" alt="選択D" /></li>
<li><img src="images/E1.png" width="108" height="43" alt="選択E" /></li>
</ul>

<h3>選択中</h3>
<ul class="delete">
<li><img src="images/A2.png" width="108" height="43" alt="選択A" /></li>
<li><img src="images/B2.png" width="108" height="43" alt="選択B" /></li>
<li><img src="images/C2.png" width="108" height="43" alt="選択C" /></li>
<li><img src="images/D2.png" width="108" height="43" alt="選択D" /></li>
<li><img src="images/E2.png" width="108" height="43" alt="選択E" /></li>
</ul>

<input type="checkbox" name="test" value="選択A" />
<input type="checkbox" name="test" value="選択B" />
<input type="checkbox" name="test" value="選択C" />
<input type="checkbox" name="test" value="選択D" />
<input type="checkbox" name="test" value="選択E" />
</div>

そして、プラグインにするために、スクリプトも変更します。

プラグイン化のスクリプト
(function($){
    $.fn.imgSelect = function(){
        $(this).each(function(){
            $(this).children('ul').eq(1).children().addClass('off').hide();
            $(this).children('ul').first().addClass('on');
            $(this).children('input').hide();
            
            $(this).children().children('li').click(function(){
                var num = $(this).index();
                $(this).hide().attr('class','off').parent().siblings('ul').children().eq(num).show().attr('class','on');
                $(this).parent().siblings('input').eq(num).attr('checked',function(){
                    if(this.checked){
                        return '';
                    } else {
                        return 'checked';
                    };
                });
            });
        });
    };
})(jQuery);

大きな変化はないのですが、自動で二つ目のulの中身を非表示にする内容を加えたり、class名を追加する内容が加えられてあります。

プラグイン化ができたら、実行してみましょう。

jQuery(function($){
     $('.imgSelect').imgSelect();
});

以上で実装できました。いかがだったでしょうか。選択をわかりやすくするためには、表示枠や背景などをもっと工夫する必要もありますが、選択・未選択を画像にしたりすることで、より何を選択しているのかというのをわかりやすくすることができるようになります。

選択中なのか、そうでないのか、わかりやすいUIにするための一例として、このようなのを導入してみてはいかがでしょうか。

おまけサンプル

最後におまけとして、もう一つだけサンプルをご紹介しておきます。

最初のサンプルの改良で、クリックした要素を、それぞれの最後(右端)に移動させて表示するというものです。

特に説明はもうけませんが、こんな方法・見せ方もあるという一例として、参考にしてみて下さい。

おすすめ記事

記事・ニュース一覧