EmptyDataTemplate in GridView Or Data Controls in ASP.NET 3.5 or 4.0

How to display a table when no records are present in the database.

How to display a table when no records are present in the Database? This is the most frequently asked question for beginners, even for intermediate developers, while displaying data on the web forms when there are no records present in the Database. Most of us, to satisfy our requirements, switch the EmptyDataText property setting of the GridView control or any DataControl by specifying the value as "No Records Found". But there are sometimes a requirement to display a table on the web page if there is no records found in the database so that the user can add a new record by filling in the fields on the table and by clicking the button. In such cases we mostly make use of a table control along with the GridView control whereby setting its (the table's) visibility to true or false depending on whether there are records in the DB or not. The alternative is to use an EmptyDataTemplate of the GridView control or the data control, whichever you are using. Whereby the user must input the data in the respective fields and on the click of the button, all the data entered by the user is stored in the DB and finally the stored Data is displayed in the GridView control. Something about the EmptyDataTemplate is that it's a template that can display any piece of information in a specified format when no records are present in the Database. You need to explicitly define the EmptyDataTemplate for your Data Control. It's simple to define the only thing that you need to do, which is to create a class that will implement the ITemplate interface and define your layout of your EmptyDataTemplate. And then finally you need to set the GridView.EmptyDataTemplate to your Template (that you created).

Ok now let's move on towards our example, as you all know. Now let's try to implement our goal.

1. Starting with our That Queries. Over here we'll be making use of an Employees table stored in an Oracle Database. The following is the script for that:

create table Employees

(

EId int not null,

EName varchar(30),

EAddress varchar(30),

EAge Number,

ECountry varchar(30),

EDesignation varchar(30)

)

 

//For Accessing the Data stored in Employees Table

create or replace procedure prcGetEmployees

(

temp_cursor out sys_refCursor

)

as

begin

open  temp_cursor for

select * from Employees;

end;

 

//For Inserting the Data in Employees Table

create or replace procedure prcAddEmp

(

v_name varchar2,

v_address varchar2,

n_age number,

v_country varchar2,

v_designation varchar2

)

as

v_id number:=0;

begin

select count(*) into v_id from Employees;

 

v_id:=v_id+1;

 

insert into Employees

values (v_id,v_name,v_address,n_age,v_country,v_designation);

end;

Until now we have created a table and a procedure that will allow us to read the Employees table information or insert data into the Employees table. Now let's use a webform in Visual Studio 2010 (named test.aspx in our project) and add a gridview to the test.aspx page and on the page load event call the procedure that provides us Employee data, in our case prcGetEmployees is the procedure that, when executed, will return the resultset of the Employees table.

Test.aspx

EmptyDataTemp1.jpg

Test.aspx.cs Code Behind

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

 

public partial class test : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!IsPostBack)

            LoadData();

    }

    private void LoadData()

    {

        DAL objDal = new DAL();

        DataSet ds = objDal.GetRecords();

        if (ds != null)

        {

            GridView1.DataSource = ds.Tables[0].DefaultView;

            GridView1.DataBind();

        }

    }

}

Now when I try to run the file all I get is a blank page like the following.

EmptyDataTemp2.jpg

This is because I neither set the EmptyDataTextProperty to "No Records Found" nor did I use an EmptyDataTemplate.

Ok, now let's move toward creating an EmptyDataTemplate for our Employee Table. For creating a table we need the cell, in other words the Column and the Row. The following are the two classes that we can call; they have helper classes that will allow us to create a column and a row for our GridView's EmptyDataTemplate.
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI.WebControls;

using System.ComponentModel;

using System.Reflection;

using System.Collections;

using System.Web.UI;

 

/// <summary>

/// This class will act a as column of EmptyDataTemplate Table.

///This class is used by EmptyGridRow class

/// </summary>

public class EmptyColumn

{

    //specifies the column text to be displayed

    public string ColumnName { get; set; }

   

    //specifies whether the column is ready only or not

    public bool IsReadOnly { get; set; }

 

    //the control to use for the column

    public WebControl ColumnControl { get; set; }

 

    //setting the default control as Label.

    public EmptyColumn()

    {

        ColumnControl = new Label();

    }

}

 

/// <summary>

/// This class act as a row of EmptyDataTemplate Table.

///This class is used by EmptyGridTemplate.

/// </summary>

public class EmptyGridRow

{

    //Specifies EmptyColumn Properties

    public EmptyColumn Columns { get; set; }

 

    //the default cell size within a row. i.e. Maximum 2 cells will be there inside a row

    public const int ColumnSize = 2;

}


