Click here to Skip to main content
Click here to Skip to main content

Simply Expanding ASP.NET GridView

, 17 Mar 2008
Rate this:
Please Sign up or sign in to vote.
ASP.NET GridView which only displays as many rows as the user is willing to fill on the client-side. Uses ASP.NET, C#, JavaScript, Regular Expressions, CSS, and HTML.

Introduction

This is a simple solution to a simple problem. It shows an ASP GridView which when rendered in HTML expands row by row when needed. In other words, it's GridView expand on-demand.

Background

A coworker asked about having a GridView which would have rows dynamically show as long as the user keeps entering or editing data. There were ideas about using AJAX for it or other new fancy technologies. However, since on each new line adding, no new server data is required, I thought that this problem could be solved with lesser effort.

How the code works

*Since it's done in VS 2008, some syntax may be different.

The idea is that we bring the whole table (with full or empty rows) where the last updatable (meaning that the user can change its value) control in each row invokes a JavaScript function which will "add" another row:

function ShowNextLine(what)
{
    //below I use a simple regular expression which 
    //searches for a number. Often you may have your controls
    //which have numbers in their names - this will make 
    //the reg exp find that number, but not the "row" number 
    //therefore you will either need to rename your controls 
    //(GridView or Foo instead of GridView1)
    //or come up with a more flexible regular expression. 
    //I'd prefer the former for it's more comprehensive plus 
    //reg exps eat CPU. 

    //Get the number part of the  item (what) ID
    var s = parseInt(what.id.substring(what.id.search("\\d")));
    //take the "text part" of tr's id and concat 
    //it with an incremented what's - current Id
    document.getElementById("GridView_" + 
      (parseInt(s)+1).toString()).setAttribute("class","trVisible"); 
}

As you can see from the code, it doesn't add the next line, but makes it visible, through changing its CssClass. Prior to that, however, you have to make it invisible.

Rows are rendered in HTML as <TR>. In order to make a <TR> invisible, we can't use "visibility:hidden", nor can we use "height:0px". None of these would do the job. Only "display:none" will:

<style type="text/css">
    .trInvisible
    {        
        display:none;
    }
    .trVisible
    {
      display:table-row;
    }
</style>

When each table row is bound, we format it appropriately and set its CssClass value to "trInvisible". Read comments in the code:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
//this will fire on each row of the datasource 
{
    // (our datatable in this case) being bound to the GridView. 
    e.Row.ID = (this.j).ToString();
    //here we are setting the row id (rendered as <TR>
    //in HTML) to the counter - a secuential number;
    
    TextBox txtLastControlInRow = 
       (TextBox)e.Row.FindControl("txtDescription");
       // get the reference to the last textbox in the row
    if (txtLastControlInRow != null) //if it ain't null
    { 
        txtLastControlInRow.Attributes.Add("onfocus", 
          "ShowNextLine(this)");
          //add a JavaScript function call on control focus.
    }
        
    if (this.j > 1) //if this is not the header or the first row
    {
        e.Row.CssClass = "trInvisible";
        //make the row invisible through 
        //specifying the appropriate CSS class
    }
    this.j = this.j + 1; //increment the class global counter.
}

Before the table could be bound, we create a sample one:

private DataTable CreateFooTable()
//this will create a table, which we use to display the grid
{
    //this table is only for demonstration purposes
    //I could have used any other source of data (XML, Database, CSV, whatever)
    //But I chose making the table on the spot
    
    DataTable dt = new DataTable(); //the table to be created;
    int i = 1;

    dt.Columns.Add("Item_Id"); //add ID column
    dt.Columns.Add("Item_Description"); //add whatever other column(s);

    for (i=1; i <= 20; i++) //add 20 rows; 
    {
        dt.Rows.Add(i, "Foo Item " + i.ToString());
        //I am simply adding rows with i in first 
        //column and Item_i into the second;
    }

    return dt; //when the table is 20 rows, return it;
}

Points of interest

  1. It's a nice little exercise for using a combination of various technologies.
  2. Only "display:none" will make a table row invisible.

License

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

About the Author

Alexei Fimine
Software Developer
Canada Canada
"And though I have the gift of prophecy, and understand all mysteries, and all knowledge; and though I have all faith, so that I could remove mountains, and have not charity, I am nothing. And though I bestow all my goods to feed the poor, and though I give my body to be burned, and have not charity, it profiteth me nothing. Charity suffereth long, and is kind; charity envieth not; charity vaunteth not itself, is not puffed up, Doth not behave itself unseemly, seeketh not her own, is not easily provoked, thinketh no evil; Rejoiceth not in iniquity, but rejoiceth in the truth; Beareth all things, believeth all things, hopeth all things, endureth all things."

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 17 Mar 2008
Article Copyright 2007 by Alexei Fimine
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid