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.