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)
{
var s = parseInt(what.id.substring(what.id.search("\\d")));
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)
{
e.Row.ID = (this.j).ToString();
TextBox txtLastControlInRow =
(TextBox)e.Row.FindControl("txtDescription");
if (txtLastControlInRow != null)
{
txtLastControlInRow.Attributes.Add("onfocus",
"ShowNextLine(this)");
}
if (this.j > 1)
{
e.Row.CssClass = "trInvisible";
}
this.j = this.j + 1;
}
Before the table could be bound, we create a sample one:
private DataTable CreateFooTable()
{
DataTable dt = new DataTable();
int i = 1;
dt.Columns.Add("Item_Id");
dt.Columns.Add("Item_Description");
for (i=1; i <= 20; i++)
{
dt.Rows.Add(i, "Foo Item " + i.ToString());
}
return dt;
}
Points of interest
- It's a nice little exercise for using a combination of various technologies.
- Only "
display:none
" will make a table row invisible.
"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."