Now we are ready to create/define our EmptyDataTemplate Class. Since all the helper classes are done, the following is the source code for it.
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Reflection;

using System.Text;

 

/// <summary>

/// This is the EmptyDataTemplate Class which when executed will try to create a temporary table

/// along with the fields specified by the user and the controls to be used defined in the EmptyGridRow class.

/// </summary>

public class EmptyGridTemplate : ITemplate

{

    private ListItemType _itemType;

 

    private const string _openTable = "table";

    private const string _closeTable = "/table";

    private const string _openAngularBracket = "<";

    private const string _closeAngularBracket = ">";

    private const string _openCell = "td";

    private const string _closeCell = "/td";

    private const string _openRow = "tr";

    private const string _closeRow = "/tr";

    private const string _space = " ";

    private const string _doubleQuotes = "\"";

    private const string _idValueDelimeter = "=";

    private const string _rowName = "row";

    private const string _cellName = "cell";

    private const string _id = "id";

    private const string _tableID = "table1";

    private const string _tableStyle = "style=\"width:100%;border:1px solid silver;\"";

    private const string _colSpan = "colspan=\"2\"";

    private const string _alignRight = "align=\"right\"";

    private int _rowCounter = 0, _cellCounter = 0;

 

    private List<EmptyGridRow> _lstGridRows = null;

    private string _redirectPath = string.Empty;

 

    //Initialized the update panel at class level so that it can be used any where in the program.

    private UpdatePanel udpMain = new UpdatePanel()

    {

        ID = "udpMain",

        RenderMode = UpdatePanelRenderMode.Block,

    };

 

    public EmptyGridTemplate(ListItemType item, List<EmptyGridRow> lstRows, string rediredPath)

    {

        _lstGridRows = lstRows;

        _itemType = item;

        _redirectPath = rediredPath;

    }

 

    /// <summary>

    /// This function is used for creating rows in the Empty Template Table

    /// </summary>

    /// <param name="lstGridRows">List Of Row's Data</param>

    public void CreateRows(List<EmptyGridRow> lstGridRows)

    {

        foreach (EmptyGridRow row in lstGridRows)

        {

            Literal ltrlRows = new Literal()

            {

                Text = _openAngularBracket + _openRow + _space + _id +

                _idValueDelimeter + _doubleQuotes + _rowName + _rowCounter + _doubleQuotes + _closeAngularBracket

            };

 

            udpMain.ContentTemplateContainer.Controls.Add(ltrlRows);

 

            EmptyColumn col = row.Columns;

 

            //First Cell of the Table

            Literal ltrlCells = new Literal()

            {

                Text = _openAngularBracket + _openCell + _space + _id + _idValueDelimeter + _doubleQuotes +

                _rowName + _rowCounter + _cellName + _cellCounter + _doubleQuotes + _closeAngularBracket

            };

 

            udpMain.ContentTemplateContainer.Controls.Add(ltrlCells);

 

            //Specify the Column Name into the Literal by using col.ColumnName

            Literal ltrlCell0 = new Literal()

            {

                Text = col.ColumnName + _openAngularBracket + _closeCell + _closeAngularBracket

            };

 

            //Add the literal to container so that it can be displayed

            udpMain.ContentTemplateContainer.Controls.Add(ltrlCell0);

 

            //Second Cell of the Table

            _cellCounter++;

            Literal ltrlCell1 = new Literal()

            {

                Text = _openAngularBracket + _openCell + _space + _id + _idValueDelimeter + _doubleQuotes +

                _rowName + _rowCounter + _cellName + _cellCounter + _doubleQuotes + _closeAngularBracket

            };

 

            udpMain.ContentTemplateContainer.Controls.Add(ltrlCell1);

 

            //Add the Control of the Cell

            udpMain.ContentTemplateContainer.Controls.Add(col.ColumnControl);

 

            Literal ltrlCell1Close = new Literal()

            {

                Text = _openAngularBracket + _closeCell + _closeAngularBracket

            };

 

            _rowCounter++;

            _cellCounter = 0;

        }

        Literal ltrl = new Literal()

        {

            //creating new Row

            Text = _openAngularBracket + _openRow + _space + _id +

                _idValueDelimeter + _doubleQuotes + _rowName + _rowCounter + _doubleQuotes + _closeAngularBracket +

                //creating new Cell

                _openAngularBracket + _openCell + _space + _id + _idValueDelimeter + _doubleQuotes +

                _rowName + _rowCounter + _cellName + _cellCounter + _doubleQuotes + _colSpan + _alignRight + _closeAngularBracket

        };

 

        udpMain.ContentTemplateContainer.Controls.Add(ltrl);

 

        Button btnAdd = new Button()

        {

            ID = "btnAdd",

            Text = "Save",

            CommandName = "AddNew",

            CausesValidation = false,

            BackColor = System.Drawing.Color.White,

            ForeColor = System.Drawing.Color.Black,

        };

        if (_redirectPath.Equals("Default.aspx", StringComparison.InvariantCultureIgnoreCase))

            btnAdd.OnClientClick = "readEmptyGridData();";

        else

            btnAdd.Click += new EventHandler(btnAdd_Click);

 

        PostBackTrigger trgPostBack = new PostBackTrigger();

        trgPostBack.ControlID = btnAdd.ID;

        udpMain.Triggers.Add(trgPostBack);

        udpMain.ContentTemplateContainer.Controls.Add(btnAdd);

    }

 

