delicious! newsing! buzzurlにブックマーク! Yahoo!ブックマーク ライブドア - この記事をクリップ! このエントリーを含むはてなブックマーク

jQuery :: チェックボックスが並んだテーブルをjQueryでどーこーするサンプル

2009/9/13 (Sun) at 3:40 am

エントリのアイコン

先日、TraversingのアレコレをNettuts+に教わりましたんで、その応用練習ってことで、よくあるテーブルのデザインのサンプルをつくってみました。こういうの↓

http://1-pixel.com/sample/jquery-table/sample.html

cssはhtml内に書かれています。よくあるヤツです。jsはコレです↓

$(function(){
  table();
});

function table(){
  $('tr', '#sample-table')
  .hover(
    function(){
      $(this).addClass('tr-selected');
    },
    function(){
      if(!$('input[type="checkbox"]', this).attr('checked')){
        $(this).removeClass('tr-selected');
      }
    }
  );
  $('tr:odd', '#sample-table')
  .addClass('tr-odd');
  $('#chkAll')
  .toggle(
    function(){
      $('input[type="checkbox"]', '#sample-table')
      .attr('checked', true);
      $(this)
      .html('Uncheck All');
      $('tr', '#sample-table')
      .addClass('tr-selected');        
    },
    function(){
      $('input[type="checkbox"]', '#sample-table')
      .attr('checked', false);
      $(this)
      .html('Check All');
      $('tr', '#sample-table')
      .removeClass('tr-selected');        
    }
  );
  $('tr', '#sample-table')
  .children('td:nth-child(1)')
  .nextAll()
  .click(
    function(){
      var _e = $('input[type="checkbox"][name^="chk"]', $(this).parent().children('td:first'));
      if(_e.attr('checked')){
        _e.attr('checked', false);
        $(this).parent().removeClass('tr-selected');
      }else{
        _e.attr('checked', true);
        $(this).parent().addClass('tr-selected');
      }
    }
  );
}

テーブルの行をクリックするとチェックボックスがONになり、選択されていることがわかりやすいように背景色が変わります。サンプルではiTuneぽいアイコンがチェックボックスの隣にありますが、これはなにかのイベントを呼ぶもんなので、このぶぶんだけ、つまり一番左のtdだけはチェックボックスON/OFFトグルのクリッカブル領域から外したい。<tr>〜</tr>をまとめてどーこーしたいのなら$('tr')でいいわけですが、これは少しむずかしい。

<tr>〜</tr>の中に複数個ある<td>〜</td>の中の、2番目から最後までのtdを複数選択する

としたい。このためにコレ↓

$('tr', '#sample-table').children('td:nth-child(1)').nextAll()

さらにこれらのtdに対してクリックイベントを割り当てます。こんどはtdからみて、チェックボックスを選択するためにコレ↓

$('input[type="checkbox"][name^="chk"]', $(this).parent().children('td:first'))

このthisは、1つのtrにつき5個づつあるtdの中の、2番目以降のどれかです。つまりこのセレクタの意味するところはこうなる↓

「このtdの親要素(つまりtr)の子供たちの中の、1番目のtdの中にある、name属性がchkで始まる、checkboxのinput要素」

てわけです。さいきんこういうのも少しづつ馴れてきました。冗長なかしょがありましたらツッコミよろしく。

delicious! newsing! buzzurlにブックマーク! Yahoo!ブックマーク ライブドア - この記事をクリップ! このエントリーを含むはてなブックマーク

add your comment!
2009/9/13, 4:07 AM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

サンプルのコードが読みにくくてすません。近々ブログのデザインをどうにかしようと思ってます。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2009/9/13, 5:15 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

その後の話。

サンプルにあるようなテーブルをつくったらば、DOMを入れ換えたり削除したりしてテーブルの中身を動的にアレコレしたいじゃないですか。ここでじゃじゃーんと登場するのがjQuery1.3xの新機能であるlive()ですが、なんと、このliveが上のサンプルのヤツだと効かないんですね。

