DataTables Part4 -Individual column searching-

前回までに引き続きDataTablesについて。今回は各列ごとに独自に検索窓を設ける方法。

これまでの投稿は下記の通り。

  • Part1 -Introduction-
  • Part2 -Server-side processing-
  • Part3 -File Export-
  •  

    基本的にはPart2 -Server-side processing-のソースがベースとなる。
    まず、通常のHTMLファイルを用意する。thead内に検索用inputタグやselectタグを設置。

    <br />
        &lt;table id=&quot;example&quot; class=&quot;display&quot; width=&quot;100%&quot; cellspacing=&quot;0&quot;&gt;<br />
            &lt;thead&gt;<br />
                &lt;tr&gt;<br />
                    &lt;th&gt;CountryCode&lt;/th&gt;<br />
                    &lt;th&gt;Language&lt;/th&gt;<br />
                    &lt;th&gt;IsOfficial&lt;/th&gt;<br />
                    &lt;th&gt;Percentage&lt;/th&gt;<br />
                &lt;/tr&gt;<br />
                &lt;tr&gt;<br />
                    &lt;td&gt;<br />
                        &lt;input type=&quot;text&quot; data-column=&quot;0&quot; class=&quot;search-input-text&quot;&gt;<br />
                    &lt;/td&gt;<br />
                    &lt;td&gt;<br />
                        &lt;input type=&quot;text&quot; data-column=&quot;1&quot; class=&quot;search-input-text&quot;&gt;<br />
                    &lt;/td&gt;<br />
                    &lt;td&gt;<br />
                        &lt;select data-column=&quot;2&quot; class=&quot;search-input-select&quot;&gt;<br />
                            &lt;option value=&quot;&quot;&gt;All&lt;/option&gt;<br />
                            &lt;option value=&quot;1&quot;&gt;T&lt;/option&gt;<br />
                            &lt;option value=&quot;2&quot;&gt;F&lt;/option&gt;<br />
                        &lt;/select&gt;<br />
                    &lt;/td&gt;<br />
                    &lt;td&gt;<br />
                        &lt;input type=&quot;text&quot; data-column=&quot;3&quot; class=&quot;search-input-text&quot;&gt;<br />
                    &lt;/td&gt;<br />
                &lt;/tr&gt;<br />
            &lt;/thead&gt;<br />
        &lt;/table&gt;<br />
    

     
    次に、javascriptの編集。
    今回はヘッダの下の行に検索窓をおくことにする。この場合、orderCellsTopをtrueにしておかないと、検索窓のところにOrdering機能が設置されてしまうので注意。
    また、どの列の検索窓に検索ワードが打ち込まれたかを検知するための記述をする。

    <br />
    $(document).ready(function(){<br />
        $('#example').DataTable( {<br />
            /**<br />
             * Part1~3で説明済み<br />
             */<br />
            dom: '&lt;&quot;top&quot;f&gt;rt&lt;&quot;bottom&quot;lip&gt;&lt;&quot;clear&quot;&gt;',<br />
            lengthMenu: [[10, 50, 100, 500, 9999], [10, 50, 100, 500, &quot;全&quot;]],<br />
            language: {<br />
                url: &quot;https://cdn.datatables.net/plug-ins/1.10.15/i18n/Japanese.json&quot;,<br />
            },<br />
            stateSave: true,<br />
            serverSide: true,<br />
            ajax: &quot;datatables_griddata4.php&quot;,</p>
    <p>        /**<br />
             * 一番上のヘッダーセルにOrdering機能を持ってくる<br />
             * (false(default)の場合は一番下)<br />
             */<br />
            orderCellsTop: true,</p>
    <p>    } );</p>
    <p>    /**<br />
         * Individual column filtering<br />
         * 各カラムでインスタント検索を行う<br />
         */<br />
        $('#example').on( 'click', '.search-input-text', function (e) {<br />
            e.stopPropagation();<br />
        } );</p>
    <p>    $('#example').on( 'keyup change', '.search-input-text', function (e) {<br />
            var i =$(this).attr('data-column');  // getting column index<br />
            var v =$(this).val();  // getting search input value<br />
            dataTable.columns(i).search(v).draw();<br />
        } );</p>
    <p>    $('#example').on( 'change', '.search-input-select', function (e) {<br />
            var i =$(this).attr('data-column');  // getting column index<br />
            var v =$(this).val();  // getting search input value<br />
            dataTable.columns(i).search(v).draw();<br />
        } );<br />
    });<br />
    

     

    Part2で使用していた “datatables_griddata1.php” をベースに “datatables_griddata4.php” として書き換える。以下は変更点のみ記載。

    <br />
        /**<br />
         * SQL for Individual column filtering<br />
         */<br />
        $sql_individual_filtering = &quot;&quot;;<br />
        if ( !empty($requestData['columns'][0]['search']['value']) ) {<br />
            $sql_individual_filtering .= &quot; AND CountryCode LIKE :col0 ESCAPE '!'&quot;;<br />
        }<br />
        if ( !empty($requestData['columns'][1]['search']['value']) ) {<br />
            $sql_individual_filtering .= &quot; AND Language LIKE :col1 ESCAPE '!'&quot;;<br />
        }<br />
        if ( !empty($requestData['columns'][2]['search']['value']) ) {<br />
            if ($requestData['columns'][2]['search']['value'] == 1) {<br />
                $sql_individual_filtering .= &quot; AND IsOfficial = 'T'&quot;;<br />
            } else if ($requestData['columns'][2]['search']['value'] == 2) {<br />
                $sql_individual_filtering .= &quot; AND IsOfficial = 'F'&quot;;<br />
            }<br />
        }<br />
        if ( !empty($requestData['columns'][3]['search']['value']) ) {<br />
            $sql_individual_filtering .= &quot; AND Percentage LIKE :col3 ESCAPE '!'&quot;;<br />
        }</p>
    <p>    /**<br />
         * Number of results after Individual column filtering<br />
         */<br />
        $sql_filtered_cnt = &quot;SELECT count(*) as reccnt FROM countrylanguage<br />
                             WHERE 1 = 1 {$sql_individual_filtering}&quot;;</p>
    <p>    if (!empty($sql_individual_filtering)) {<br />
            $stmt_num = $pdo-&gt;prepare($sql_filtered_cnt);<br />
            if ( !empty($requestData['columns'][0]['search']['value']) ) {<br />
                $stmt_num-&gt;bindValue(col0, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][0]['search']['value']) . '%');<br />
            }<br />
            if ( !empty($requestData['columns'][1]['search']['value']) ) {<br />
                $stmt_num-&gt;bindValue(col1, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][1]['search']['value']) . '%');<br />
            }<br />
            if ( !empty($requestData['columns'][3]['search']['value']) ) {<br />
                $stmt_num-&gt;bindValue(col3, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][3]['search']['value']) . '%');<br />
            }<br />
            $stmt_num-&gt;execute();<br />
        } else {<br />
            $stmt_num = $pdo-&gt;query($sql_filtered_cnt);<br />
        }<br />
        $totalFiltered = $stmt_num-&gt;fetchColumn();<br />
    

     

    <br />
        $sql = &quot;SELECT CountryCode, Language, IsOfficial, Percentage<br />
                FROM countrylanguage<br />
                WHERE 1 = 1 {$sql_individual_filtering}<br />
                ORDER BY $order_col $order_dir<br />
                LIMIT :st, :len&quot;;<br />
        $stmt = $pdo-&gt;prepare($sql);</p>
    <p>    if (!empty($sql_individual_filtering)) {<br />
            if ( !empty($requestData['columns'][0]['search']['value']) ) {<br />
                $stmt-&gt;bindValue(col0, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][0]['search']['value']) . '%');<br />
            }<br />
            if ( !empty($requestData['columns'][1]['search']['value']) ) {<br />
                $stmt-&gt;bindValue(col1, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][1]['search']['value']) . '%');<br />
            }<br />
            if ( !empty($requestData['columns'][3]['search']['value']) ) {<br />
                $stmt-&gt;bindValue(col3, '%' . preg_replace('/(?=[!_%])/', '!', $requestData['columns'][3]['search']['value']) . '%');<br />
            }<br />
        }<br />
    

     

    具体的な動きはこちら。