    //Button Click Event

    private void btnAdd_Click(object sender, EventArgs e)

    {

        string Data = "";

        foreach (EmptyGridRow row in _lstGridRows)

        {

            if (!row.Columns.IsReadOnly)

            {

                WebControl webControl = (WebControl)row.Columns.ColumnControl;

                if (webControl.GetType().Equals(typeof(DropDownList)))

                {

                    DropDownList ddl = (DropDownList)webControl;

                    Data += ddl.SelectedItem.Text + "|";

                }

                else if (webControl.GetType().Equals(typeof(TextBox)))

                {

                    TextBox txt = (TextBox)webControl;

                    Data += txt.Text + "|";

                }

            }

        }

        string eName = string.Empty;

        string eAdd = string.Empty;

        int eAge = 0;

        string eCountry = string.Empty;

        string eDesignation = string.Empty;

        string[] eData = Data.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

        eName = eData[0];

        eAdd = eData[1];

        eAge = Convert.ToInt32(eData[2]);

        eCountry = eData[3];

        eDesignation = eData[4];

        DAL objDal = new DAL();

        objDal.AddRecord(eName, eAdd, eAge, eCountry, eDesignation);

        HttpContext.Current.Response.Redirect(_redirectPath);

    }

 

    public void InstantiateIn(Control container)

    {

        switch (_itemType)

        {

            case ListItemType.Header:

                Literal ltrlTable = new Literal()

                {

                    Text = _openAngularBracket + _openTable + _space + _id + _idValueDelimeter + _doubleQuotes + _tableID

                                 + _doubleQuotes + _space + _tableStyle + _closeAngularBracket

                };

                udpMain.ContentTemplateContainer.Controls.Add(ltrlTable);

                CreateRows(_lstGridRows);

                container.Controls.Add(udpMain);

                break;

            default:

                break;

        }

    }

}


NOTE: if your observe the code above with in the lime shade, you will find that if the _redirectpage is default.aspx then we are setting the button onclientclick property to some JavaScript function or else we are setting the server side function. For now, just keep this in mind because it will be used at the end of the article where we will try to insert records into the Employee table using an xmlHttpRequest object.

If you observe the source code you will find the following things:-

  1. Our EmptyGridTemplate inherits from the ITemplate class that has one function named InstantiateIn (Control container) that is called automatically when you bind this class to your data control; in our case the GridView control's EmptyDataTemplate.

  2. There is a CreateRow function that accepts a List<EmptyGridRow> class, in other words this list will have all the columns along with the necessary information such as column name to be displayed, whether the column is read-only or not and the control for that column (that is to be used for accepting the input from the user for that column, for instance for accepting a name we will provide a TextBox control in front of the Name column).

  3. In the InstantiateIn function we are using an UpdatePanel, in other words all of our table's data will be placed inside an updatepanel.

  4. After adding all the table data to the updatePanel control, we are adding the update panel to the container control inside the InstantiateIn function.

  5. Finally, on the Button click event we are calling the DAL function to add the record for the Employee.

Now our EmptyGridTemplate is ready, we can make use of it. For testing it let's try to add a page with the name test2.aspx.

NOTE: Remember that our EmptyGridTemplate makes use of UpdatePanel for adding the control on the page. In other words, in our test2.aspx page we will need to add a ScriptManager class.

The following is the markup file of the test2.aspx page:
 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test2.aspx.cs" Inherits="test2" %>

 

<!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></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

   

        <asp:ScriptManager ID="ScriptManager1" runat="server">

        </asp:ScriptManager>

   

        <asp:GridView ID="GridView1" runat="server">

        </asp:GridView>

   

    </div>

    </form>

</body>

</html>

Following is the Source Code of test2.aspx Page.
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

 

public partial class test2 : System.Web.UI.Page

{

    private string _pageName = string.Empty;

    protected void Page_Load(object sender, EventArgs e)

    {

        _pageName = System.Web.HttpContext.Current.Request.Url.AbsolutePath;

        System.IO.FileInfo oInfo = new System.IO.FileInfo(_pageName);

        _pageName = oInfo.Name;

        LoadData();

    }

    private void LoadData()

    {

        DAL objDal = new DAL();

        DataSet ds = objDal.GetRecords();

        if (ds != null)

        {

            GridView1.DataSource = ds.Tables[0].DefaultView;

            GridView1.DataBind();

        }

        else

        {

            //If there is no data present then define the Columns of our EmptyGridRow and add those rows to the EmptyGridTemplate

 

            //Define controls index position for eg at index 1,2,3,5 textbox will be there and at index 4 DropDownList

            int[] txtFieldsIndex = { 1, 2, 3, 4 };//here i want textbox to be displayed for column at index position 1,2,3 and 4

            int[] ddlFieldsIndex = { 5 };//dropdownlist to be displayed for column at index position 5

 

            //Define Column names to be displayed in our emptydatatemplate table

            string[] colNames = { "EID", "EName", "EAddress", "EAge", "EDesignation", "ECountry" };

            string errorMsg = "";

 

            //Creating array of EmptyColumn

            EmptyColumn[] cols = new EmptyColumn[colNames.Length];

 

            for (byte i = 0; i < cols.Length; i++)

            {

                cols[i] = new EmptyColumn()

                {

                    ColumnName = colNames[i],

                    IsReadOnly = txtFieldsIndex.Contains(i) == true ? false : ddlFieldsIndex.Contains(i) == true ? false : true;

 

 

                    ColumnControl = txtFieldsIndex.Contains(i) == true ? new TextBox()

                    {

                        ID = string.Concat("txt", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 15,

                    }

                    :

                    ddlFieldsIndex.Contains(i) == true ? (WebControl)new DropDownList()

                    {

                        ID = string.Concat("ddl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 20,

                        AutoPostBack = true,

                        //defining static list to be displayed inside the dropdownlist

                        DataSource = new ListItemCollection { new ListItem("Select"), new ListItem("India"), new ListItem("China") }

                    }

                    :

                    (WebControl)new Label()

                    {

                        //this column is just for display purpose even if you dont show it there is no issue. I've shown it so that all of us can come to known

                        // that we can display multiple controls inside the emptydatatemplate table at runtime.

                        ID = string.Concat("lbl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Text = "0",//by default setting the EID value to zero because it will automatically be calculated inside the insert procedure

                        Height = 15,

                    }

                };

            }

            //Creating list of EmptyGridRows

            List<EmptyGridRow> lstRows = new List<EmptyGridRow>();

 

            foreach (EmptyColumn col in cols)

            {

                lstRows.Add(new EmptyGridRow() { Columns = col });

            }

 

            //ing the list of rows and the listitem type as header and page name to refresh the page to the constructor of our EmptyGridTemplate class

            EmptyGridTemplate objTemplate = new EmptyGridTemplate(ListItemType.Header, lstRows, _pageName);

            //Binding the EmptyGridTemplate to our GridView

            GridView1.EmptyDataTemplate = objTemplate;

            GridView1.DataBind();

        }

    }

}

Finally now we can test the output of our test2.aspx page. If you look at the following diagram, you will find that the column that we declared is displayed as a column heading and also the controls that we used are displayed respective to the columns on the right hand side on the second cell of the row. Since we just now created the Employees, it will not have any records because we are testing the EmptyDataTemplate that will be rendered only if there are no records found in the database.

EmptyDataTemp3.jpg
Now the user can enter the required data and when the user clicks on the Save button all the data entered by the user will be saved in the DB (the Employees table). Let's try to save one record and see the output for it.

EmptyDataTemp4.jpg
Finally now after clicking the SAVE button, you'll find that your data from the EmptyGridTemplate is being saved in your Employees table and you will be able to see the following output:

EmptyDataTemp5.jpg
With this we have completed our work that we want to do. Now let's talk about something relevant to this module. It would be a better approach for us if we check the column, in other words whether the user has entered the proper column name, in other words with no duplication of columns with the same name has been done. Also, for inserting data you can do it directly through JavaScript by making use of the AJAX xmlhttprequest (that we discussed in the NOTE above) or if needed by using Code Behind. In the example above we inserted records by firing the server side button onClick event. Ok now let's try to sort it out one by one.

Checking Column names

For this I've created a class with the name PropertyChecker and one Extension Method CheckItem (that is used on List<EmptyGridRows>) that will check whether the List<EmptyGridRow> has a column with the same name and value that will be added. If it has a column with the same name and value then it will prompt the user with the error details stating the column was already added. The PropertyChecker class is basically checking whether the properties of list elements and that of the targetItem element matches and also their values. If the value of the list elements and that of the targetItem matches then it returns false or else returns true. True denotes the targetItem can be added as a new row in the List<EmptyGridRow> list. It's a generic class.

The following is the source code for it.

Extension Method (CheckItem) Source Code
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

/// <summary>

/// This class is used for checking whether the item is already added or not.

/// It makes use for PropertyMatcher class which in turn checks whether

///  the column with the specific value has already been added or not.

/// </summary>

public static class ExtendedColumnCheck

{

    public static bool CheckItem<T, U>(this List<T> lstT, U addItem, out string errorMsg)

        where T : class,new()

        where U : class,new()

    {

        errorMsg = "";

        bool status = true;

 

        if (addItem == null)

        {

            errorMsg = "Added Item cannot be null";

            return false;

        }

        if (lstT.Count == 0)

            status = true;

        else

        {

            status = PropertyMatcher.MatchPropertyValues<T, U>(lstT, addItem, out errorMsg);

        }

        return status;

    }

}


The PropertyMatcher class (that will check whether the property of two objects are the same or not; if the same then return false else true):
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Reflection;

using System.Collections;

 

/// <summary>

/// It will check whether the item that needs to be added inside the list

///has already been added to the list or not by checking the column name and its value

/// </summary>

public static class PropertyMatcher

{

    public static bool MatchPropertyValues<TSource, TTarget>(List<TSource> lstT, TTarget targetItem, out string errorMsg, string propName = "")

        where TSource : class

        where TTarget : class,new()

    {

        errorMsg = "";

        List<TSource> _lstSource = null;

        TTarget _targetItem = null;

 

        //Assing the value of the list and targetItem object to the class Variables.

        _lstSource = lstT;

        _targetItem = targetItem;

 

        bool status = true;

        Dictionary<string, object> dicObj = new Dictionary<string, object>();

        Dictionary<string, object> dicSourceObj = new Dictionary<string, object>();

 

        if (_lstSource == null || _targetItem == null)

            throw new ArgumentException("Source List or Target Item cannot be null");

        if (_lstSource.Count == 0)

            throw new ArgumentException("List Should Contain atleast one item");

 

 

        //Retrieve the targetItem Properties

        PropertyInfo[] targetProperties = _targetItem.GetType().GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);

 

        //Push the targetItem Properties name and value into the Dicobj Dictionary

        dicObj = targetProperties.ToDictionary(prop => prop.Name, prop => prop.GetValue(_targetItem, null)).ToDictionary(prop => prop.Key, prop => prop.Value);

 

        //Retrieve each object from the list

        foreach (var source in _lstSource)

        {

            //Get the property of the object stored in the list

            //it will return Columns which is the property

            PropertyInfo[] props = source.GetType().GetProperties();

 

            //Store the Column key and value into the Dictionary

            dicSourceObj = props.ToDictionary(prop => prop.Name,

                 prop => prop.GetValue(source, null)).

                 ToDictionary(prop => prop.Key, prop => prop.Value);

 

            //Iterate over the items stored in the target DicObj

            foreach (KeyValuePair<string, object> keyvalue in dicObj)

            {

                //Iterate ove the items stored in the source Dictionary

                //it has key=Columns and value =EmptyHeaderColumn Values stored in the _listSource

                foreach (KeyValuePair<string, object> sourceKeyValue in dicSourceObj)

                {

                    //Get the Property of the source Dictionary i.e. Columns stored in the _listSource

                    PropertyInfo prop = typeof(TSource).GetProperty(sourceKeyValue.Key);

                    //Get the Type of the Columns Property i.e. EmptyHeaderColumn stored in the _listSource

                    Type type = prop.PropertyType;

                    //Get the actual Properties from the Type type(i.e. EmptyHeaderColumn) stored in the _listSource

                    PropertyInfo[] mainProps = type.GetProperties();

                    //Iterate over the properties of the list EmptyGridRows [Columns] Properties

                    foreach (PropertyInfo p in mainProps)

                    {

                        if (!(p.Name.Equals("IsReadOnly", StringComparison.InvariantCultureIgnoreCase) || p.Name.Equals("ColumnControl", StringComparison.InvariantCultureIgnoreCase)))

                        {

                            if (p.Name.Equals(keyvalue.Key, StringComparison.InvariantCultureIgnoreCase) && object.Equals(p.GetValue(sourceKeyValue.Value, null), keyvalue.Value))

                            {

                                status = false;

                                errorMsg = "Key : " + p.Name + " With Value = " + keyvalue.Value +

                                " Already added";

                                return status;

                            }

                        }

                    }

                }

            }

        }

        return status;

    }

}


Now let's try to test it. For testing I've created a web form with the name as test3.aspx.

Mark up code of the Test3.aspx page:
 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test3.aspx.cs" Inherits="test3" %>

 

<!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></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:GridView ID="GridView1" runat="server">

        </asp:GridView>

    </div>

    </form>

</body>

</html>


Code behind for the same
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

 

public partial class test3 : System.Web.UI.Page

{

    private string _pageName = string.Empty;

    protected void Page_Load(object sender, EventArgs e)

    {

        _pageName = System.Web.HttpContext.Current.Request.Url.AbsolutePath;

        System.IO.FileInfo oInfo = new System.IO.FileInfo(_pageName);

        _pageName = oInfo.Name;

        LoadData();

    }

    private void LoadData()

    {

        DAL objDal = new DAL();

        DataSet ds = objDal.GetRecords();

        if (ds != null)

        {

            GridView1.DataSource = ds.Tables[0].DefaultView;

            GridView1.DataBind();

        }

        else

        {

            bool tableStatus = true;

            //Define controls index position for eg at index 1,2,3,5 textbox will be there and at index 4 DropDownList

            int[] txtFieldsIndex = { 1, 2, 3, 4 };

            int[] ddlFieldsIndex = { 5 };

            //Define Column names

           //here we are purposely adding EName twice so in such case we should get an error message

            string[] colNames = { "EID", "EName", "EName", "EAge", "EDesignation", "ECountry" };

            string errorMsg = "";

            EmptyColumn[] cols = new EmptyColumn[colNames.Length];

 

            for (byte i = 0; i < cols.Length; i++)

            {

                cols[i] = new EmptyColumn()

                {

                    ColumnName = colNames[i],

                    IsReadOnly = txtFieldsIndex.Contains(i) == true ? false : ddlFieldsIndex.Contains(i) == true ? false : true,

 

                    ColumnControl = txtFieldsIndex.Contains(i) == true ? new TextBox()

                    {

                        ID = string.Concat("txt", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 15,

                    }

                    :

                    ddlFieldsIndex.Contains(i) == true ? (WebControl)new DropDownList()

                    {

                        ID = string.Concat("ddl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 20,

                        AutoPostBack = true,

                        DataSource = new ListItemCollection { new ListItem("Select"), new ListItem("India"), new ListItem("China") }

                    }

                    :

                    (WebControl)new Label()

                    {

                        ID = string.Concat("lbl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Text = "0",

                        Height = 15,

                    }

                };

            }

            //Creating list of EmptyGridRows

            List<EmptyGridRow> lstRows = new List<EmptyGridRow>();

 

            foreach (EmptyColumn col in cols)

            {

                //Checking whether the column name has already being added or not

                if (lstRows.CheckItem<EmptyGridRow, EmptyColumn>(col, out errorMsg))

                    lstRows.Add(new EmptyGridRow() { Columns = col });

                else

                {

                    tableStatus = false;

                    ClientScript.RegisterStartupScript(this.GetType(), "error", "<script>alert('" + errorMsg + "');</script>");

                }

            }

            if (tableStatus == true)

            {

                //Binding the EmptyTemplate to our GridView

                EmptyGridTemplate objTemplate = new EmptyGridTemplate(ListItemType.Header, lstRows, _pageName);

                GridView1.EmptyDataTemplate = objTemplate;

                GridView1.DataBind();

            }

        }

    }

}


Now let's run the test3.aspx page and see the following output. Before running it, we will truncate the Employees table so that there are no records and our EmptyGridTemplate can be applied to the GridView's EmptyDataTemplate. Now when you run your test3.aspx page you'll see the following output.

EmptyDataTemp6.jpg

By looking at the following output we are sure that our propertymatcher class is working fine.

Now for the last part of the article, in other words the insertion of data using an xmlhttprequest object. For this I'm adding an external js file with the name jsHelper.js and also the AjaxHelper.aspx page that will be called by an xmlHttpRequest object.

The following is the code for that:

External Js File (jsHelper.js)
 

var grid = null;

var elements = null;

var name = null;

var address = null;

var designation = null;

var country = null;

var age = 0;

var eid = 0;

 

var eData = "";

 

//Create XMLHttpRequest object

 

var httpRequest = null;

 

function getXMLHttpRequest() {

    if (window.ActiveXObject) {

        try {

            return new ActiveXObject("Msxml2.XMLHTTP");

        } catch (e) {

            try {

                return new ActiveXObject("Microsoft.XMLHTTP");

            } catch (e1) {

                return null;

            }

        }

    } else if (window.XMLHttpRequest) {

        return new XMLHttpRequest();

    } else {

        return null;

    }

}

 

//Check whether the request is from Firefox browser

function isFireFox() {

    return navigator.userAgent;

}

 

 

//Read Data From GridView

function readEmptyGridData() {

    try {

        if (elements != null)

            grid = document.getElementById(elements.varGridView);

 

        var userNavigator = isFireFox();

 

        //Accessing our UpdatePanel which we created in our EmptyDataTemplate

        var emptyUpdatePanel = grid.rows[0].cells[0].childNodes[0]; //#table1 is the id of the table Control

        //Accessing the table control created in our EmptyDataTemplate

        var emptyTable = emptyUpdatePanel.childNodes[1];

 

        var rowsLength = emptyTable.rows.length;

 

        for (var rowCounter = 0; rowCounter < rowsLength - 1; rowCounter++) {

            for (var cellCounter = 0; cellCounter < emptyTable.rows[rowCounter].cells.length; cellCounter++) {

                if (userNavigator.indexOf("Firefox") != -1) {

                    eData += emptyTable.rows[rowCounter].cells[cellCounter].childNodes[0].textContent;

                }

                else {

                    //For accessing the textContent of the First Column Cells Names

                    if (cellCounter == 0) {

                        eData += emptyTable.rows[rowCounter].cells[cellCounter].childNodes[0].textContent;

                        eData += "=";

                    }

                    //For accessing the value within the TextBox

                    else {

                        //This is done for accesing the text of the Empid and value as  Zero because over there are no control we have used

                        if (emptyTable.rows[rowCounter].cells[cellCounter].childNodes[0].value != undefined)

                            eData += emptyTable.rows[rowCounter].cells[cellCounter].childNodes[0].value; //for accessing the controls from TextBox or Some other control

                        else//that's why we will have to access the values by using textContent

                            eData += emptyTable.rows[rowCounter].cells[cellCounter].childNodes[0].textContent;

                    }

                }

            }

            eData += "|";

        }

        httpRequest = getXMLHttpRequest();

        httpRequest.open("POST", "Ajax/AjaxHelper.aspx?eData=" + eData, true);

        //    //Send the proper header information along with the request

        //    httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        //    httpRequest.setRequestHeader("Content-length", param.length);

        //    httpRequest.setRequestHeader("Connection", "close");

        //Setup the callback function

        httpRequest.onreadystatechange = onSuccess;

        httpRequest.send();

        return false;

    }

    catch (e) {

        alert(e.Message);

    }

}

/*

If data is inserted successfully then refresh the page

*/

function onSuccess() {

    //checking for the readyState and status of the httpRequest object

    if (httpRequest.readyState == 4 && httpRequest.status == 200) {

        //  finally getting the responseText of the httpRequest object

        var result = httpRequest.responseText;

        if (result == "Successfull") {

            window.location.href = window.location.href; //refresh the page

        }

        else if (result == "Error")

            alert('Error Saving Data'); //else display an error message

    }

}

 

/*

This function is used for handling errors

*/

function onError(result) {

    // ajax call failed

    alert('Error ' + result.status + ': ' + result.statusText);

}


The AjaxHelper.js file is placed inside the Ajax folder within the application. The following is the markup and code behind file for that:
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

using System.Data.OracleClient;

 

public partial class Ajax_AjaxHelper : System.Web.UI.Page

{

    const string _dbCon = "DATA SOURCE=DHQMDB;WORD=hqm321;PERSIST SECURITY INFO=True;USER ID=HQM_ADMIN";

    OracleConnection con;

    OracleCommand cmd;

 

    protected void Page_Load(object sender, EventArgs e)

    {

        if (Request.QueryString.Count > 0 && Request.QueryString["eData"] != null)

        {

            AddDataToEmployee(Request.QueryString["eData"].ToString());

        }

    }

 

    /// <summary>

    /// This function is used for adding record  to the employee table.

    /// </summary>

    /// <param name="eData">Data appended by using | operator</param>

    /// <returns>returns string as Successfull or Error</returns>

 

    private string AddDataToEmployee(string eData)

    {

        //Spliting the value by using | operator and removing the empty entries

        string[] arr = eData.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

 

        List<string> lstValues = new List<string>();

        string value = "", returnValue = "";

 

        foreach (string str in arr)

        {

            //Accessing the value from the array that's why the index 1 is specified. because over here the value are in the

            //form of ColName=Value so in our arr items will be store like the following

            //{Empid=value},{EName=value},{Ecountry=value} like so on.

            value = str.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1];

            lstValues.Add(value);

        }

        DAL obj = new DAL();

        int rows = obj.AddRecord(lstValues[1], lstValues[2], Convert.ToInt32(lstValues[3]), lstValues[4], lstValues[5]);

        if (rows > 0)

            returnValue = "Successfull";

        else

            returnValue = "Error";

        return returnValue;

    }

}

Now to test it I've added a page with the name Default.aspx.

On the Markup page (the default.aspx page) we just took a gridview control.

Default.aspx Code behind
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Configuration;

using System.Data.OracleClient;

using System.Data;

 

public partial class _Default : System.Web.UI.Page

{

    private string _pageName = string.Empty;

 

    protected void Page_Load(object sender, EventArgs e)

    {

        _pageName = System.Web.HttpContext.Current.Request.Url.AbsolutePath;

        System.IO.FileInfo oInfo = new System.IO.FileInfo(_pageName);

        _pageName = oInfo.Name;

        LoadData();

    }

 

    private void LoadData()

    {

        DAL objDal = new DAL();

        DataSet ds = objDal.GetRecords();

        if (ds != null)

        {

            GridView1.DataSource = ds.Tables[0].DefaultView;

            GridView1.DataBind();

        }

        else

        {

            bool tableStatus = true;

            //Define controls index position for eg at index 1,2,3,5 textbox will be there and at index 4 DropDownList

            int[] txtFieldsIndex = { 1, 2, 3, 4 };

            int[] ddlFieldsIndex = { 5 };

            //Define Column names

            string[] colNames = { "EID", "EName", "EAddress", "EAge", "EDesignation", "ECountry" };

            string errorMsg = "";

            EmptyColumn[] cols = new EmptyColumn[colNames.Length];

 

            for (byte i = 0; i < cols.Length; i++)

            {

                cols[i] = new EmptyColumn()

                {

                    ColumnName = colNames[i],

                    IsReadOnly = txtFieldsIndex.Contains(i) == true ? false : ddlFieldsIndex.Contains(i) == true ? false : true,

 

                    ColumnControl = txtFieldsIndex.Contains(i) == true ? new TextBox()

                    {

                        ID = string.Concat("txt", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 15,

                    }

                    :

                    ddlFieldsIndex.Contains(i) == true ? (WebControl)new DropDownList()

                    {

                        ID = string.Concat("ddl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Height = 20,

                        AutoPostBack = true,

                        DataSource = new ListItemCollection { new ListItem("Select"), new ListItem("India"), new ListItem("China") }

                    }

                    :

                    (WebControl)new Label()

                    {

                        ID = string.Concat("lbl", colNames[i]),

                        ForeColor = System.Drawing.Color.Black,

                        Width = new Unit(200),

                        Text = "0",

                        Height = 15,

                    }

                };

            }

            //Creating list of EmptyGridRows

            List<EmptyGridRow> lstRows = new List<EmptyGridRow>();

 

            foreach (EmptyColumn col in cols)

            {

                //Checking whether the column name has already being added or not

                if (lstRows.CheckItem<EmptyGridRow, EmptyColumn>(col, out errorMsg))

                    lstRows.Add(new EmptyGridRow() { Columns = col });

                else

                {

                    tableStatus = false;

                    ClientScript.RegisterStartupScript(this.GetType(), "error", "<script>alert('" + errorMsg + "');</script>");

                }

            }

            if (tableStatus == true)

            {

                //Binding the EmptyTemplate to our GridView

                EmptyGridTemplate objTemplate = new EmptyGridTemplate(ListItemType.Header, lstRows, _pageName);

                GridView1.EmptyDataTemplate = objTemplate;

                GridView1.DataBind();

            }

        }

    }

}

Let's try to run the Default.aspx page. Before running we will truncate the Employees table so that there are no records and our EmptyGridTemplate can be applied to the GridView's EmptyDataTemplate. Now when you run your Default.aspx page you'll see the following output.

EmptyDataTemp7.jpg
On the Button click event it will class the jsHelper function that will insert the data into my Employees table by making use of the AjaxHeper.aspx file and you will get the following output:

EmptyDataTemp8.jpg
I hope you all liked the article.