「〜の中に複数個ある〜の中の、2番目から最後までのtdを複数選択する」

のために書いた長ったらしいヤツに対して、click(ナントカ)と書いてたところを、live('click', function(){});てな具合にやればいいかと単純に考えていたんだけど、ためしにやったらだめでした。documentにはこう書かれてある↓

Live events currently only work when used against a selector. For example, this would work: $("li a").live(...) but this would not: $("a", someElement).live(...) and neither would this: $("a").parent().live(...).

<a href="http://docs.jquery.com/Events/live"; rel="nofollow">http://docs.jquery.com/Events/live<;/a>

どういうときにダメなのか、制約がよくわからないんだけれども、とにかく上のケースではだめでした。"currently" と書いてあるくらいだから、将来的に制約が緩くなるのかもしれませんが。。

上のサンプルでlive()をやりたかったらば、単純ちからワザというかですね、

$('tr', '#sample-table').children('td:nth-child(1)').nextAll()

という調子で選択していたtd群に対しクラス名をつけて、

$('.foo')

とやればよいと思われます。未検証ですが。

クラスやidを量産して対処するという普段の私に戻ってしまったわけで、複雑なきぶん。。。いたしかゆしといいますか。。。。

ところでlive()ってのはなにかというと、ある条件(クラス名とか)に合致した要素に対してイベントを割り当てたら、その条件に合う要素がイベント割り当てのあとに出現したとき、自動的にイベントがbindされていく、というものです。これによって、新DOMを突っ込んだときに、いちいちイベントをbindしなくてすむようになり、コードが短く書けるようになります。という説明であってるかな。live()とclone()をうまく使えるようになると、なかなかいいかんじ。私はまだそのような域には達してはいませんが。。まだ使ってない方はどうぞ試してみてください。べんりですよ。上のような制約があるわけですが。。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2009/9/13, 9:23 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

その後の話2。

やっぱり気になるので、上のコメントに書いたコレ↓

> $('.foo')

でやってみたらオッケーでした。わーい。そうか、こういう場合にlive()を使いたい時はclass名をつけていくしかないんだな。。。と納得しかけたつかのま、

「それならaddClass('foo')してからliveを使ったらいいのではないか??」

と別の考えがわいてきました。でもまだ検証してません。そこまでやるのはバカらしいというか、単純にclass名をハードコーディングしていくほうがわかりやすいですよね。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2009/9/13, 9:58 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

あ、てか、addClassは意味ないですね。それだと新DOMを突っ込んだあとにいちいちaddClassしなくてはならなくなるんで、イベントをbindしていく手間と大して変わらない。だから意味ない。あー、疲れてしまった。もう今日はおしまい。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

コメント・プリーズ!

お名前 (your name)
(required)
url
(optional) ※公開されます。
メールアドレス (email)
(optional) ※公開されません。管理者にだけわかります。
コメント (comment)
(required)

※クッキーに保存すると次回から入力を省略できるので便利ですが、お使いのコンピュータに情報が残りますので、公共のパソコンなどからアクセスするような場合はチェックをはずしたほうがよいでしょう。

※コメント中のhtmlタグは実体参照に変換されます。たとえば、『<』は『&lt;』というかんじになりますのでhtmlタグをそのまま書き込んでくださってオッケーです。

one-px-ffffff-tl one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

PROFILEcaption

藤居ヒロヤ。ウェブデザイナー/ウェブディレクター。ウェブデザインオフィス、3OT NET主宰。名古屋市中区。「優しいデザイン」「激しいデザイン」「正しいデザイン」「セクシーなデザイン」「泣けるデザイン」「もっともなデザイン」... 。あなただけのウェブデザインを丹精込めておつくり致します。見積り依頼等、お気軽にお問い合わせ下さい。

お問い合わせフォーム

RECENT ENTRIEScaption

RECENT COMMENTScaption

TOOLScaption

BOOKMARKScaption

RESOURCEScaption

ARCHIVEcaption