Saturday 31 January 2015

Dynamic Table using jQuery

One of the most requested features using JavaScript, is to dynamically add or remove rows from a table.
I've made a repo on github, and I've made use of the following components.

  1. TextBox
  2. Checkbox
  3. Radio button
  4. Single Select
  5. Multi Select
  6. Datepicker

You could add a TextArea too, and it should work just fine.

Here's how it looks like,

















Check out my repository for the full source. DynoTable - Github

Happy coding!

Monday 16 June 2014

ExtJS grids with Editors

Of all the grids till now, we never allowed user input. The editor grid allows the user to add/modify row elements.

Creating an editor grid is very simple. Redeclare the GridPanel to EditorGridPanel. Then assign an editor to those fields which can allow edits.

Here’s what we will build in this post,




The modified grid,

var grid = new Ext.grid.EditorGridPanel({
store: empStore,
columns: [
{header: 'Emp No.', width: 100, sortable: true, dataIndex: 'emp_no', align:'center', renderer: showEmpDetails},
{header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name',
editor: new Ext.form.TextField({ allowBlank: false }) },
{header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name',
 editor: new Ext.form.TextField({ allowBlank: false }) },
{header: 'Age', width: 75, sortable: true, dataIndex: 'age',
editor: new Ext.form.NumberField({
                                allowBlank: false,
                                allowNegative: false,
                                maxValue: 100
}) },
{header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj',
editor: new Ext.form.DateField({
                                                format: 'm/d/Y',
                                                minValue: '01/01/2009'
                                }) },
{header: 'Address', width: 150, dataIndex: 'address',
editor: new Ext.form.TextField({ allowBlank: true }) }
],
            stripeRows: true,
height: 350,
width: 650,
title: 'Employee Details',
            renderTo: Ext.getBody()
});


Double clicking on any cell will reveal the editor.

NOTE:
1.  No editor has been defined for the first column, assuming it to be a primary key
2. Setting the config option (for EditorGridPanel) “clicksToEdit” to ‘1’ will make each cell editable on the very first click. By default it is set to 2


Here’s the JSFiddle ->  Editor Grid JSFiddle

Friday 6 June 2014

ExtJS grids with Grouping GridView


Grid data can also be grouped based on data present for a column. Consider the employee grid, there may be many employees who are in the same age group. It is possible to list down employee details grouped by “Age”.


Here’s what we will build in this post,




NOTE: Grouping GridView is achieved straight out of the box. There is no extra js/css to include here.


The modified grid,

