I've read forums which put text boxes in the gridviews footer for the user to enter a new record into a db. The problem with this is that the user would have to scroll down to the end of the gridview to enter new data. If the gridview has a lot of rows this isn't very intuitive.
The following code is how I'm dynamically adding a row under the header of a gridview. The row has text boxes for the user to enter data along with a linkbutton the user will click to insert the data entered into the text boxes into a SQL db.
I'm pretty new to asp.net and I haven't been able to figure out how to read the data from the textboxes when the linkbutton is clicked.
protected void gvDRM_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
//**** Gridview Header ****
if (e.Row.RowType == DataControlRowType.Header)
//**** Gridview Data ****
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dv = (System.Data.DataRowView)e.Row.DataItem;
if (dv.Row["UserID"].ToString() == "0")
{
e.Row.Visible = false;
}
//Create Link Button Object Instance
LinkButton lnkDeleteButton = (LinkButton)e.Row.FindControl("lnkDeleteButton");
//Add Javascript to link button
lnkDeleteButton.Attributes.Add("onclick", "javascript:return confirm('Are you sure you want to delete this Record?')");
}
//**** Gridview Footer ****
if(e.Row.RowType == DataControlRowType.Footer)
{
//**** Insert Add New Record row under the Header ****
GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
// Add the Columns
row.Cells.AddRange(CreateCells());
// get a reference to the table that holds this row
Table tbl = (e.Row.Parent as Table);
// Add the row under the header
tbl.Rows.AddAt(1, row);
}
}
catch (Exception)
{
}
}
private TableCell[] CreateCells()
{
TableCell[] cells = new TableCell[5];
//**** Add Linkbutton ****
TableCell cell0;
LinkButton lnkBtn;
cell0 = new TableCell();
cell0.ColumnSpan = 1;
cell0.BackColor = System.Drawing.Color.LightGray;
lnkBtn = new LinkButton();
lnkBtn.Text = "Add";
lnkBtn.CommandName = "Insert";
cell0.Controls.Add(lnkBtn);
cells[0] = cell0;
//******************************************
//**** New Date Textbox ****
TableCell cell1;
TextBox txt1;
cell1 = new TableCell();
cell1.ColumnSpan = 1;
cell1.BackColor = System.Drawing.Color.LightGray;
txt1 = new TextBox();
txt1.Text = string.Format("{0:d}", DateTime.Now.Date).ToString();
txt1.Width = 80;
txt1.ID = "txtAddDate";
//Calendar control
cell1.Controls.Add(txt1);
CalendarExtender cal = new CalendarExtender();
cal.TargetControlID = "txtAddDate";
cell1.Controls.Add(cal);
cells[1] = cell1;
//******************************************
//**** New DRM Textbox ****
TableCell cell2;
TextBox txt2;
cell2 = new TableCell();
cell2.ColumnSpan = 1;
cell2.BackColor = System.Drawing.Color.LightGray;
txt2 = new TextBox();
txt2.Text = "";
txt2.Width = 80;
txt2.ID = "txtAddDRM";
cell2.Controls.Add(txt2);
// Watermark
TextBoxWatermarkExtender wmAddDRM = new TextBoxWatermarkExtender();
wmAddDRM.ID = "wmAddDRM";
wmAddDRM.TargetControlID = "txtAddDRM";
wmAddDRM.WatermarkText = "Enter DRM #";
wmAddDRM.WatermarkCssClass = "watermark";
cell2.Controls.Add(wmAddDRM);
// Reg Exp Validator
RegularExpressionValidator revAddDRM = new RegularExpressionValidator();
revAddDRM.ControlToValidate = "txtAddDRM";
revAddDRM.ErrorMessage = "Numeric";
revAddDRM.ValidationExpression = "^[0-9]*$";
cell2.Controls.Add(revAddDRM);
cells[2] = cell2;
//******************************************
//**** New Hours Textbox ****
TableCell cell3;
TextBox txt3;
cell3 = new TableCell();
cell3.ColumnSpan = 1;
cell3.BackColor = System.Drawing.Color.LightGray;
txt3 = new TextBox();
txt3.Text = "";
txt3.Width = 80;
txt3.ID = "txtAddHour";
cell3.Controls.Add(txt3);
// Watermark
TextBoxWatermarkExtender wmAddHour = new TextBoxWatermarkExtender();
wmAddHour.ID = "wmAddHour";
wmAddHour.TargetControlID = "txtAddHour";
wmAddHour.WatermarkText = "Enter Hours";
wmAddHour.WatermarkCssClass = "watermark";
cell3.Controls.Add(wmAddHour);
// Reg Exp Validator
RegularExpressionValidator revAddHours = new RegularExpressionValidator();
revAddHours.ControlToValidate = "txtAddHour";
revAddHours.ErrorMessage = "Numeric";
revAddHours.ValidationExpression = "^[0-9]*\\.?[0-9]*$";
cell3.Controls.Add(revAddHours);
cells[3] = cell3;
//******************************************
//**** New Comments Textbox ****
TableCell cell4;
TextBox txt4;
cell4 = new TableCell();
cell4.ColumnSpan = 1;
cell4.BackColor = System.Drawing.Color.LightGray;
txt4 = new TextBox();
txt4.Text = "";
txt4.Width = 400;
txt4.ID = "txtAddComment";
cell4.Controls.Add(txt4);
// Watermark
TextBoxWatermarkExtender wmAddComments = new TextBoxWatermarkExtender();
wmAddComments.ID = "wmAddComments";
wmAddComments.TargetControlID = "txtAddComment";
wmAddComments.WatermarkText = "Enter Comments (optional)";
wmAddComments.WatermarkCssClass = "watermark";
cell4.Controls.Add(wmAddComments);
cells[4] = cell4;
//******************************************
return cells;
}
Loading
Elza SimpsonPosted Jan 25, 2010, 3:00 PM
The solution I came up with is simple and it works nicely - but I'm open for a better, more professional approach if someone has one.
What I ended up doing was to created static text boxes in a hidden panel. When the user enters data in the dynamically created text boxes under the gridview's header, javacript updates the text boxes in the hidden panel. When the dynamically created 'Add' button is clicked, the on page load event checks for data in the panel text boxes and adds the data to the database if data exists, then it clears the text boxes.
The dynamically created text boxes in the gridview are created when the gridview's footer is created. This allows for column sorting in the gridview and the text boxes are always right under the header.
Of course if the gridview has no data to display then the text boxes never get created and the user can't enter data. To get around this I made sure that at least one line of data appears - even if the line is empty. To do this I added a UNION SELECT to my SQL code. For example, if my SQL statement was SELECT id, FName, LName I would change it to SELECT id, FName, LName UNION SELECT '' AS id, '' AS FName, '' AS LName. This will always retun a blank row. Then I look for this blank row in the gridview RowDataBound event and set visible to false.
paul danielPosted Jan 25, 2010, 6:15 AM
http://geekswithblogs.net/casualjim/articles/51360.aspx
Elza SimpsonPosted Jan 19, 2010, 4:47 PM
Sam HobbsPosted Jan 17, 2010, 2:20 PM