Creating an AJAX-Enabled Grid With Cell Edit

In this post i will show how to edit the cell of gridview on doubleclicking and also how to update server side data without refreshing the page. The key advantages of this grid are as follows * Data will be bind to grid only once, i.e. on page load. * Only modified data goes to server to update the grid.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxEnabledGrid.aspx.cs"
   Inherits="AjaxEnabledGrid" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   <title>Untitled Page</title>

  <script type = "text/javascript" >
  var ddlId = new Array();
function MakeCellEditable(obj) {
  if(!window.document.getElementById(obj.id + "_input")) {
     if(document.all) {
        obj.innerHTML = "<input id=" + obj.id + "_input" + " type=text value='" + obj.innerText + "'/>" }
     else {
        obj.innerHTML = "<input id="+ obj.id + "_input" + " type=text value='" + obj.textContent + "'/>" }
     }
  window.document.getElementById(obj.id + "_input").focus();
  }
function UpdateGrid(args) {
  <%= ClientScript.GetCallbackEventReference(this, "args", "ShowResult", null) %> ;
  }
function JSUpdateTable() {
  var ddl = window.document.getElementById('Gridview');
  var ddl1 = ddl.getElementsByTagName('input');
  var data = "";
  for(i = 0 ; i < ddl1.length ; i++) {
     ddlId[i] = ddl1[i].id;
     //ddlId is a global array in JS we will use it in step 9
     if(i == 0 ) data = ddl1[i].id + "|" + ddl1[i].value;
     else data = data + "~" + ddl1[i].id + "|" + ddl1[i].value;
     }
  UpdateGrid('updateTable$' + data);
  }
function UpdateGrid(args) {
  <%= ClientScript.GetCallbackEventReference(this, "args", "ShowResult", null) %> ;
  }
function ShowResult(eventArgument , context) {
  //debugger;
  formObj = window.document;
  if(eventArgument == "SUCCESS") {
     for(j = 0 ; j < ddlId.length ; j++) {
        var ids = ddlId[j].split("_");
        formObj.getElementById(ids[0] + "_" + ids[1]).innerHTML = formObj.getElementById(ddlId[j]).value;
        }
     document.getElementById('ServerMsg').innerText = "Data has been updated Successfully...";
     }
  }
</script>
</head>
<body>
   <form id="form1" runat="server">
       <div id="Gridview">
           <asp:GridView EnableViewState="False" runat="server" ID="_grid" OnRowDataBound="_grid_RowDataBound" CellPadding="4" ForeColor="#333333" GridLines="None">
               <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
               <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
               <EditRowStyle BackColor="#999999" />
               <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
               <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
               <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
               <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
           </asp:GridView>
           <span id="ServerMsg"></span>
       </div>
       <br />
       <input type="button" value="Update" onclick="javascript: JSUpdateTable ();" />
   </form>
</body>
</html>
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class AjaxEnabledGrid : System.Web.UI.Page, ICallbackEventHandler
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            _grid.DataSource = _sampleData;
            _grid.DataBind();
        }
    }
    string result;
    public DataTable _sampleData
    {
        get
        {
            DataTable dt = (DataTable)Session["DataTable"];
            if (dt == null)
            {
                dt = new DataTable();
                dt.Columns.Add(new DataColumn("Contact                                Name", typeof(string)));
                dt.Columns.Add(new DataColumn("Company Name", typeof(string)));
                dt.Columns.Add(new DataColumn("City", typeof(string)));
                dt.Columns.Add(new DataColumn("Country", typeof(string)));

                dt.Rows.Add(new object[] { "Maria Anders", "Alfreds Futterkiste", "Berlin", "Germany" });
                dt.Rows.Add(new object[] { "Ana Trujillo", "Emparedados y helados ", "México D.F.", "Mexico" });
                dt.Rows.Add(new object[] { "Antonio Moreno", "Antonio Moreno Taquería", "México D.F.", "Mexico" });
                Session["DataTable"] = dt;
            }
            return dt;
        }
        set
        {
            Session["DataTable"] = value;
        }
    }
    int _rowNumber;
    protected void _grid_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            for (int i = 0; i < e.Row.Cells.Count; i++)
            {
                e.Row.Cells[i].Attributes.Add("ondblclick", "javascript:MakeCellEditable(this);");
                e.Row.Cells[i].Attributes.Add("id", _rowNumber + "_" + i);
            }
            _rowNumber += 1;
        }
    }
      
    public void RaiseCallbackEvent(string eventArgument)
    {
        string[] args = eventArgument.Split('$');
        if (args[0] == "updateTable") updateTable(args[1]);
    }

    public string GetCallbackResult()
    {
        return result;
    }
    private void updateTable(string _data)
    {
        string[] _NewData = _data.Split('~');
        DataTable _tempTable = _sampleData;
        for (int i = 0; i < _NewData.Length; i++)
        {
            string[] _changedTxt = _NewData[i].Split('|');
            string[] _rowCol = _changedTxt[0].Split('_');
            _tempTable.Rows[Convert.ToInt32(_rowCol[0])][Convert.ToInt32(_rowCol[1])] = _changedTxt[1];
        }
        _sampleData = _tempTable;
        result = "SUCCESS";
    }
}

1 comment:

  1. Thanks for this code, I was looking to find something like this, there is one thing that might need to be changed. ddlID's length should be updated in function JSUpdateTable by something like

    ddlId.length = ddl1.length;

    otherwise the number of textboxes in the array dont get updated when you are editing the 2nd, 3rd time etc, hope that helps someone else as well!

    ReplyDelete