OK, in our last two posts we built a basic grid and populated it with data. As you can see, so far it's a very basic grid.

Nothing much to it, really. Let's start adding a few important pieces. jqGrid includes a large set of Column Model Options, but there really aren't a ton that you'll need. Here we'll run through some basics.

First, the id field really isn't something you typically need to show anyone. So, just hide it.

jqGridDemo.js - Column Model - Hide

view plain print about
1colModel: [
2    {name: 'ID', hidden: true},
3    ...
4],

Oh yeah, and the views column is a count of the number of page views. As a number, it should probably be right justified.

jqGridDemo.js - Column Model - Align

view plain print about
1colModel: [
2    ...
3    {name: 'VIEWS', align: 'right'}
4],

Great! But that column is way too wide! Without any additional info, jqGrid will attempt to size the columns according to their data, and currently it's just making three even columns. Let's size it down.

jqGridDemo.js - Column Model - Width

view plain print about
1colModel: [
2    ...,
3    {name: 'VIEWS', align: 'right', width: 60, fixed: true}
4],

Alright! We've set a 'fixed' width, so that any resizing of the grid (even automatic resizing) will maintain the set column width. We set it to give full width of the column title, as well as some room for the sort markers when the column is being sorted.

Now let's talk about three options that can be somewhat confusing: index, label and name. Up until now we've used the name option, which has mirrored the column name being returned. However, we might want our column header to be different than the actual column name. For this, we use the label option.

jqGridDemo.js - Column Model - Label

view plain print about
1colModel: [
2    ...,
3    {name: 'POSTED', label: 'Release Date'}
4],

This changed the label used in the column header, while maintaining a reference used when sorting the grid by the posted field. This is good, until you do something like this:

jqGridDemo.js - Column Model - Remap

view plain print about
1grid.jqGrid('setGridParam',{remapColumns:[
2    gridCols['ID'] + gridMultiSelect,
3    gridCols['ID'] + gridMultiSelect,
4    gridCols['TITLE'] + gridMultiSelect,
5    gridCols['POSTED'] + gridMultiSelect,
6    gridCols['VIEWS'] + gridMultiSelect
7]});

jqGridDemo.js - Column Model - Index

view plain print about
1colModel: [
2    {name: 'ID', hidden: true},
3    {name: 'Action', index: 'ID', label: 'Action', width: 80, fixed: true, sortable: false, align: 'center'},
4    {name: 'Title'},
5    {name: 'Posted', label: 'Release Date'},
6    {name: 'Views', align: 'right', width: 60, fixed: true}
7],

"Cutter, What are you doin' ta me!?!" Yeah, now it's confusing. I've added a column. A column that also references the ID field in the return dataset. In this instance the index really isn't truly necessary, but I'll try to explain it for you anyway. Up until now, jqGrid has used the name option as the value that is passed back to the server on a sort request. Here's the thing though: each column has to have a unique reference. That's what the name option is for; being a unique column reference within jqGrid. So, if you have two columns whose underlying data is the same (as it shows you in our new Remap config), then you need a unique reference for jqGrid (the name), and the index field reference that jqGrid will send back to the server on sort requests (again, with the sortable: false I've thrown in here, it's really moot for us). So, to recap:

  • name - A unique column reference used by jqGrid
  • index - A data field reference used in sort requests. If not present then the name is used.
  • label - If present it will override the name option, for what to display in the column header.

You probably noticed that I added a little something to our column remap code.

view plain print about
1gridCols['ID'] + gridMultiSelect,

This goes along with a new variable I added to our global variable declarations at the very top of our script.

view plain print about
1var gridCols = {set:false},
2    gridMultiSelect = 0;

I'll probably not use that on this round, but it will become important, so I'll leave it for now.

Column Formatting

Now that we've talked about some of the more important column options, let's get into column formatting. Now that we've added some configuration you'll notice a new Action column. Right now, if you ran your template, you'd see a truncated ID value in the cells. We'll need that ID in our output, but the Action column we're building will be used to display action icons (edit, delete, etc). jqGrid has functions for doing this, if you're using it's edit packages, but my app has custom editors for a lot of this data, so we'll apply a custom column formatter to show these action icons.

jqGrid provides predefined formatters for many things, but you can also create your own custom formatters to create your own cell templates. A custom formatter is just a function, applied through the column model, that returns the string to be displayed in the cell. Your function will take three arguments, cellvalue, options, and rowObject. The cellvalue is the value of the data that jqGrid is trying to apply to the cell (in our case, a record's ID). The options is an object containing the rowId and the colModel of the record being applied. The rowObject is the data for the entire row of the record being applied.

jqGrid provides the ability to apply these functions as extensions of it's built in formatter package. Let's write a basic actionFormatter function that returns just the first two characters of the ID field, to get started.

jqGridDemo.js - actionFormatter - figure 1

view plain print about
1$.extend($.fn.fmatter, {
2    actionFormatter: function(cellvalue, options, rowObject) {
3        return cellvalue.substr(0,2);
4    }
5});

jqGridDemo.js - Column Model - Custom Formatter

view plain print about
1colModel: [
2    ...
3    {name: 'Action', index: 'ID', label: 'Action', width: 80, fixed: true, sortable: false, align: 'center', formatter: 'actionFormatter'},
4    ...
5],

That was easy! You see now how we get to value being applied to the cell. Now let's really change it up, by applying the custom output we discussed before. First, we need the style references to the icons we're going to use.

jqGridDemo.css - icons

view plain print about
1/* Basic layout of all trigger icons */
2.icon-trigger { margin: 2px; vertical-align: middle; display: inline-block; width: 16px; height: 16px; }
3.action-trigger { cursor: pointer; }
4.disabled-trigger {opacity:0.4;filter:alpha(opacity=40)!important;}
5
6/* delete icon image for trigger */
7.delete { background: url('/resources/images/icons/delete.png') no-repeat scroll 0px 0px transparent !important; }
8
9/* pencil icon image for trigger */
10.pencil { background: url('/resources/images/icons/pencil.png') no-repeat scroll 0px 0px transparent !important; }

For our demo, I'm using the highly useful FamFamFam Silk icon library. Here I've defined some classes for the display of icon 'triggers', or icons that are used as buttons for actions. Next, we'll adjust our actionFormatter to apply the proper output.

jqGridDemo.js - actionFormatter - figure 2

view plain print about
1$.extend($.fn.fmatter, {
2    actionFormatter: function(cellvalue, options, rowObject) {
3        var retVal = "<span class=\'icon-trigger action-trigger pencil\' rel=\'" + cellvalue + "\' \/>";
4        retVal += "<span class=\'icon-trigger action-trigger delete\' rel=\'" + cellvalue + "\' \/>";
5        return retVal;
6    }
7});

As you can see, now when you re-run your template you have a nice, formatted Action column, with action icons for 'edit' and 'delete'.

So, in this post we covered some of the more important Column Model display options, as well as creating a custom column formatter. In our next entry we'll tie some functions to our 'action icons', and talk about row selection options. You can find sample code attached in the Download link at the bottom of the page.