teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

ほかにあった修正点を追記しました。また、おすすめのコード記述方式も追記しています。

2017/08/06 00:27

投稿

zohnam
zohnam

スコア1449

answer CHANGED
@@ -13,4 +13,82 @@
13
13
 
14
14
 
15
15
  ブラウザでF12を押したらデベロッパーツールと言うものが出てきます。
16
- デベロッパーツールを使えば、現在各タグがどんな状態にあるのか(どんなidが振られているのか)確認できますので、デバッグに便利ですよ。
16
+ デベロッパーツールを使えば、現在各タグがどんな状態にあるのか(どんなidが振られているのか)確認できますので、デバッグに便利ですよ。
17
+
18
+ ##修正点追記
19
+
20
+ おかしい挙動の原因は、`label`関連の指定がおかしかったせいもあったようですね。
21
+ ```html
22
+ <div class="checkbox" id="additional_member">
23
+ <input type="checkbox" name="checkbox_member" id="sidebar_member1" class="cb_member" value="3254" />
24
+ <label for="sidebar_member1" class="sb_member" id="label_sb1"><span id="member_name1">高木 優斗</span></label>
25
+ <input type="checkbox" name="checkbox_member" id="sidebar_member2" class="cb_member" value="1895" />
26
+ <label for="sidebar_member2" class="sb_member" id="label_sb2"><span id="member_name2">吉岡 健二</span></label>
27
+ </div>
28
+ ```
29
+
30
+ `</label>`指定がないせいで、`吉岡 健二`のほうをクリックしたら、`高木 優斗`のほうもクリックされたことになっていました。
31
+ また、`label`の`for`指定がチェックボックスのidになっていないせいで、クリックしてもチェックボックスのチェックが付かない状態でした。
32
+
33
+ あと、`checked`について勘違いされているような気がしますので念のため書いておきますが、`ラベルにcheckedクラスをつける`のと、`チェックボックスをチェック状態にする`のには関連性はありませんよ。
34
+
35
+ 上述のindex記述と、label部分の修正を行えば正常動作しますが、せっかくなので、おすすめの記述を書いておきます。
36
+
37
+ ```html
38
+ <!DOCTYPE HTML>
39
+ <html>
40
+ <head></head>
41
+ <body>
42
+ <div class="checkbox" id="additional_member">
43
+ <label>
44
+ <input type="checkbox" name="checkbox_member" class="cb_member" data-member="1" value="3254" />
45
+ <span>高木 優斗</span>
46
+ </label>
47
+ <label>
48
+ <input type="checkbox" name="checkbox_member" class="cb_member" data-member="2" value="1895" />
49
+ <span>吉岡 健二</span>
50
+ </label>
51
+ </div>
52
+
53
+ <div id="add_member"></div>
54
+
55
+ <ul id="member_list"></ul>
56
+
57
+ <script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
58
+ <script>
59
+ $('#additional_member').on('click', '.cb_member', function(){
60
+ var $elem = $(this);
61
+ var member_id = $elem.data("member");
62
+ var val = $elem.val();
63
+ var str = $elem.parents("label").find("span").text();
64
+ //チェックボックスはチェック状態か?
65
+ if ( $elem.prop('checked') ){
66
+ $('<input>').attr({
67
+ type: 'hidden',
68
+ class : 'member',
69
+ id: 'member_id' + member_id,
70
+ name: 'member[]',
71
+ value: val
72
+ }).appendTo('#add_member');
73
+ var str_li = '<li id="list_elm' + member_id + '">' + str + '</li>';
74
+ $('#member_list').append(str_li);
75
+ $elem.addClass('checked');
76
+ }else{
77
+ $("#member_id" + member_id).remove();
78
+ $("#list_elm" + member_id).remove();
79
+ $elem.removeClass('checked');
80
+ }
81
+ });
82
+ </script>
83
+ </body>
84
+ </html>
85
+ ```
86
+
87
+ この記述のポイントはこんなところです。
88
+ - `label`は`for`でid指定すると項目が増えるごとにマジックナンバーの入力が増えるため、`<label>~</label>`で囲む方を利用します。
89
+ - また、labelを囲み方式することで、メンバーidは一箇所だけ入力しておけば、parents,findを駆使して同一グループ内のデータを取り出せるようになります。
90
+ - クリック判定はラベルではなくチェックボックスで行います。
91
+ - これは私個人のルールですが、indexという変数名は、**配列内の順番を示すときにだけ使い**、idをベースとした管理をするときは`**_id`のような変数にします。目的に沿った変数名にしておくと、余計な混乱を招きません。
92
+ - `.prop('checked')`でチェック状態かどうかを取得できますので、それを利用します。`checked`クラスを付ける意味はこれでほとんどありませんが、CSSの都合でつけておきたいかもしれませんので一応残しています。
93
+ - 追加する3項目をA,B,Cという順番で処理するなら、削除するときもA,B,Cの順番で処理します。
94
+