Introduction
ExtJS is a really cool library generating fancy looking GUI apps in JavaScript. I started using ExtJS for a bunch of database frontends and found that I needed to have a DataGrid
that would change its contents based on an AJAX call that filtered data based on some search parameters.
Notionally, this was easy enough and it appeared there may be many ways to make this happen. As it turns out, there is one right way and many - seemingly plausible - options that don't work.
After extracting this functionality from a few postings that were doing far more impressive things and trawling through the documentation, I figured it might be helpful to post a bare-bones example of this functionality to make it easy for the next ExtJS newbie who finds her/himself wanting to do the same thing.
Using the Code
The JavaScript/ExtJS portion looks like this:
Ext.onReady(function(){
Ext.QuickTips.init();
var proxy = new Ext.data.HttpProxy({
url: 'demo.data.php',
method: 'post'
});
var dstore = new Ext.data.JsonStore({
url: 'demo.data.php',
proxy: proxy,
fields: ['id', 'data'],
totalProperty: 'totalCount',
root: 'matches'
});
dstore.load();
var grid = new Ext.grid.GridPanel({
store: dstore,
columns: [
{id:'id', header: "Id", width: 60, sortable: true, dataIndex: 'id'},
{id: 'data', header: "Data", width: 200, sortable: true, dataIndex: 'data'}
],
stripeRows: true,
autoExpandColumn: 'data',
height:350,
width: 500,
title:'Demo Data'
});
var search = new Ext.FormPanel({
labelWidth: 150,
frame:true,
title: 'Search Demo Data',
bodyStyle:'padding:5px 5px 0',
width: 500,
defaults: {width: 230},
defaultType: 'textfield',
items:
[{
fieldLabel: 'Search regular expression',
name: 'pattern',
id: 'pattern'
}],
buttons: [{
text: 'Search',
handler: function() {
dstore.load({
params: {
pattern: document.getElementById('pattern').value
}});
}
}]
});
search.render('search_form');
grid.render('search_results');
});
The backend datasource (which happens to be from PHP) looks like this:
<?php
$items = Array(Array('id'=>1, 'data' => 'the first item'),
Array('id'=>2, 'data' => 'the second item'),
Array('id'=>3, 'data' => 'one fish'),
Array('id'=>4, 'data' => 'two fish'),
Array('id'=>5, 'data' => 'red fish'),
Array('id'=>6, 'data' => 'blue fish')
);
$matches = Array();
if(!isset($_REQUEST['pattern']) || $_REQUEST['pattern'] == '') {
$matches = $items;
} else {
foreach ($items as $item) {
if (eregi($_REQUEST['pattern'], $item['data'])) {
$matches[] = $item;
}
}
}
echo json_encode(Array('totalCount' => count($matches),
'matches' => $matches
)
);
?>
The HTML file (that really is just the standard stuff) is included in the ZIP file.
Points of Interest
MySQL/PHP Backend Data Source
For those looking to load database data (probably MySQL for PHP folk) into an ExtJS JSONStore, the PHP file supplies most of what you need to know. Basically you want an array of data that you then encode with json_encode(...)
. For MySQL, building the data would look a bit like:
$data = Array();
$qry = mysql_query("SELECT id, description FROM ...");
while ($vals = mysql_fetch_array($qry)) {
$data[] = Array('id' => $vals['id'], 'description' => $vals['description'];
}
echo json_encode($data);
Paging Control on DataGrid
If you are using a paging control on the grid, then you will want the parameters that are sent to the DataStore
to persist between calls (i.e. for when they press the paging buttons to retrieve the next page of data). To do this, you need to set the baseParams
property on the datastore
rather than sending parameters via the params
object of the load(...)
call. A real world example is shown below:
function search_submit() {
dstore.baseParams = {
number: document.getElementById('number').value,
title: document.getElementById('title').value,
keywords: document.getElementById('keywords').value,
typeid: document.getElementById('typeid').value,
allversions: (document.getElementById('allversions').checked) ? 1 : 0,
};
dstore.load({
params: {
start: 0,
limit: 25
}
});
}
HIstory
- 23-Jul-2008 - PJC - First posted
Paul is a serial entrepreneur with a strong technical background. In 2008 he co-founded Lumient Pty Ltd which provides bespoke software development services across a which range of industries. In 2018 he co-founded Data Effects Pty Ltd which has grown quickly to be a world-leader in biosecurity surveillance technologies. Between 2013 and 2018 he was also the co-owner / co-director of Daelibs Pty Ltd and oversaw the companies transition to state-of-the-art time and attendance tracking that included the roll out of the world’s first implementation of location tracking based on Bluetooth beacons.
From the technical standpoint Paul has been the solution architect for a range of large software systems that are used by companies including Medibank, Bosch, Zeiss, Elders, Remondis, Resthaven, Wilson Security & SA Water.