Adding buttons to JQGrid toolbar

As I have wrote in my previous article, JQGrid is one of the most powerful JQuery plug-ins used in creation of grids. Though JQGrid provides most of the functionality out of box, there are certain things for which we might need to extend. I came across one such requirement a week before.

JQGrid add buttons, like search to the navigator (pager) component. This navigator component is placed below the table. As far as user experience (UE) is considered action items needs to be placed at the top of the grid for easier accessibility (and many other reasons,  which I am not much aware of, comment if you are). So I started to dig in to JQGrid documents and source to achieve this. During this time, Rama pointed me about the toolbar option.  But there is no API in JQGrid to add buttons with the same look and feel as navigator buttons in toolbar (readers comment if you find any). This gave me a chance to extend JQGrid plug-in for this functionality.  With sometime over the weekend, I am able to achieve the same. Here, I share the code with you

Note: Updated code at end of post
/*
 * Add functionality to add buttons to toolbar instead of pager
 * Why can't we use the navButtonAdd method by passing toolbar as the element
 * 	1. By default toolbar:[true,"both/top/bottom"] adds a div perfectly between the table caption and header. But there is not table within this div. Due to this structure difference we can't make use of navButtonAdd
 *      2. We can go ahead by appending table inside toolbar div and then reusing navButtonAdd. But that still needs some more customziation. So went ahead with a new method
 */
$.fn.extend({
/*
 *
 * The toolbar has the following properties
 *	id of top toolbar: t_
<tablename>
 *	id of bottom toolbar: tb_
<tablename>
 *	class of toolbar: ui-userdata
 * elem is the toolbar name to which button needs to be added. This can be
 *	#t_tablename - if button needs to be added to the top toolbar
 *	#tb_tablename - if button needs to be added to the bottom toolbar
 */
    toolbarButtonAdd: function(elem,p){
       p = $.extend({
                caption : "newButton",
                title: '',
                buttonicon : 'ui-icon-newwin',
                onClickButton: null,
                position : "last"
              }, p ||{});
        var $elem = $(elem);
 	var tableString="
<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"table-layout: fixed;\">";
	tableString+="
<tbody>
<tr></tr>
</table>
";

      /*
	* Step 1: check whether a table is already added. If not add
	* Step 2: If there is no table already added then add a table
	* Step 3: Make the element ready for addition to the table
	* Step 4: Check the position and corresponding add the element
	* Step 5: Add other properties
	*/
        return this.each(function() {
		if( !this.grid)  { return; }
		if(elem.indexOf("#") != 0) {
			elem = "#"+elem;
		}
		//step 2
		if($(elem).children('table').length === 0){
			$(elem).append(tableString);
		}
		//step 3
		var tbd = $("
<td></td>
");
		$(tbd).addClass('ui-pg-button ui-corner-all').append("
<div class='ui-pg-div'><span class='ui-icon "+p.buttonicon+"'></span>"+p.caption+"</div>
").attr("title",p.title  || "")
	    .click(function(e){
		if ($.isFunction(p.onClickButton) ) {  p.onClickButton(); }
		return false;
		})
             .hover(
		function () {$(this).addClass("ui-state-hover");},
		function () {$(this).removeClass("ui-state-hover");}
		);
		if(p.id) {$(tbd).attr("id",p.id);}
		if(p.align) {$(elem).attr("align",p.align);}
		var findnav=$(elem).children('table');
		if(p.position ==='first'){
			if($(findnav).find('td').length === 0 ) {
				$("tr",findnav).append(tbd);
			} else {
				$("tr td:eq(0)",findnav).before(tbd);
			}
		} else {
			$("tr",findnav).append(tbd);
		        }
	});//this.each()
     }
});

I hope there is no rocket science in the above code, so I am not explaining it here. The toolbarButtonAdd function will be more or less the same as navButtonAdd function in grid.formedit.js. One extra option that I have introduced is align. I have introduced this option to align the button in toolbar based on user preference. Align could take left, right, center.  I hope, MAC users will be more comfortable with buttons in left and Windows/nix users are comfortable with toolbars in right. Note: The element should point to the toolbar div. The id of the toolbar div depends upon the position as follows,

    Top toolbar: t_<tableid>

Bottom toolbar: tb_<tableid>   Sample Usage:

$('#mysimpletable')
.toolbarButtonAdd("#t_mysimpletable",{caption:"Toggle",position:"first",
title:"Toggle Search Toolbar", align:"right", buttonicon :'ui-icon-search', onClickButton:function(){ mygrid[0].toggleToolbar(); } })

Let me know your comments on the above piece of toolbarButtonAdd function.
Now, I am working on unit-testing and code coverage tools for JS.  So you could soon expect a blog on the same.
Update 24-jul-2009 - New code is available at
Updated 13-Aug-2009 - Support for IE http://snippets.dzone.com/posts/show/7629
Add to FacebookAdd to NewsvineAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Furl

About these ads

13 Responses

  1. Can you give a bit more info please? I’m new to jquery.

    1) In your sample usage is #mysimpletable the existing I turn into a jqgrid eg;

    $(“#mysimpletable”).jqGrid(…

    2) Is #t_mysimpletable the id I want the toolbar to have when it is created? Does #t_mysimpletable need to exist before I call .toolbarButtonAdd()?

    Thanks

  2. @gaz 1. correct, $(”#mysimpletable”) points to the table
    2. Yes it should exist. Refer Tip 10 in http://veechand.wordpress.com/2009/07/13/10-jqgrid-tips-learned-from-my-experience/

  3. Excellent site, keep up the good work. I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I’m glad I found your blog. Thanks,

  4. To add a separator ( because it can be useful :) ), you can add this function :

    toolbarSeparatorAdd:function (elem,p) {
    p = $.extend({
    sepclass : “ui-separator”,
    sepcontent: ”
    }, p ||{});
    return this.each(function() {
    if( !this.grid) { return; }
    if( elem.indexOf(“#”) != 0) { elem = “#”+elem; }
    //step 2
    if($(elem).children(‘table’).length === 0){
    $(elem).append(tableString);
    }
    //step 3
    var tbd = $(“”);
    $(tbd).addClass(‘ui-pg-button ui-corner-all’).append(“”+p.caption+””).attr(“title”,p.title || “”)
    .click(function(e){
    if ($.isFunction(p.onClickButton) ) { p.onClickButton(); }
    return false;
    })
    .hover(
    function () {$(this).addClass(“ui-state-hover”);},
    function () {$(this).removeClass(“ui-state-hover”);}
    );
    if(p.id) {$(tbd).attr(“id”,p.id);}
    if(p.align) {$(elem).attr(“align”,p.align);}
    var findnav=$(elem).children(‘table’);
    var sep = “”+p.sepcontent+””;
    if(p.position ===’first’){
    if($(findnav).find(‘td’).length === 0 ) {
    $(“tr”,findnav).append(sep);
    } else {
    $(“tr td:eq(0)”,findnav).before(sep);
    }
    } else {
    $(“tr”,findnav).append(sep);
    }

    });
    }

  5. @Laurent yep for sure it will be useful. Thanks for your contribution

  6. no problem, that’s the way FOSS advance.
    did you manage to contact jqgrid developers to integrate you code ?

  7. @Laurent was thinking of it for a long time, but didn’t do it till now. Planning to send a mail to jqgrid developers now hope your mail id is l.corrochano@free.fr let me know if not

  8. Yes it is.

  9. hi, maybe have you ever work with jqGrid and Codeigniter? I need to add a new button to implement SEARCH, but I still have problems with that

  10. I haven’t worked with Codeigniter. However let me know the exact issue that you are facing when you add a button. Also, is there any specific reason for not using jqGrid search/advanced search

  11. Hi Veer,
    I was adding a topbar search button using your code in codeigniter and it worked awesome but I failed to trigger filter event so that the default search dialog would appear like it does when we click the default search button in the navigation bar.

    Is there some event [ like trigger(“reloadGrid”) to refresh grid ] so that we can activate the search dialog?

    I failed to find anything useful in the documentation docs and also your usage example has the following code to fire some event

    onClickButton:function(){ mygrid[0].toggleToolbar(); }

    what is [mygrid[0].toggleToolbar()] ? Am I missing something? FF error console tells me ‘mygrid is not defiled’ which certainly is not and I tries the toolbar and grid table ids and got the same error!

    Please help.

    Anupam

  12. myGird variable holds the reference to the grid created. Any example in jqGrid demo page will show you this http://www.trirand.com/blog/jqgrid/jqgrid.html
    Are you looking for Integrated search tool bar (see above link under New in version 3.5) or Advanced Searching (see above link under New in version 3.5) ? For integrated search tool bar “mygrid[0].toggleToolbar();” will help you out. For Advance search the above demo should help you out.

  13. Very useful and easy to take, thanks a lot!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: