Jump to content

Remembering Tabulator $_GET vars in a Session


mongoose00318
 Share

Recommended Posts

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?

Link to comment
Share on other sites

$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
Link to comment
Share on other sites

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 by mongoose00318
Link to comment
Share on other sites

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;

 

Link to comment
Share on other sites

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. 

Link to comment
Share on other sites

@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 by mongoose00318
Link to comment
Share on other sites

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 by mongoose00318
Link to comment
Share on other sites

This thread is more than a year old.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.