var grid = new Ext.grid.GridPanel({
        store: empStore,
        columns: [
                        {header: 'Emp No.', width: 100, sortable: true, dataIndex: 'emp_no', align:'center', renderer: showEmpDetails},
                        {header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
                        {header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
                        {header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
                        {header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'},
                        {header: 'Address', width: 250, dataIndex: 'address'}
        ],
        view: new Ext.grid.GroupingView({
                        groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
        }),
        stripeRows: true,
        height: 350,
        width: 650,
        title: 'Employee Details',
        renderTo: Ext.getBody()
       });


The field mapping is provided in the reader defined below,
               
var empReader = new Ext.data.JsonReader({}, [
                                   {name: 'last_name'},
                                   {name: 'first_name'},
                                   {name: 'emp_no'},
                                   {name: 'age', type: 'int'},
                                   {name: 'doj', type: 'date', dateFormat: 'm/d/Y'},
                                   {name: 'address'}
                ]);



The store needs to be redefined as,

var empStore = new Ext.data.GroupingStore({
reader: empReader,
data: empData,
sortInfo:{field: 'emp_no', direction: "ASC"},
groupField:'age'
       });



That’s it we are done with our grid with the ability to group rows based on a decided column.

Here’s the JSFiddle -> ExtJS Grouping GridView

NOTE:

  1. It is also possible to sort data (by clicking on the column header) after they are grouped.
  2. You can also group data based on another column other than "age". Invoke the header menu on any column and notice the option "Group by this field".

Monday 7 April 2014

ExtJS grids with Locking Columns

There may be grids where in two or more columns are required to be shown at all times even if there are many columns available. In such a scenario, we can lock a few columns which will prevent them from getting hidden when attempting to scroll sideways along the grid. A similar functionality is present in MS Excel where in a column can be locked from scrolling away.


Here’s what we will build in this post.




To use locking functionality we must explicitly specify the LockingColumnModel and the LockingGridView.

NOTE: Two imports need to be added for the locking grid to work.

<link rel="stylesheet" type="text/css" href="../ux/css/LockingGridView.css" />
<script type="text/javascript" src="../ux/LockingGridView.js"></script>

The modified grid,

var grid = new Ext.grid.GridPanel({
                store: empStore,
                colModel: new Ext.ux.grid.LockingColumnModel([
                                {header: 'Emp No.', width: 100, sortable: true, dataIndex: 'emp_no', align:'center', renderer: showEmpDetails, locked: true},
                                {header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name', locked: true},
                                {header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
                                {header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
                                {header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'},
                                {header: 'Address', width: 400, dataIndex: 'address'}
                ]),
                stripeRows: true,
                height: 350,
                width: 400,
                title: 'Employee Details',
                view: new Ext.ux.grid.LockingGridView(),
                renderTo: Ext.getBody()
});


Setting ‘locked’ to “true” for a column would prevent it from getting hidden on scrolling.

The user would also be allowed to decide on which columns to lock, unlock. Clicking on the column header would show up two mutually exclusive options, Lock and Unlock.

Columns already locked can be unlocked by the user and vice versa.

Here’s the JSFiddle -> JSFiddle Locking Grid

Wednesday 2 April 2014

ExtJS grids with cell & row renderers

In this post I will focus on cell and row renderers. It is often desired to provide external references to the data present on the grid. One simple way is to present the user with a hyperlink on selected columns. This is made possible using a cell renderer.



Here’s the modified columns array definition.


columns: [
{header: 'Emp No.', width: 100, sortable: true, dataIndex: 'emp_no', align:'center', renderer:  showEmpDetails},
{header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
{header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
{header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
{header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'}
]

The renderer function is defined as,

function showEmpDetails(val, meta, rec, rIndex, cIndex, store) {
return "<a href='#'>" + val + "</a>";
//or apply any css class of your choice using
//meta.css = ‘awesome-header-style’
//return val;
}

Here's the JSFiddle -> JSFiddle Row renderer

NOTE: The renderer function should return only ‘html’ content.

Similarly, Rows on the grid can be made to appear in colors other than white/grey.
Consider the employee grid. We could indicate senior employees (age >=27) with a yellow background.





Here’s the modified grid definition,

var grid = new Ext.grid.GridPanel({
store: empStore,
            columns: [
                                {header: 'Emp No.', width: 100, sortable: true, dataIndex: 'emp_no', align:'center', renderer: showEmpDetails},
                                {header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
                                {header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
                                {header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
                                {header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'}
                ],
                viewConfig: {
                                //Return CSS class to apply to rows depending upon data values
                                getRowClass: function(record, index) {
                                                var c = record.get('age');
                                                if (c >= 27) {
                                                                return 'senior';
                                                }
                                }
                },
                stripeRows: true,
                height: 350,
                width: 530,
                title: 'Employee Details',
                renderTo: Ext.getBody()
});

The CSS class ‘senior’ is defined as,

<style>
        .senior {
               background-color: #FFFF00
        }

</style> 

Here's the fiddle -> JSFiddle Row renderer

Friday 28 March 2014

ExtJS grid with numbering & checkbox selection

In this 2nd post I will be enhancing the grid we created in the previous post.
How about adding row numbers to our view? We modify the columns array to hold a new member.

columns: [
new Ext.grid.RowNumberer(),
{id:'company',header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
{header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
{header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
{header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'}
]

Here’s the demo,


Here’s the link to the fiddle -> JSFiddle row numbering

By default multiple rows of the grid can be selected by holding down the “Ctrl” button. To disable multi select of rows add the following selection model to the grid.

sm: new Ext.grid.RowSelectionModel({ singleSelect:true })

Selecting multiple rows of a grid can be helpful. But to provide a better visual treatment rather than highlighted rows use a “CheckBoxSelectionModel”.

Here’s the modified grid code,

var sm = new Ext.grid.CheckboxSelectionModel();               
var grid = new Ext.grid.GridPanel({
store: empStore,
columns: [
        sm,   //this is to provide the checkbox for every row
        new Ext.grid.RowNumberer(),
        {header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
        {header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
        {header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
        {header: 'Date of Joining', width: 100, sortable: true, renderer:        Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'}
],
sm: sm,  //sm is short for “selModel”
stripeRows: true,
height: 350,
width: 430,
title: 'Employee Details',
renderTo: Ext.getBody()
});

Demo below,


Grab the fiddle -> JSFiddle checkbox


Thursday 27 March 2014

Simple Grid using Ext JS

This blog post assumes you have a little background on Ext JS basics. If not I recommend you to head over to Sencha’s site and have a look at the documentation or even better follow a book.

But this is not rocket science either. A strong foundation in JavaScript is enough to get started.Grid data are very important for the user as most common information display is tabular. Grids or Data grids are made possible by using the class “Ext.grid.GridPanel”.

The following series of blog posts are written following Ext JS version 3.4. Migrating them to the latest version is not hard either. Subsequent posts will improve upon this grid by adding features incrementally. At the end you’ll realize how awesome the framework is.

This is what we will be building by the end of this post.

Let’s start by defining the sample data for the employee database. For the sake of simplicity, lets hardcode our data inside the application.

var empData = [
                       {'last_name':'Doe', 'first_name':'John', 'age':'23', 'doj':'08/06/2009'},
                       {'last_name':'Sparrow', 'first_name':'Jack', 'age':'26', 'doj':'08/12/2010'},
                       {'last_name':'Spacey', 'first_name':'Kevin', 'age':'27', 'doj':'01/23/2011'},
                       {'last_name':'Gates', 'first_name':'Bill', 'age':'35', 'doj':'10/10/2006'}
            ];

Next up we define the store. The store is nothing but a container of records. Each record is nothing but the actual data present in each row.

var empStore = new Ext.data.JsonStore({
                        fields: [
                             {name: 'last_name'},
                             {name: 'first_name'},
                             {name: 'age', type: 'int'},
                             {name: 'doj', type: 'date', dateFormat: 'm/d/Y'}
                         ],
                         data: empData
            });

Next up we define the actual grid,

var grid = new Ext.grid.GridPanel({
store: empStore,
            columns: [
                   {header: 'Last Name', width: 100, sortable: true, dataIndex: 'last_name'},
                   {header: 'First Name', width: 100, sortable: true, dataIndex: 'first_name'},
                   {header: 'Age', width: 75, sortable: true, dataIndex: 'age'},
                   {header: 'Date of Joining', width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'doj'}
                ],
             stripeRows: true,
             height: 350,
             width: 400,
             title: 'Employee Details',
             renderTo: Ext.getBody()

});

In the above code,

  1. The “empStore” we just defined is associated with the GridPanel. This connects the store to the actual display grid. Store is not a display component but a behind the scenes prompter. Without it the grid probably does nothing.
  2. We’ve declared the columns for the grid using the columns array. “dataIndex” is the glue which defines the mapping between the record data and the column in which it is supposed to show.
  3. The “renderTo” specifies which DOM elements which would contain this grid. In our case, we chosen the page body.
  4. Setting ‘sortable’ to “false” will disable sorting on that particular column.
  5. Setting ‘stripeRows’ to “false” will not show any difference in row color between consecutive rows.
We're done. Here’s the working fiddle -> JSFiddle ExtJS Simple Grid