tag:crieit.net,2005:https://crieit.net/tags/CheckBox/feed 「CheckBox」の記事 - Crieit Crieitでタグ「CheckBox」に投稿された最近の記事 2021-11-29T20:59:12+09:00 https://crieit.net/tags/CheckBox/feed tag:crieit.net,2005:PublicArticle/17795 2021-11-29T20:59:12+09:00 2021-11-29T20:59:12+09:00 https://crieit.net/posts/input-checkbox-double-bracket-post-failed-20211129 input type="checkbox" の二重ブラケットについて <p>WordPress の自作プラグインで挙動不審なところが見付かり、そういえば……と思って input type="checkbox" の二重ブラケットについて調べてみました。</p> <p>調査した結果としては、自作プラグインのコードの書き方が悪かったので修正しました。</p> <h2 id="経緯・現象"><a href="#%E7%B5%8C%E7%B7%AF%E3%83%BB%E7%8F%BE%E8%B1%A1">経緯・現象</a></h2> <p>WordPress の自作プラグインでカスタムタクソノミーをチェックボックスで選択できる設定画面を作ってあったのですが、そこにチェックを入れてもデータが保存されない現象に遭遇。</p> <h3 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h3> <pre><code class="php"><?php require_once( ABSPATH . '/wp-admin/includes/template.php' ); class MyCategoryChecklistWalker extends \Walker_Category_Checklist { /** * var */ protected $c; protected $hidden_ids; /** * コンストラクタ */ function __construct( $c, $arrayTaxonomies ) { $this->c = $c; $this->hidden_ids = $arrayTaxonomies['id']; } /** * Start the element output. * * @see Walker::start_el() * * @since 2.5.1 * * @param string $output Used to append additional content (passed by reference). * @param object $category The current term object. * @param int $depth Depth of the term in reference to parents. Default 0. * @param array $args An array of arguments. @see wp_terms_checklist() * @param int $id ID of the current term. */ function start_el( &$output, $category, $depth = 0, $args = Array(), $id = 0 ) { extract( $args ); if( empty( $taxonomy )) { $taxonomy = 'category'; } if( $taxonomy == 'category' ) { $name = 'post_category'; } else { $name = 'tax_input[' . $taxonomy . ']'; } $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : ''; // 処理 $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; // 処理 } } </code></pre> <p>設定画面は WordPress の Walker_Category_Checklist を継承したクラスで、チェックボックスの設定画面を作成していました。</p> <p>特に今回気になったのは次の部分。</p> <pre><code class="php"> else { $name = 'tax_input[' . $taxonomy . ']'; } </code></pre> <p>もう一つ。</p> <pre><code class="php"> $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; </code></pre> <p>デフォルトのカテゴリーならば <code>post_category</code> という文字列を付与していますが、カスタムタクソノミーの場合は <code>tax_input[TAXONOMY_NAME]</code> とブラケットを使ってオブジェクトの記述にしていました。これをチェックボックスの <code>name</code> 属性に使用しています。その際に、複数選択可能なチェックボックスなのでさらに外側にブラケットが付くようにしていました。</p> <pre><code>name="myplugin_checkboxes[tax_input[TAXONOMY_NAME]___term---TERMID]" </code></pre> <p>こんな感じですね。ところが、このチェックボックスにチェックを入れても反映されない、となったわけです。</p> <p>いかにも二重にブラケットで括っているのが挙動不審の原因になっていそうな気がしたので、調査しました。</p> <h2 id="調査"><a href="#%E8%AA%BF%E6%9F%BB">調査</a></h2> <pre><code>a:XX:{s:26:"post_category___term---154";i:1;s:26:"post_category___term---165";i:1;s:26: /* 略 */ i:1;s:32:"tax_input[TAXONOMY_NAME";i:1;} </code></pre> <p>データベースで該当するキーを確認すると……やはり、二重ブラケットになった値を入れるところでシリアライズされたデータのフォーマットが崩れています。</p> <h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2> <p>そこで簡単なコードを作成。</p> <pre><code class="html"><!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>input</title> </head> <body> <form action="./test.php" method="post"> <label for="input"> <input type="checkbox" name="input[hoge[fuga]]" id="input" value="1"> インプット </label> <button type="submit">送信</button> </form> </body> </html> </code></pre> <p>二重ブラケットのチェックボックスを用意して POST するだけの簡単なフォームです。</p> <pre><code class="php"><!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>result</title> </head> <body> <pre><code> <?php var_dump($_SERVER); ?> </code></pre> <pre><code> <?php var_dump($_REQUEST); ?> </code></pre> </body> </html> </code></pre> <p>テストなのでエスケープとか一切していないですが、これで出力を確認。</p> <pre><code>array (size=1) 'input' => array (size=1) 'hoge[fuga' => string '1' (length=1) </code></pre> <p>思った通り、二重ブラケットのキーが途中で壊れてしまっています。 DB の中でシリアライズが崩れたデータと同じ状態です。</p> <p>これで二重ブラケットがNGであることが分かったのでコードを修正します。</p> <h2 id="修正"><a href="#%E4%BF%AE%E6%AD%A3">修正</a></h2> <pre><code class="php"> else { // $name = 'tax_input[' . $taxonomy . ']'; $name = $taxonomy; } </code></pre> <p>今回は独自のパース処理でタームのチェックを判断しているので、 <code>tax_input</code> の配列名は不要でした。そこで、タクソノミー名をそのまま <code>$name</code> に渡すように修正を加えました。</p> <pre><code class="php"> $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; </code></pre> <p>それを使ってチェックボックスを出力する部分や他の部分は一切触らず。これで動作OKを確認しました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://developer.wordpress.org/reference/classes/walker_category_checklist/">Walker_Category_Checklist | Class | WordPress Developer Resources</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/15393 2019-09-13T09:40:08+09:00 2019-09-13T09:40:08+09:00 https://crieit.net/posts/VB-NET-5d7ae568f1244 【VB.NET】データグリッドビューで行毎のチェックボックスにイベントを仕込む <p>今回は、データグリッドに配置したチェックボックス列にイベントを仕込みたいと思います。</p> <p>プログラムは前回のものを流用。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/12/15/post-3456/" target="_blank" rel="noopener noreferrer" data-blogcard="1">【VB.NET】データグリッドビューで行毎のコンボボックスにイベントを仕込む</a></p> <h2 id="プログラムの修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BF%AE%E6%AD%A3">プログラムの修正</a></h2> <h3 id="新規イベントの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0">新規イベントの追加</a></h3> <p>データグリッドビューの現在のセル状態が変更された際のイベントを追加します。</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/12/VbGridCheck000.jpg" alt="新規イベントの追加①" /></p> <p>Form1.vb</p> <pre><code> ''' <summary> ''' データグリッドビューの現在のセル状態が変更された際のイベント ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub dgv_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles dgv.CurrentCellDirtyStateChanged ' 対象のセルを判定 If dgv.CurrentCellAddress.X = 0 AndAlso dgv.IsCurrentCellDirty Then ' 変更を確定する dgv.CommitEdit(DataGridViewDataErrorContexts.Commit) End If End Sub </code></pre> <p> </p> <p>データグリッドビューのセル値が変更された際のイベントを追加</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/12/VbGridCheck001.jpg" alt="新規イベントの追加②" /></p> <p>Form1.vb</p> <pre><code> ''' <summary> ''' データグリッドビューのセル値が変更(が確定)された際のイベント ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub dgv_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellValueChanged If (TypeOf dgv(e.ColumnIndex, e.RowIndex) Is DataGridViewCheckBoxCell) Then Dim chk As DataGridViewCheckBoxCell = dgv(e.ColumnIndex, e.RowIndex) MessageBox.Show(e.RowIndex + 1 &amp; "行目のチェックボックス値:" &amp; chk.Value) End If End Sub </code></pre> <p> </p> <p>データグリッドビューのセルがクリック(マウスダウン)された際のイベントを追加</p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/12/VbGridCheck002.jpg" alt="新規イベントの追加③" /></p> <p>Form1.vb</p> <pre><code> ''' <summary> ''' データグリッドビューのセルをクリック(マウスダウン)した際のイベント ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub dgv_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgv.CellMouseDown If (TypeOf dgv(e.ColumnIndex, e.RowIndex) Is DataGridViewCheckBoxCell) Then Dim cell As DataGridViewCheckBoxCell = dgv(e.ColumnIndex, e.RowIndex) cell.Value = If(cell.Value = False, True, False) ' 変更を確定する dgv.CommitEdit(DataGridViewDataErrorContexts.Commit) dgv.EndEdit() End If End Sub </code></pre> <p> </p> <h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/12/VbGridCheck003.jpg" alt="チェックしてみる" /></p> <p><img src="https://www.doraxdora.com/wp-content/uploads/2017/12/VbGridCheck004.jpg" alt="チェックを外してみる" /></p> <p>無事に処理できましたね。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>次回は、チェックされた行の背景色を変更してみたいと思います。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2017/12/20/post-3502/" target="_blank" rel="noopener noreferrer">【VB.NET】データグリッドビューでチェックされた行の背景色を変更する</a></p> <p>ではでは。</p> doraxdora