mongoose00318 Posted May 27, 2020 Share Posted May 27, 2020 I'm trying to make it to where when a user clicks a link inside of my tabulator table, they can click the back button in their browser and my tabulator table will remember any filters, sorts, and pagination information and restore them to the exact view they had when they left the page. I am going to store the info in a session but I'm having trouble with the logic of it; meaning when and how to update the information in the session. For example: Case 1: User arrive on page for the first time and has no session data so tabulator passes the initial $_GET variables. I process the $_GET vars and then store the information in the session. Case 2: User has session information so I restore their view of the table based on these values. But, now let's say they go to the next page....how would I go about figuring out if I need to update their session values or just restore the values that already exist? Quote Link to comment Share on other sites More sharing options...
Barand Posted May 27, 2020 Share Posted May 27, 2020 $setting = $_GET['setting'] ?? $_SESSION['setting'] ?? 'default'; $_SESSION['setting'] = $setting; … which does the following If the user has provided a value via GET, use that value. If there is no new GET value use the SESSION value if it exists If neither exist, use a default value Save the value Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 27, 2020 Author Share Posted May 27, 2020 Okay, I was thinking something along those lines as well. The only problem is that no matter what tabulator passes $_GET vars. When you first load the table these values are passed. Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 27, 2020 Author Share Posted May 27, 2020 (edited) Okay I've made some progress. I have it remembering the sorters and the filters. I'm having trouble with the pagination though. //handle pagination $_GET vars $tabulator_get['pagination'] = [ 'current_page' => ( $_GET['page'] !== 1 && isset ( $_SESSION['tabulator_get']['pagination']['current_page']) ) ? $_SESSION['tabulator_get']['pagination']['current_page'] : 1, //current page of pagination 'last_page' => ceil($total_rows / $records_per_page), 'offset' => ($_GET[ 'page' ]-1) * $records_per_page, 'records_per_page' => 14, ]; The 'current_page' part...I'm trying to say if that value of $_GET['page'] isn't set to 1 then use the value of the session. Something isn't working with it though. My logic here is that even though tabulator sends a $_GET response in the beginning I can determine if it was the initial load by seeing if it is sending page 1.... It just keeps setting the value to 1. Something must be wrong with my if condition. @Barand I was able to use the Null Coalescing Operator in parts of my code. I will be replacing parts of my code with that where I can to shorten my code. I love using those short hand operators. Thanks. Edited May 27, 2020 by mongoose00318 Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 27, 2020 Author Share Posted May 27, 2020 I'm at a loss. I'm not sure where I'm going wrong with setting the current page.... //handle filters $_GET vars if ( isset ( $_GET['filters'][0] ) ) { //set fields if ( $_GET['filters'][0]['field'] == 'Job Number' ) $tabulator_get['filters'] = ['field' => 'job_number']; //set to job number elseif ( $_GET['filters'][0]['field'] == 'Enterprise' ) $tabulator_get['filters'] = ['field' => 'enterprise']; //set to enterprise elseif ( $_GET['filters'][0]['field'] == 'Description' ) $tabulator_get['filters'] = ['field' => 'description']; //set to enterprise $tabulator_get['filters']['type'] = 'LIKE'; //set type $tabulator_get['filters']['value'] = "'%" . $_GET['filters'][0]['value'] . "%'"; //set value //filters aren't set in $_GET vars; see if session has filter data stored } elseif ( isset ( $_SESSION[ 'tabulator_get' ][ 'filters'] ) ) { $tabulator_get['filters']['field'] = $_SESSION[ 'tabulator_get' ][ 'filters']['field']; $tabulator_get['filters']['type'] = $_SESSION[ 'tabulator_get' ][ 'filters']['type']; $tabulator_get['filters']['value'] = $_SESSION[ 'tabulator_get' ][ 'filters']['value']; } //handle sorter $_GET vars if ( isset ( $_GET['sorters'] ) ) { $tabulator_get['sorters'] = [ 'field' => ( isset ($_GET[ 'sorters' ][0]['field']) && $_GET[ 'sorters' ][0]['field'] == 'AS400 Ship Date' ) ? 'as400_ship_date' : '', 'direction' => ( isset ($_GET[ 'sorters' ][0]['dir']) ) ? strtoupper( $_GET[ 'sorters' ][0]['dir'] ) : '', ]; //sorters aren't set in $_GET vars; see if session has sorter data stored } elseif ( isset ( $_SESSION[ 'tabulator_get' ][ 'sorters'] ) ) { $tabulator_get['sorters'] = [ 'field' => $_SESSION[ 'tabulator_get' ][ 'sorters' ][ 'field' ], 'direction' => $_SESSION[ 'tabulator_get' ][ 'sorters' ][ 'direction' ], ]; } //query db for necessary pagination data if( isset ( $tabulator_get[ 'filters' ] ) ) { $total_pages_sql = "SELECT COUNT(*) FROM production_data WHERE " . $tabulator_get['filters']['field'] . " LIKE " . $tabulator_get['filters']['value']; } else { $total_pages_sql = "SELECT COUNT(*) FROM production_data"; } $stmt = $pdo->query($total_pages_sql); $stmt->execute(); $records_per_page = 14; $page = $_GET['page']; $offset = ($page-1) * $records_per_page; $total_rows = $stmt->fetchColumn(); $total_pages = ceil($total_rows / $records_per_page); //handle pagination $_GET vars $tabulator_get['pagination'] = [ 'current_page' => (!$_GET['page'] || $_GET['page'] == 1) ? $_SESSION['tabulator_get']['pagination']['current_page'] : $_GET['page'], //current page of pagination 'last_page' => ceil($total_rows / $records_per_page), 'offset' => ($_GET[ 'page' ]-1) * $records_per_page, 'records_per_page' => 14, ]; //store tabulator $_GET vars in a session $_SESSION[ 'tabulator_get' ] = $tabulator_get; Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 27, 2020 Author Share Posted May 27, 2020 If I go to a different page and then back to the tabulator page; it always submits a GET of page=1 when it first loads. Quote Link to comment Share on other sites More sharing options...
Barand Posted May 27, 2020 Share Posted May 27, 2020 Looks like you've got some debugging to do. We can't do that for you. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 27, 2020 Share Posted May 27, 2020 6 hours ago, mongoose00318 said: I'm trying to make it to where when a user clicks a link inside of my tabulator table, they can click the back button in their browser and my tabulator table will remember any filters, sorts, and pagination information and restore them to the exact view they had when they left the page. here's an alternative method. build the links that you output on a page, starting with a copy of any existing get parameters, plus whatever get parameters the link contributes. an example - // get a copy of the existing $_GET parameters (leave $_GET unmodified so that any other functionality on the page has access to the original values) $get = #_GET; //create link(s), such as pagination links // set the element in $get that this portion of the software is responsible for $get['page'] = x; // build the query string part the the url $qs = http_build_query($get,'','&'); // produce the link echo "<a href='?$qs'>x</a>"; by dong this, any code that produces a link only sets, modifies, or unsets the get parameters that it is responsible for, but the link carries all other existing $_GET parameters. Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 28, 2020 Author Share Posted May 28, 2020 (edited) @mac_gyver Very interesting idea. I've never used the http_build_query function. I have made some progress. After I stepped away from it for a bit and gave it some thought, I figured maybe I needed to be handling this on the front-end with the built in tabulator functions. Here is my code for that...I do have it working...sort of. //define new tabulator instance var table = new Tabulator("#production-data-table", { ajaxURL:"scripts/order_status.php?action=fetch_production_data", //ajax URL pagination:"remote", ajaxFiltering:true, ajaxSorting:true, layout:"fitColumns", columns:[ {title:"Enterprise", field:"Enterprise", sorter:"string", width:100, headerSort:false}, {title:"Job Number", field:"Job Number", sorter:"number", width:100, headerSort:false}, {title:"LN #", field:"LN #", sorter:"string", formatter:"html", align:'center', width:80, headerSort:false}, {title:"Description", field:"Description", sorter:"string", headerSort:false}, {title:"QTY", field:"QTY", sorter:"string", headerSort:false, align: 'center', width: 40,}, {title:"AS400 Ship Date", field:"AS400 Ship Date", sorter:"date", align:"center", width:100}, {title:"Exp. Ship", field:"Est Ship", sorter:"date", align:"center", width:100, headerSort:false}, //{title:"QC", field:"QC", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Pole Barn", field:"Pole Barn", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Thermoforming", field:"Thermoforming", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Vinyl/Paint", field:"Vinyl/Paint", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"FA1", field:"Fnl Asmb 1", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"FA2", field:"Fnl Asmb 2", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Crating", field:"Crating", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Shipping", field:"Shipping", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"New", field:"New", visible:false}, {title:"Revised", field:"Revised", visible:false}, ], ajaxError:function(xhr, textStatus, errorThrown){ //xhr - the XHR object //textStatus - error type //errorThrown - text portion of the HTTP status if(typeof(data) != "undefined" && data !== null) { table.clearData(); } console.debug(data); }, ajaxResponse:function(url, params, response) { var obj = JSON.parse(JSON.stringify(response)); //parse response var array_to_output = obj['tabulator_get_session']; console.debug(obj['tabulator_get_session']); console.debug(obj['current_page']); return response; }, dataLoaded:function(data) { table.setPage(<?php echo $_SESSION['tabulator_get']['pagination']['current_page']; ?>); }, rowFormatter:function(row) { var data = row.getData(); var data = JSON.parse(JSON.stringify(row.getData())); var orderNew = data['New']; var orderRevised = data['Revised']; if ( orderNew == 1 ) { row.getElement().style.backgroundColor = "#69db88"; row.getElement().style.fontWeight = "bold"; } if ( orderRevised == 1 ) { row.getElement().style.backgroundColor = "#dbd069"; row.getElement().style.fontWeight = "bold"; row.getElement().style.fontStyle = "italic"; } }, placeholder:"No Data Available", //display message to user on empty table //ajaxLoaderError:"<div>New Error new error new error</div>", }); This link was helpful: https://github.com/olifolkerd/tabulator/issues/573 It mentioned using the dataLoaded function and explained why the page resets to 1 on each load. My only problem now is it just continues to fire for some reason. https://imgur.com/C5YjjhP Is there a way to debug and figure out why it just fires over and over again? It did the same thing if I put the table.setPage within the ajaxResponse function.... If I remove the setPage function all together it stops firing repeatedly and runs as it should. The page above mentions this "Put the setPage() call AFTER the setData() in your xmlhttp.onreadystatechange listener." I don't think I have that listener... 😕 Edited May 28, 2020 by mongoose00318 Quote Link to comment Share on other sites More sharing options...
mongoose00318 Posted May 28, 2020 Author Share Posted May 28, 2020 (edited) I've tried the tableBuilt listener and I've tried calling setPage outside of where I instantiate the table. Neither has worked. When I try putting it in the tableBuilt listener like so: var table = new Tabulator("#production-data-table", { ajaxURL:"scripts/order_status.php?action=fetch_production_data", //ajax URL pagination:"remote", ajaxFiltering:true, ajaxSorting:true, layout:"fitColumns", columns:[ {title:"Enterprise", field:"Enterprise", sorter:"string", width:100, headerSort:false}, {title:"Job Number", field:"Job Number", sorter:"number", width:100, headerSort:false}, {title:"LN #", field:"LN #", sorter:"string", formatter:"html", align:'center', width:80, headerSort:false}, {title:"Description", field:"Description", sorter:"string", headerSort:false}, {title:"QTY", field:"QTY", sorter:"string", headerSort:false, align: 'center', width: 40,}, {title:"AS400 Ship Date", field:"AS400 Ship Date", sorter:"date", align:"center", width:100}, {title:"Exp. Ship", field:"Est Ship", sorter:"date", align:"center", width:100, headerSort:false}, //{title:"QC", field:"QC", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Pole Barn", field:"Pole Barn", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Thermoforming", field:"Thermoforming", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Vinyl/Paint", field:"Vinyl/Paint", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"FA1", field:"Fnl Asmb 1", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"FA2", field:"Fnl Asmb 2", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Crating", field:"Crating", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"Shipping", field:"Shipping", sorter:"string", formatter:"html", align:'center', width:101, resizable:false, headerSort:false}, {title:"New", field:"New", visible:false}, {title:"Revised", field:"Revised", visible:false}, ], ajaxError:function(xhr, textStatus, errorThrown){ //xhr - the XHR object //textStatus - error type //errorThrown - text portion of the HTTP status if(typeof(data) != "undefined" && data !== null) { table.clearData(); } console.debug(data); }, ajaxResponse:function(url, params, response) { var obj = JSON.parse(JSON.stringify(response)); //parse response var array_to_output = obj['tabulator_get_session']; console.debug(obj['tabulator_get_session']); console.debug(obj['current_page']); return response; }, rowFormatter:function(row) { var data = row.getData(); var data = JSON.parse(JSON.stringify(row.getData())); var orderNew = data['New']; var orderRevised = data['Revised']; if ( orderNew == 1 ) { row.getElement().style.backgroundColor = "#69db88"; row.getElement().style.fontWeight = "bold"; } if ( orderRevised == 1 ) { row.getElement().style.backgroundColor = "#dbd069"; row.getElement().style.fontWeight = "bold"; row.getElement().style.fontStyle = "italic"; } }, placeholder:"No Data Available", //display message to user on empty table //ajaxLoaderError:"<div>New Error new error new error</div>", tableBuilt:function() { table.setPage(<?php echo $_SESSION['tabulator_get']['pagination']['current_page']; ?>); }, }); I get the following error: production_log.php:575 Uncaught TypeError: Cannot read property 'setPage' of undefined All the reading I've done suggests I have to handle it client side because tabulator will override any thing coming from the ajax response when it first loads the page. There has to be some way to tell it to setPage when it's done loading...which is what these listeners are supposed to do but I'm doing something wrong. The dataLoaded listener does set the page for me but runs over and over again; the tableBuilt won't let me run that function in it at all. Edited May 28, 2020 by mongoose00318 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.