Note that there are some explanatory texts on larger screens.

plurals
  1. POExporting filtered DataTable with serverside Processing (CodeIgniter)
    primarykey
    data
    text
    <p>I'm working with DataTables and CodeIgniter, and I've been working on exporting a table after filtering it by each column. </p> <p>Since we're going to be using a lot of rows of data, I started working on the version where all of the processing (filtering, pagination, search, etc.) was based on the server. I'm currently having trouble exporting my <em>filtered table</em> into a PDF. </p> <p>Issue that arise:</p> <ul> <li>Only the rows that are currently visible to the user are exported for download. None of the other rows (especially those on other pages--separated through pagination) are included.</li> <li>If the number of rows I get after filtering is > the number of rows allowed per page, I don't get all of the rows that I narrowed down my table to. </li> </ul> <p><em>I would like some help as to how I would overcome this issue.</em> </p> <p>My code is as follows: <strong>Views/List.php</strong></p> <pre><code>&lt;script&gt; $(document).ready( function () { var oTable = $('#tablesupport').dataTable({ "sPaginationType":"bootstrap", "oLanguage": { "sSearch": "Search all columns:" }, "sScrollY": "400px", "bProcessing": true, "bServerSide": true, "sServerMethod": "GET", "sAjaxSource": "dthelper", "iDisplayLength": 10, "aaSorting": [[0, 'asc']], "aoColumns": [ { "bVisible": true, "bSearchable": true, "bSortable": true }, { "bVisible": true, "bSearchable": true, "bSortable": true }, { "bVisible": true, "bSearchable": true, "bSortable": true }, { "bVisible": true, "bSearchable": true, "bSortable": true }, { "bVisible": true, "bSearchable": true, "bSortable": true }, { "bVisible": true, "bSearchable": true, "bSortable": true } ] }); //This function works completely fine if the table is processed client-side, //I am not as successful on the server-side function table2xls(oTable, exportmode, tableElm){ var xls = ''; var headers = []; var rows = []; xls +="&lt;table&gt;&lt;thead&gt;&lt;tr&gt;"; //Headers do not appear when server-side processing is used $(tableElm+' thead').find('th').each(function() { var $th = $(this); var text = $th.text(); var header = '&lt;th&gt;' + text + '&lt;/th&gt;'; // headers.push(header); // original code if(text != "") headers.push(header); }); xls += headers.join(" "); xls += '&lt;tbody&gt;&lt;tr&gt;'; // get table data if (exportmode == "full") { // total data var total = oTable.fnSettings().fnRecordsTotal(); for(i = 0; i &lt; total; i++) { var row = oTable.fnGetData(i); row = strip_tags(row); rows.push(row); } } else { // This branch works fine, however this does not work (in serv. side) for // rows on other pages separated by pagination var filteredrows = $("#tablesupport").dataTable()._('tr', {"filter": "applied"}); for ( var i = 0; i &lt; filteredrows.length; i++ ) { var numCols = 6; var col = '&lt;tr&gt;'; for(var j = 0; j &lt; numCols; j++){ if(j==2) col+= '&lt;td&gt;&lt;div style="font-family: Mv Iyyu Formal;"&gt;' + filteredrows[i][j] + '&lt;/div&gt;&lt;/td&gt;'; else col += '&lt;td&gt;' + filteredrows[i][j] + '&lt;/td&gt;'; } //console.log(filteredrows[i][0]); col += '&lt;/tr&gt;'; rows.push(col); }; /* $(tableElm+' tbody td:visible').each(function(index) { var row = oTable.fnGetData(this); row = strip_tags(row); row = '&lt;td&gt;' + row + '&lt;/td&gt;'; rows.push(row); }); */ } xls += rows.join(); xls += "&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;"; //alert(xls); $("#xlsinput").val(xls); } function strip_tags(html) { var tmp = document.createElement("div"); tmp.innerHTML = html; return tmp.textContent||tmp.innerText; } $("tfoot input").keyup( function () { /* Filter on the column (the index) of this element */ oTable.fnFilter( this.value, $("tfoot input").index(this) ); } ); $.extend( $.fn.dataTableExt.oStdClasses, { "sSortAsc": "header headerSortDown", "sSortDesc": "header headerSortUp", "sSortable": "header" } ); $('#tablesupport tr').click(function() { var href = $(this).find("a").attr("href"); if(href) { window.location = href; } }); $('#export_visible_xls').click(function(event) { event.preventDefault(); table2xls(oTable, 'visible', 'table#tablesupport'); }); } ); &lt;/script&gt; &lt;div class="container"&gt; &lt;div class="row-fluid"&gt;&lt;div class="span12"&gt; &lt;div class="span3"&gt; &lt;div class="btn-group" style="position:relative; right:170px;"&gt; &lt;a class="btn dropdown-toggle" data-toggle="dropdown" href="#"&gt; Actions &lt;span class="caret"&gt;&lt;/span&gt; &lt;/a&gt; &lt;ul class="dropdown-menu"&gt; &lt;li&gt;&lt;a href="#" id="export_visible" value="CSV" /&gt;CSV&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="export_visible_pdf" value="PDF"&gt;PDF&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="export_visible_xls" value="XLS" &gt;XLS&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;/div&gt; &lt;div id="down-button"&gt; &lt;/div&gt; &lt;div class="span3"&gt; &lt;form action=&lt;?php echo base_url() . 'exports/toxls/member_export'; ?&gt; method="post"&gt; &lt;input type="hidden" id="xlsinput" name="xlspost" /&gt; &lt;button type="submit" style="display: none; position: relative; right: 300px;" id="xlsdownload" name="submit" value="Download" class="btn btn-danger" &gt; &lt;i class="icon-download" &gt;&lt;/i&gt; Download&lt;/button&gt; &lt;/form&gt; &lt;/div&gt; &lt;div class="span3"&gt; &lt;form action=&lt;?php echo base_url() . 'exports/topdf'; ?&gt; method="post"&gt; &lt;input type="hidden" id="pdfinput" name="pdfpost"&gt;&lt;/input&gt; &lt;button type="submit" style="display: none; position: relative; right: 500px;" id="pdfdownload" name="submit" value="Download" class="btn btn-info"&gt; &lt;i class="icon-download" &gt;&lt;/i&gt; Download&lt;/button&gt; &lt;/form&gt; &lt;/div&gt; &lt;div class="span3"&gt; &lt;form action=&lt;?php echo base_url() . 'exports/tocsv/member_export'; ?&gt; method="post"&gt; &lt;input type="hidden" id="csvinput" name="csvpost"/&gt; &lt;button type="submit" style="display: none; position: relative; right: 710px" id="csvdownload" name="submit" value="Download" class="btn btn-primary"&gt; &lt;i class="icon-download" &gt;&lt;/i&gt; Download&lt;/button&gt; &lt;/form&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="row-fluid"&gt; &lt;div class="span12"&gt; &lt;div class="span2"&gt;&lt;/div&gt; &lt;div class="span8"&gt; &lt;div class="table-responsive"&gt; &lt;div id="dvData"&gt; &lt;table class = "table table-hover" id="tablesupport"&gt; &lt;thead&gt; &lt;tr&gt; &lt;th id='nid'&gt;NID&lt;/th&gt; &lt;th&gt;Name (ENG)&lt;/th&gt; &lt;th&gt;Name (DV)&lt;/th&gt; &lt;th&gt;Current address&lt;/th&gt; &lt;th&gt;Permanent address&lt;/th&gt; &lt;th&gt;Status&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody id="fbody" class="rowlink"&gt; &lt;/tbody&gt; &lt;tfoot&gt; &lt;tr&gt; &lt;th&gt;&lt;input type="text" name="search_nid" placeholder="Search NID" class="search_init" /&gt;&lt;/th&gt; &lt;th&gt;&lt;input type="text" name="search_name" placeholder="Search Name (ENG)" class="search_init" /&gt;&lt;/th&gt; &lt;th&gt;&lt;input type="text" name="search_namedv" id="thaanaInput7" class="thaana" placeholder="ނަން ހޯދާ" class="search_init" /&gt;&lt;/th&gt; &lt;th&gt;&lt;input type="text" name="search_caddress" placeholder="Search curr. address" class="search_init" /&gt;&lt;/th&gt; &lt;th&gt;&lt;input type="text" name="search_paddress" placeholder="Search perm. address" class="search_init" /&gt;&lt;/th&gt; &lt;th&gt;&lt;input type="text" name="search_status" placeholder="Search status" class="search_init" /&gt;&lt;/th&gt; &lt;/tr&gt; &lt;/tfoot&gt; &lt;/table&gt; &lt;/div&gt;&lt;/div&gt;&lt;div class="span2"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; </code></pre> <p><strong>Controllers/Record/dthelper()</strong> function</p> <pre><code>public function dthelper(){ $numCols = 6; $this-&gt;load-&gt;database(); $aColumns = array('member_NID', 'member_fName', 'member_mName', 'member_lName', 'member_fNameDV', 'member_mNameDV', 'member_lNameDV', 'member_currAtoll', 'member_currIsland','member_currAddress', 'member_permAtoll', 'member_permIsland', 'member_permAddress', 'member_status'); $sTable = "membershiprecord"; $iDisplayStart = $this-&gt;input-&gt;get_post('iDisplayStart', true); $iDisplayLength = $this-&gt;input-&gt;get_post('iDisplayLength', true); $iSortCol_0 = $this-&gt;input-&gt;get_post('iSortCol_0', true); $iSortingCols = $this-&gt;input-&gt;get_post('iSortingCols', true); $sSearch = $this-&gt;input-&gt;get_post('sSearch', true); $sSearch_0 = $this-&gt;input-&gt;get_post('sSearch_0', true); $sSearch_1 = $this-&gt;input-&gt;get_post('sSearch_1', true); $sSearch_2 = $this-&gt;input-&gt;get_post('sSearch_2', true); $sSearch_3 = $this-&gt;input-&gt;get_post('sSearch_3', true); $sSearch_4 = $this-&gt;input-&gt;get_post('sSearch_4', true); $sEcho = $this-&gt;input-&gt;get_post('sEcho', true); // Paging if(isset($iDisplayStart) &amp;&amp; $iDisplayLength != '-1') { $this-&gt;db-&gt;limit($this-&gt;db-&gt;escape_str($iDisplayLength), $this-&gt;db-&gt;escape_str($iDisplayStart)); } // Ordering if(isset($iSortCol_0)) { for($i=0; $i&lt;intval($iSortingCols); $i++) { $iSortCol = $this-&gt;input-&gt;get_post('iSortCol_'.$i, true); $bSortable = $this-&gt;input-&gt;get_post('bSortable_'.intval($iSortCol), true); $sSortDir = $this-&gt;input-&gt;get_post('sSortDir_'.$i, true); if($bSortable == 'true') { $this-&gt;db-&gt;order_by($aColumns[intval($this-&gt;db-&gt;escape_str($iSortCol))], $this-&gt;db-&gt;escape_str($sSortDir)); } } } /* * Filtering * NOTE this does not match the built-in DataTables filtering which does it * word by word on any field. It's possible to do here, but concerned about efficiency * on very large tables, and MySQL's regex functionality is very limited */ if(isset($sSearch) &amp;&amp; !empty($sSearch)) { for($i=0; $i&lt;count($numCols); $i++) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_'.$i, true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;like('member_NID', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_fName', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_mName', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_lName', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_fNameDV', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_mNameDV', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_lNameDV', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_currAtoll', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_currIsland', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_currAddress', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_permAtoll', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_permIsland', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_permAddress', $this-&gt;db-&gt;escape_like_str($sSearch)); $this-&gt;db-&gt;or_like('member_status', $this-&gt;db-&gt;escape_like_str($sSearch)); } } } if(isset($sSearch_0) &amp;&amp; !empty($sSearch_0)) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_0', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;or_like('member_NID', $this-&gt;db-&gt;escape_like_str($sSearch_0)); } } if(isset($sSearch_1) &amp;&amp; !empty($sSearch_1)) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_1', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;like('member_fName', $this-&gt;db-&gt;escape_like_str($sSearch_1)); $this-&gt;db-&gt;or_like('member_mName', $this-&gt;db-&gt;escape_like_str($sSearch_1)); $this-&gt;db-&gt;or_like('member_lName', $this-&gt;db-&gt;escape_like_str($sSearch_1)); } } if(isset($sSearch_2) &amp;&amp; !empty($sSearch_2)) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_2', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;like('member_fNameDV', $this-&gt;db-&gt;escape_like_str($sSearch_2)); $this-&gt;db-&gt;or_like('member_mNameDV', $this-&gt;db-&gt;escape_like_str($sSearch_2)); $this-&gt;db-&gt;or_like('member_lNameDV', $this-&gt;db-&gt;escape_like_str($sSearch_2)); } } if(isset($sSearch_3) &amp;&amp; !empty($sSearch_3)) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_3', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;like('member_currAtoll', $this-&gt;db-&gt;escape_like_str($sSearch_3)); $this-&gt;db-&gt;or_like('member_currIsland', $this-&gt;db-&gt;escape_like_str($sSearch_3)); $this-&gt;db-&gt;or_like('member_currAddress', $this-&gt;db-&gt;escape_like_str($sSearch_3)); } } if(isset($sSearch_4) &amp;&amp; !empty($sSearch_4)) { $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_4', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { $this-&gt;db-&gt;like('member_permAtoll', $this-&gt;db-&gt;escape_like_str($sSearch_4)); $this-&gt;db-&gt;or_like('member_permIsland', $this-&gt;db-&gt;escape_like_str($sSearch_4)); $this-&gt;db-&gt;or_like('member_permAddress', $this-&gt;db-&gt;escape_like_str($sSearch_4)); } } if(isset($sSearch_5) &amp;&amp; !empty($sSearch_5)) { $var = 0; $bSearchable = $this-&gt;input-&gt;get_post('bSearchable_5', true); // Individual column filtering if(isset($bSearchable) &amp;&amp; $bSearchable == 'true') { switch($sSearch_5){ case "Registered member": $var = 1; break; case "Non-registered member": $var = 2; break; case "Ex-member": $var = 3; break; } $this-&gt;db-&gt;like('member_status', $this-&gt;db-&gt;escape_like_str($var)); } } // Select Data $this-&gt;db-&gt;select('SQL_CALC_FOUND_ROWS '.str_replace(' , ', ' ', implode(', ', $aColumns)), false); $rResult = $this-&gt;db-&gt;get($sTable); // Data set length after filtering $this-&gt;db-&gt;select('FOUND_ROWS() AS found_rows'); $iFilteredTotal = $this-&gt;db-&gt;get()-&gt;row()-&gt;found_rows; // Total data set length $iTotal = $this-&gt;db-&gt;count_all($sTable); // Output $output = array( 'sEcho' =&gt; intval($sEcho), 'iTotalRecords' =&gt; $iTotal, 'iTotalDisplayRecords' =&gt; $iFilteredTotal, 'aaData' =&gt; array() ); foreach($rResult-&gt;result_array() as $aRow) { $row = array(); /* foreach($aColumns as $col) { $row[] = $aRow[$col]; }*/ for($i=0; $i&lt;sizeof($aColumns); $i++){ if($i == 1) $row[] = $aRow[$aColumns[$i]] ." ". $aRow[$aColumns[$i+1]] ." ". $aRow[$aColumns[$i+2]]; else if($i == 4) $row[] = $aRow[$aColumns[$i]] ." ". $aRow[$aColumns[$i+1]] ." ". $aRow[$aColumns[$i+2]]; else if($i == 7) $row[] = $aRow[$aColumns[$i]] .", ". $aRow[$aColumns[$i+1]] .", ". $aRow[$aColumns[$i+2]]; else if($i == 10) $row[] = $aRow[$aColumns[$i]] .", ". $aRow[$aColumns[$i+1]] .", ". $aRow[$aColumns[$i+2]]; else if($i==2 || $i == 3) continue; else if($i ==5 || $i==6) continue; else if($i ==8 || $i==9) continue; else if($i ==11 || $i==12) continue; else if($i==13){ $status = $aRow[$aColumns[$i]]; $var = ''; switch($status){ case "1": $var = "Non-registered member"; break; case "2": $var = "Registered member"; break; case "3": $var = "Ex-member"; break; } $row[] = $var; } else $row[] = $aRow[$aColumns[$i]]; } $output['aaData'][] = $row; } echo json_encode($output); } </code></pre> <p>The ugliness of the above code has much to do with the fact that it was written in one sitting. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload