Recently I had the need to add some custom processing to the contents of a RadGrid. I decided that the most desirable solution would be to add a menu of options in the footer of the grid, but unfortunately the RadGrid does not support footer templates. I don’t know if this is because there are other built-in features that are hosted in the grid footer (e.g. paging, command items, etc.), or simply because there hasn’t been any demand for this feature. Either way, I needed to add the functionality.
This seemed like a great opportunity for a jQuery plugin, so I decided to whip one up.
Examining the structure of a RadGrid
Before I can programmatically add a footer to the RadGrid I need to understand its structure. The HTML generated by the RadGrid differs based upon the features being employed in a specific instance, so let’s take a look at a couple of scenarios.
First, here’s how the RadGrid renders on the client in the most basic of implementations:
<div id="rgCustomers">
<table>
<colgroup>
<!-- column group definitions -->
</colgroup>
<thead>
<!-- header contents -->
</thead>
<tbody>
<!-- body contents -->
</tbody>
</table>
</div>
And since I care most about content that is rendered in the footer, let’s look at the RadGrid structure when paging and the command item toolbar are enabled:
<div id="rgCustomers">
<table>
<colgroup>
<!-- column group definitions -->
</colgroup>
<thead>
<!-- header contents -->
</thead>
<tbody>
<!-- body contents -->
</tbody>
<tfoot>
<tr class="rgCommandRow">
<!-- command row elements -->
</tr>
<tr class="rgPager">
<!-- pager elements -->
</tr>
</tfoot>
</table>
</div>
As you can see, the grid is rendered as a <table> wrapped in a <div> element. The <table> defines <colgroup>, <thead>, and <tbody> sections. The contents of these sections is not important as I am only concerned with adding a footer to the <table>. Unless certain features are enabled, no footer element (<tfoot>) is rendered. In that case I’ll need to create and attach a new one. However, if a feature is enable that causes a footer to be rendered I need to ensure that the new menu content is added after any existing footer row elements.
Creating a custom jQuery plugin
Armed with a general understanding of the structure of a RadGrid, I can design the markup I will use to create the menu.
<tr class="footer-menu">
<td colspan="4">
<ul>
<li class="menu-item export">Export Data</li>
<li class="menu-item search">Search</li>
<li class="menu-item audit">Audit</li>
<li class="menu-item email">Email</li>
</ul>
</td>
</tr>
The implementation is simple. I will add a new footer row with a single cell that spans the width of the table (in this case 4 columns). The cell will contain an unordered list of menu items; class names and text values will be configurable.
Next I’ll write a simple jQuery plugin to inject this markup into a RadGrid element.
(function($) {
$.fn.footerMenu = function(items, settings) {
/* Default settings for footer menu class name */
var config = { 'className': 'footer-menu' };
$.extend(config, settings);
this.each(function() {
/* Grab the table element */
var table = $(this).children('table');
/* Verify that exactly one table element exists */
if (table.size() === 1) {
/* Grab the table's footer element */
var footer = table.children('tfoot');
/* If not footer element exists, create one and append it to the table */
if (footer.size() === 0) {
footer = $('<tfoot>').appendTo(table);
}
/* Grab the last row element that is not the pager or command row */
var row = footer.children('tr:last:not(.rgPager):not(.rgCommandRow)');
/* If a row does not exist, create one and append it to the footer */
if (row.size() === 0) {
row = $('<tr>').appendTo(footer);
}
/* Set the row class name to the value specified in the config object */
row.attr('class', config.className);
/* Grab the row's cell element */
var cell = row.children('td');
/* If no cell element exists, create one and append it to the row */
if (cell.size() === 0) {
/* Give the cell a column span equal to the number of columns in the table */
var colspan = table.find('colgroup col').size();
cell = $('<td>').attr('colSpan', colspan).appendTo(row);
}
/* Grab the cell's unordered list element */
var list = cell.children('ul');
/* If no list exists, create one and append it to the cell */
if (list.size() === 0) {
list = $('<ul>').appendTo(cell);
}
/* Iterate through the menu items */
for (i = 0; i < items.length; i++) {
var item = items[i];
/* Create a new list item and append it to the unordered list */
var listItem = $('<li>').attr('class', item.className).appendTo(list);
/* If the item was given a text value, set it */
if (item.text) listItem.append(item.text);
/* If the item should be hidden, hide it */
if (item.hidden) listItem.hide();
/* Add the items click handler to the listItem element */
listItem.click(item.click);
}
}
});
return this;
};
})($telerik.$);
Notice that I pass a reference to $telerik.$ to the self-calling function surrounding the plugin, instead of $ or jQuery. This is because Telerik aliases the jQuery object with $telerik.$ in the scripts included in their assembly.
Using the new RadGrid footer menu plugin
With the plugin created and working properly, I need to write a bit of CSS to style the new menu (and its items) to give it a look that is consistent with the RadGrid theme I’m using.
.footer-menu td
{
background-color: #434343;
padding: 5px;
}
.footer-menu ul
{
list-style: none;
padding: 0;
margin: 0;
}
.footer-menu li
{
color: #ccc;
float: left;
padding: 5px 5px 5px 25px;
margin-right: 5px;
cursor: pointer;
}
.footer-menu li:hover
{
background-color: #ccc;
color: #434343;
}
.footer-menu .export
{
background: url(/Content/export.png) no-repeat 5px center;
float: right;
}
.footer-menu .search
{
background: url(/Content/search.png) no-repeat 5px center;
}
.footer-menu .audit
{
background: url(/Content/audit.png) no-repeat 5px center;
}
.footer-menu .email
{
background: url(/Content/email.png) no-repeat 5px center;
}
Next, I simply add a reference to the new script in my RadScriptManager. Remember that Telerik includes jQuery with their controls, so you don’t need to have another copy referenced on your page. Check out this post by Atanas Korchev for more details.
<telerik:RadScriptManager ID="RadScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
<asp:ScriptReference Path="~/Content/jquery.footer-menu.js" />
</Scripts>
</telerik:RadScriptManager>
Finally, I can create the menu and attach it to the RadGrid instance on my page.
Sys.Application.add_load(function() {
var exportData = function() {
var tableView = $find('<%= rgCustomers.ClientID %>').get_masterTableView();
tableView.exportToCsv();
};
var search = function() {
// add search functionality
};
var audit = function() {
// add audit functionality
};
var email = function() {
// add email functionality
};
var items = [
{ 'text': 'Export Data', 'className': 'export', 'click': exportData },
{ 'text': 'Search', 'className': 'search', 'click': search },
{ 'text': 'Audit', 'className': 'audit', 'click': audit },
{ 'text': 'Email', 'className': 'email', 'click': email }
];
$telerik.$('#<%= rgCustomers.ClientID %>').footerMenu(items);
});

Final Thoughts
Creating jQuery plugins is pretty easy. With jQuery already bundled with the RadControls, using it to customize and enhance their functionality is a no-brainer. For more details on writing your own jQuery plugins, check out this tutorial.
[Source: C#]