Click here to Skip to main content
15,893,564 members
Articles / Web Development / XHTML

Paging, Selecting, Deleting, Editing and Sorting in the ASP.NET GridView Control with Keyboard Shortcuts

Rate me:
Please Sign up or sign in to vote.
4.89/5 (32 votes)
5 Oct 2010CPOL8 min read 158.1K   6.3K   137  
An ASP.NET 2.0 AJAX Extender to enhance the ASP.NET GridView to page, select, delete, edit and sort rows with keyboard shortcuts.
#define NET20
using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script;
using System.Web.Script.Services;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// Webservice support for AjaxGrid (using JSON format).
/// These calls are performed synchronously
/// No async handler for JSON is currently available (see http://forums.asp.net/t/1139582.aspx)
/// 
/// These methods all extract the user profile and then call AjaxGrid methods
/// Most call either Repaint (paint complete grid) or RepaintData (repaint only data)
/// and return the string to the AJAX callback function
/// </summary>
[ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public partial class AjaxGrid : System.Web.Services.WebService 
{
    // private method to read profile from session data
    // the session may expire, if so normally requires recreation of session data
    // (perhaps redirect to a login page).
    private GridProfileData Profile(int gridId)
    { return ((List<GridProfileData>)Session["GridProfile"])[gridId]; }

    // AJAX methods called from javascript
    // -----------------------------------
    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnSort(int gridId, int col)
    {
        GridProfileData profile = Profile(gridId);
        int sortcol = profile.currentSortCol;
        if (sortcol == col) // toggle sort direction if no column change
            profile.currentSortDirection = !profile.currentSortDirection;
        else
        {   // else set new sort column (ascending)
            profile.currentSortDirection = false;
            profile.currentSortCol = (byte)col;
        }
        return Repaint(profile, gridId);
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnFilter(int gridId, int col, string value)
    {
        GridProfileData profile = Profile(gridId);
        profile.columns[col].currentFilter = (value.Length == 0 || value == NoFilterText) ? null : value;
        return RepaintData(profile, gridId);
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnFreeTextFilter(int gridId, string value)
    {
        GridProfileData profile = Profile(gridId);
        profile.currentFreeTextFilter = value;
        return Repaint(profile, gridId);
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public void OnGridUpdate(int gridId, int id, int col, string value)
    {
        GridProfileData profile = Profile(gridId);
        UpdateCell(gridId, profile, id, col, value);
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnNewRow(int gridId, bool newrow)
    {
        GridProfileData profile = Profile(gridId);
        profile.addingNewRow = newrow;
        return Repaint(profile, gridId);
    }


    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnSaveNewRow(int gridId)
    {
        return InsertRow(gridId, Profile(gridId));
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnUpdateNewRow(int gridId, int col, string value)
    {
        return UpdateNewRow(gridId, col, value, Profile(gridId));
    }

    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public AjaxResponse OnUpdateMaxResults(int gridId, int value)
    {
        GridProfileData profile = Profile(gridId);
        profile.currentTableMax = value;
        return RepaintData(profile, gridId);
    }

    // this method illustrates an interesting way of generating language-independent javascript on demand
    // just call the server, who knows who you are, and it will generate text for you
    [WebMethod(EnableSession = true)]
    [ScriptMethod]
    public string OnTools(int gridId)
    {
        GridProfileData profile = Profile(gridId);
        string maxresults = (profile.currentTableMax == 0) ? "" : profile.currentTableMax.ToString();
        StringBuilder html = new StringBuilder();
        html.AppendFormat (
            "<div class='popuptitlebar'>"
            + "<a onclick='return hidePopup(\"gridTools\");' href='#'><img src='img/cancel.gif' width='19' height='20' /></a>"
            + "</div>"
            + "<div class='popupcontents'>"
            + "<span>Limiting the results displayed in the table can improve the response time. If the results exceed the limit specified below, only that number will be displayed and the settings indicator will highlight to notify you to apply a sort or filter</span><br /><br />"
            + "<span style='margin:4px'>max to display</span><input type='text' id='txtMax' value='{1}'/><br /><br />"
            + "<div align='right'><button title='Output CSV' style='width:80px;margin-right:5px;' onclick='return exportTable(\"{0}\");'>Output CSV</button>"
            + "<button title='Update max results' style='width:60px;margin-right:5px;' onclick='return updatePopupMax(\"{0}\");'>Ok</button>"
            + "<button title='No maximum' style='width:60px;margin-right:5px;' onclick='return noPopupMax(\"{0}\");'>No max</button>"
            + "<button title='Cancel' style='width:60px;' onclick='return hidePopup(\"gridTools\");'>Cancel</button>"
            + "</div>", gridId,maxresults);
        return html.ToString();
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Dipl.-Ing. Rolf Cerff Software Development and IT-
Germany Germany
I'am a freelance software developer, located at Freiburg i. Br., Germany. My main domain is designing and developing Web applications based on the ASP.NET technology. Further main interests are. Sustainable and agile software architectures, Domain Driven Design (DDD). I'am a certified SCRUM Master.

Comments and Discussions