In this article I will demonstrate how to create a basic EXTJS grid on your XPages website. I will go through each step of the process and once complete this will be the reference for all following articles on how to do it.
Introduction
EXTJS is a JavaScript library. Well ok to be clear it is MANY JavaScript libraries which can all be added to your XPages in the same way. I will show you where to find the files, how to add them to your Domino database and then how to use the Extension Library REST service to put your first grid on your XPage.
Sencha
“Originally built as an add-on library extension of YUI by Jack Slocum, Ext JS includes interoperability with jQuery and Prototype. Beginning with version 1.1, Ext JS retains no dependencies on external libraries, instead making their use optional.”
Licensing
Sencha has two licenses commercial and GPL. For the sake of this blog I am working under the GPL license because everything is being made public. If you want to use the grid for your work you will need to pay for it. A developer pack is $600 each and at a commercial XPages developers charge out rate that is less than a day….I think it will make you more productive!
Downloading
Go to the download page and download the appropriate copy of the whole library (45M-ish).
Getting it into your Database
Once downloaded, unzip the file and get the contents on your machine. That is 210M of unreal goodness and excessive volume and we REALLY don’t need to bloat our database with all that. So delete all the folders except resource and src and remove all the js files until you are left with the extjs files and the license….
That has got us down to about 30M of files which is still a LOT but they are not going to be loaded into your webpage all at the same time so don’t fret about it
Then drag and drop the root folder into your databases WebContents folder. This can be found in the Package Explorer via the XPage perspective in 8.5.3 or Window/Show Eclipse Views/Java in <8.5.3.
Asynchronous Module Definition
As you may know with the dojo libraries there is a methodology called “Asynchronous Module Definition (AMD)” which allows a JavaScript application to load in the modules that it needs – and this rocks! What is also means is that (and I know some of you were thinking it) you are not going to load “30M” worth of files onto your webpage at any time.
Building an XPage
On your XPage you will need to reference the EXTJS library to make sure that is included in your webpage resources. This is done by simply adding the following code to the XPage:
<script type="text/javascript" src="ext-4.1.1/ext-all-debug.js"></script> <link href="ext-4.1.1/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
This also adds the basic stylesheet to the grid as well (more on that in a later blog post) Once that is added to the XPage then we are all ready to start……
Looking at the examples
As I mentioned in my first article – you really should go look at the examples page in this case specifically the grids section. In there you should poke around and look at the code, terrifying as it may be it really shouldn’t be and as we go through this blog series I will explain and simply all the examples. In this case I am going to look at the RESTful Store example Clicking on the restful.js link you will see all the code used int his example. I am not going to go into the code itself in this example, suffice as to say you just need to copy and paste 🙂
Creating a grid from a REST service
We are going to start our XPage with Dave Leedy’s fakenames first name view from that we are going to look at the view in Designer, specifically at the programmatic names of the columns.
As you can see from the image above, each of the columns has a programmatic use name. This is important to remember and necessary to change sometimes.
The REST service.
The REST service is added to an XPage in the following manner – (you must have the Extension Library installed on the client and the server to make this happen). This is the code on my xRestService XPage for the ByFirstName feed. Very simple and sends 100 documents out in JSON format
<xe:restService id="by-FirstName" pathInfo="byFirstName"> <xe:this.service> <xe:viewItemFileService viewName="ByName-First" count="100" defaultColumns="true" systemColumns="132"> </xe:viewItemFileService> </xe:this.service> </xe:restService>
Looking at the REST service through a URL call we see the following format for the output:
{ "@timestamp":"2013-02-23T06:53:34Z", "@toplevelentries":1300, "items": [ { "@entryid":"1-66F3A5FE2B2A38CC85257B1B00254E6D", "@unid":"66F3A5FE2B2A38CC85257B1B00254E6D", "@noteid":"688E", "@position":"1", "@siblings":1298, "firstname":"Adam", "lastname":"Saenz", "address":"2519 Custer Street", "city":"ROCKWOOD (SOMERSET)", "state":"PA", "zip":15557, and so on, }, { "@entryid":"2-3857882D6726A78F85257B1B00254F1C", "@unid":"3857882D6726A78F85257B1B00254F1C", "@noteid":"6B4A", "@position":"2", and so on,
Adding the Grid to the XPage I have simplified the example given on the Sencha site so that we can just see the bare bones of the grid. As we go through th series I will add more and more complication into the grids so that we can see how they work. The grid code is built up of multiple components:
- Require the necessary EXTJS libraries
- Defining a People Object
- Creating the data store
- Getting the grid data from the REST service
- Applying the data to the grid in columns
So let’s look at the code The AMD part
Ext.require(['Ext.data.*', 'Ext.grid.*']);
The Person Object In here we define the fields ‘firstname’, ‘lastname’, ‘address’, ‘city’, ‘state’. These field names relate to the names of the fields coming in through the REST service JSON string and therefore directly to the programmatic column name in the view (told you it was important)
Ext.define('Person', { extend: 'Ext.data.Model', fields: [{ 'firstname', 'lastname', 'address', 'city', 'state'] });
The Data Store In this section the data Store is created which is used to populate the grid. The store: defines the Person Object (above) as the model to display the information sets up the connection to get the REST service from the ‘xRestService.xsp/byFirstName’ URL
var store = Ext.create('Ext.data.Store', { autoLoad: true, autoSync: true, model: 'Person', proxy: { type: 'rest', url: 'xRestService.xsp/byFirstName', reader: { type: 'json', root: 'items' }, writer: { type: 'json' } } });
The Grid itself Finally we build the grid – and the grid parameters define what it looks like – I have added comments to the code so that you can see in place what each section is doing
var grid = Ext.create('Ext.grid.Panel', { renderTo: 'gridHere', //render to the id named gridHere width: 600, //width of the grid height: 300, //height of the grid frame: true, title: 'Users', //Grid title at the top store: store, //Store object iconCls: 'icon-user', //icon for the title columns: [{ //for each column in the grid define the attributes of the column header: 'First', //Column Header Title width: 80, //Column width sortable: true, //Is the column sortable? dataIndex: 'firstname', //what is the data field in the JSON used to fill this column field: { //what type of field is this? xtype: 'textfield' } }, { text: 'Last', width: 80, sortable: true, dataIndex: 'lastname', field: { xtype: 'textfield' } }, { text: 'Address', width: 80, sortable: true, dataIndex: 'address', field: { xtype: 'textfield' } }, { text: 'City', width: 80, sortable: true, dataIndex: 'city', field: { xtype: 'textfield' } },{ text: 'State', width: 80, sortable: true, dataIndex: 'state', field: { xtype: 'textfield' } }] }); });
And there it is – you add all the above in a SCRIPT tag on the XPage the code for you first grid. We also add a little CSS to show the icon for the image and a div as a container. This is not the “best” way to do it, and we will discuss that in a later article but for the moment it is the easiest to understand being in the same XPage.
<script type="text/javascript" src="ext-4.1.1/ext-all-debug.js"></script> <link href="ext-4.1.1/resources/css/ext-all.css" rel="stylesheet" type="text/css" /></pre> <style><!-- .icon-user { background-image: url(images/user.png) !important; } .icon-add { background-image: url(images/add.png) !important; } .icon-delete { background-image: url(images/delete.png) !important; } --></style> <pre> <script type="text/javascript">// <![CDATA[ Ext.require(['Ext.data.*', 'Ext.grid.*']); Ext.define('Person', { extend: 'Ext.data.Model', fields: [{ name: 'id', type: 'int', useNull: true }, 'firstname', 'lastname', 'address', 'city', 'state'] }); Ext.onReady(function(){ var store = Ext.create('Ext.data.Store', { autoLoad: true, autoSync: true, model: 'Person', proxy: { type: 'rest', url: 'xRestService.xsp/byFirstName', reader: { type: 'json', root: 'items' }, writer: { type: 'json' } } }); var grid = Ext.create('Ext.grid.Panel', { renderTo: 'gridHere', width: 600, height: 300, frame: true, title: 'Users', store: store, iconCls: 'icon-user', columns: [{ header: 'First', width: 80, sortable: true, dataIndex: 'firstname', field: { xtype: 'textfield' } }, { text: 'Last', width: 80, sortable: true, dataIndex: 'lastname', field: { xtype: 'textfield' } }, { text: 'Address', width: 80, sortable: true, dataIndex: 'address', field: { xtype: 'textfield' } }, { text: 'City', width: 80, sortable: true, dataIndex: 'city', field: { xtype: 'textfield' } },{ text: 'State', width: 80, sortable: true, dataIndex: 'state', field: { xtype: 'textfield' } }] }); }); // ]]></script></pre> <div id="gridHere"></div> <pre>
Demonstration
The EXTJS in XPages demonstration database can be found at http://demo.xomino.com/xomino/extjs.nsf
You will note that the menu does not look right – I know – one thing to discuss with the grids – their stylesheets…..we will see 🙂
This was tested in IE9, Safari, Chrome, Firefox, Chrome on Android and iPhone/iPad
Play with the columns and see what they can do – I will post again soon to discuss the capabilities of the basic grid further.
Download
The sample database that will accompany this series will always be available from the menu in the live demo database from this link – http://demo.xomino.com/xomino/Extjs.nsf
Conclusion
I think it is safe to say that this is a simple, fantastic, aesthetically pleasing, way of showing data on the screen to the users and hopefully this was a simple enough process to follow along with. This is a simple grid with not much functionality but as we will come to see – there are w whole world of different capabilities within the EXT grids and their plugins 🙂