When I load the page I send the number of rows the table will have:
protected void Page_Load(object sender, EventArgs e)
{
string numFilas = Request.QueryString["filas"];
tblAdd.Visible = true;
for (int i = 0; i < int.Parse(numFilas); i++)
{
TableRow NewRow1 = new TableRow();
TableCell NewCell1 = new TableCell();
TableCell NewCell2 = new TableCell();
TextBox txtBox1 = new TextBox();
txtBox1.Width = 200;
TextBox txtBox2 = new TextBox();
txtBox2.Width = 200;
// adding lebel into cell
NewCell1.Controls.Add(txtBox1);
NewCell2.Controls.Add(txtBox2);
// adding cells to row
NewRow1.Cells.Add(NewCell1);
NewRow1.Cells.Add(NewCell2);
tblAdd.Rows.Add(NewRow1);
}
}
now when I click submit I'd like to retrieve the data of the textbox inside the table, what I've been capable of is this:
public void submit(Object sender, EventArgs e)
{
for (Int32 i = 0; i < tblAdd.Rows.Count; i++)
{
TableRow dr = tblAdd.Rows[i];
TableCell hhh = dr.Cells[0];
String textCell = hhh.Text();
}
}
However, the text in the cells is empty because the text the user writes is IN the textbox, which I don't know how to get it.
Try this
While creating your text boxes add an ID
E.g.
txtBox1.ID = "txtBox1";
Then you can easily find this TextBox control from the current Cell's Controls collection as follows.
string textCell = ((TextBox)dr.Cells[0].FindControl("txtBox1")).Text;
Hope you understood what I'm trying to say. Basically, you need to find your control in the Cell.
Vote and accept the answer if it solved your issue.
Cheers!
Related
I am writing a code in webforms to add rows to a table after a button click. and inside some cells i need add html elements like textbox and dropdows,
protected void LinkButton1_Click(object sender, EventArgs e)
{
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
cell1.Text = "<input type=\"text\"></input>";
row.Cells.Add(cell1);
//proptable is the table id
PropTable.Rows.Add(row);
}
it works if i write like this.
but is there a more accurate way to do this?
any help is appreciated.
You can add Controls to TextBox easily like this:
protected void LinkButton1_Click(object sender, EventArgs e)
{
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
TextBox textbox = new TextBox();
textbox.Text = "Testing...";
//cell1.Text = "<input type=\"text\"></input>";
cell1.Controls.Add(textbox);
row.Cells.Add(cell1);
//proptable is the table id
PropTable.Rows.Add(row);
}
I am adding text boxes dynamically and trying to capture data entered in text box on button click. but what is happening is , though I entered the data in the text box, when I clicked the button, the page is getting loaded and the control is getting created again. As a result , I am loosing the data in the text box. Can you tell me how can I capture this data entered to the dynamically created text boxes.
My sample code is as follows:
protected void Page_Load(object sender, EventArgs e)
{
Table tblTextboxes = new Table();
for(int i=0;i<10;i++)
{
TableRow tr=new TableRow();
TableCell tc=new TableCell();
TextBox tb=new TextBox();
tb.ID=i.ToString();
tc.Controls.Add(tb);
tr.Cells.Add(tc);
TableCell tc1=new TableCell();
LinkButton lnk=new LinkButton();
lnk.ID=i.ToString()+tb.Text+"lnk";
lnk.Text = "Show";
lnk.Click+=new EventHandler(lnk_Click);
tc1.Controls.Add(lnk);
tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
void lnk_Click(object sender, EventArgs e)
{
LinkButton lnk=sender as LinkButton;
Label lbl=new Label();
lbl.Text="The text is"+lnk.ID;
placeTest.Controls.Add(lbl);
}
LinkButton ID is changed every time you enter text into TextBox and post back.
One thing you want to make sure when creating control dynamically is - you want to recreate them with same ID when post back.
Updated Solution (to retrieve text from TextBox)
protected void Page_Load(object sender, EventArgs e)
{
var tblTextboxes = new Table();
for (int i = 0; i < 10; i++)
{
var tr = new TableRow();
var tc = new TableCell();
var tb = new TextBox {ID = i.ToString()};
tc.Controls.Add(tb);
tr.Cells.Add(tc);
var tc1 = new TableCell();
// This is a fix for - lnk.ID=i.ToString()+tb.Text+"lnk";
var lnk = new LinkButton {ID = i + "lnk", Text = "Show"};
lnk.Click += lnk_Click;
tc1.Controls.Add(lnk);
tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
void lnk_Click(object sender, EventArgs e)
{
var lnk = sender as LinkButton;
var lbl = new Label();
lbl.Text = "LinkButton ID: " + lnk.ID;
// Get number value from string
string id = Regex.Replace(lnk.ID, #"[^\d]", "");
// Retrieves a TextBox control by ID
var control = FindControlRecursive(Page, id);
if (control != null)
{
var textbox = control as TextBox;
lbl.Text += "; TextBox Text: " + textbox.Text;
}
placeTest.Controls.Add(lbl);
}
public Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}
Based on the MSDN, I would recommend to use Page class's Init event. Look in to the title View State and Dynamically Added Controls for explanation. Also, I would recommend to add dynamic controls at the end of all existing controls. Create table first, and then add the text boxes.
I modified your code. It worked for me. I used VS 2012, .Net 4.5
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
}
protected void Page_Init(object sender, EventArgs e)
{
Table tblTextboxes = new Table();
for (int i = 0; i < 10; i++)
{
TableRow tr = new TableRow();
TableCell tc = new TableCell();
TextBox tb = new TextBox();
tb.ID = i.ToString();
tc.Controls.Add(tb);
tr.Cells.Add(tc);
//TableCell tc1 = new TableCell();
//LinkButton lnk = new LinkButton();
//lnk.ID = i.ToString() + tb.Text + "lnk";
//lnk.Text = "Show";
//lnk.Click += new EventHandler(lnk_Click);
//tc1.Controls.Add(lnk);
//tr.Cells.Add(tc1);
tblTextboxes.Rows.Add(tr);
}
placeTest.Controls.Add(tblTextboxes);
}
protected void Button1_Click(object sender, EventArgs e)
{
}
I read all related posts , but still could not understand the prob that am currently facing.On Oninit I create table with text boxes as follows, when i assign an id to the text box the textchanged event does not fire, but when i do not assign an ID it fires. Cant reason out why. Kindly help.
protected override void OnInit(EventArgs e)
{
PopulateTextBoxes();
base.OnInit(e);
}
protected void PopulateTextBoxes()
{
int quantityRequired = 0;
quantityRequired =GetQuantity();
for (int j = 0; j < quantityRequired; j++)
{
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
TextBox tb = new TextBox();
//tb.ID = j.ToString() +":RowTbx";---> this when uncommented does not fire my tb_textChanged event while left commented the textchanged event is fired. Cant understand why? How is assigning an ID affect event Firing, I need to have the ID to further update my Db.
tb.AutoPostBack = true;
tb.TextChanged += new EventHandler(tb_TextChanged);
cell1.Controls.Add(tb);
row.Cells.Add(cell1);
TableCell cell2 = new TableCell();
CheckBox chBox = new CheckBox();
chBox.CheckedChanged += new EventHandler(chBox_CheckedChanged);
chBox.AutoPostBack = true;
cell2.Controls.Add(chBox);
row.Cells.Add(cell2);
TableCell cell3 = new TableCell();
Image img = new Image();
img.Width = Unit.Pixel(25);
img.Height = Unit.Pixel(25);
img.ImageUrl = "HttpRuntime.AppDomainAppVirtualPath" + "/Images/" +"img.jpeg";
cell3.Controls.Add(img);
row.Cells.Add(cell3);
tbl_Serial.Rows.Add(row);
}
}
private void tb_TextChanged(object sender, EventArgs e)
{
// TODO: Implement this method
//throw new NotImplementedException();
}
Thank you
The id you are setting is not a valid control id.
Refer: Control.ID
Only combinations of alphanumeric characters and the underscore
character ( _ ) are valid values for this property. Including spaces
or other invalid characters will cause an ASP.NET page parser error.
try this:
tb.ID = "RowTbx" + j;
dont use : for ID. try this instead
tb.ID = j.ToString() + "_RowTbx";
I'm creating textboxes in the Page_Load event and giving them values, however whenever I load the details I am getting the same output. I always seem to get the first output I got, even on subsequent searches.
Here's what my code with the irrelevant information missing:
Textbox txtName = New Textbox();
protected void Page_Load(object sender, EventArgs e)
{
LoadData();
}
void LoadData()
{
txtName.Text = DropDownList.SelectedValue;
tableCell.Controls.Add(txtName);
}
If DropDownList has two values (e.g. "Item 1" and "Item 2") and has autopostback enabled, first time it will generate and show "Item 1" in the textbox (the default value for the DropDownList), but if this is changed and the autopostback fires, the textbox does not change.
I've tried getting around this by creating a new TextBox, overriding the "LoadPostData" function to prevent this from loading, which got around the issue there, but then I couldn't view the data afterwards.
Any idea how I could get around this? I may be approaching this in the wrong way.
Edit: I've added another item to DropDownList that removes TextBox, so that it can be re-created again. It seems to show the correct data when it is re-created after being removed, but if I'm attempting to just edit it, this isn't updating correctly.
Edit2: Here's the rest of the code for this page in case this helps at all. The objects which I'm having issues with are SBUName and SBUComments, which are both TextBoxes. The same issue is also happening for SBUClientDropdown but I believe the resolution will be similar:
DBHandler DBHandler = new DBHandler();
List<string> clients = new List<string>();
List<string> clientGroups = new List<string>();
List<string> sbus = new List<string>();
// Objects for SBU changes
string previousSBU = "";
string previousSBUClient = "";
TextBox SBUName = new TextBox() { ID = "SBUName" };
TextBox SBUComments = new TextBox() { ID = "SBUComments" };
DropDownList SBUClientDropdown = new DropDownList();
protected void Page_Load(object sender, EventArgs e)
{
clients = DBHandler.GetClients();
clientGroups = DBHandler.GetClientGroups();
if (!Page.IsPostBack)
{
foreach (string client in clients)
{
SBUClientList.Items.Add(GenerateItem(client));
ClientList.Items.Add(GenerateItem(client));
}
foreach (string clientGroup in clientGroups)
ClientGroupList.Items.Add(GenerateItem(clientGroup));
}
if ((SBUClientList.SelectedValue.ToString() != previousSBUClient) || (SBUList.SelectedValue.ToString() != previousSBU))
{
previousSBUClient = SBUClientList.SelectedValue.ToString();
previousSBU = SBUList.SelectedValue.ToString();
sbus = DBHandler.GetSBUs(SBUClientList.SelectedValue);
SBUList.Items.Clear();
foreach (string sbu in sbus)
SBUList.Items.Add(GenerateItem(sbu));
LoadSBU();
}
}
void LoadSBU()
{
if ((SBUClientList.SelectedValue.Trim().Length > 0) && (SBUList.SelectedValue.Trim().Length > 0))
{
Entity thisSBU = DBHandler.GetSBUInformation(SBUClientList.SelectedValue, SBUList.SelectedValue);
SBUTable.Rows.Add(GenerateHeaderRow("Client Name", "SBU Name", "Comments"));
SBUClientDropdown.Items.Clear();
foreach (string client in clients)
SBUClientDropdown.Items.Add(GenerateItem(client));
SBUClientDropdown.SelectedValue = SBUClientList.SelectedValue;
SBUClientDropdown.SelectedIndex = SBUClientList.SelectedIndex;
TableCell SBUClientCell = new TableCell();
SBUClientCell.Controls.Add(SBUClientDropdown);
SBUName.Text = thisSBU.sSBUName;
TableCell SBUNameCell = new TableCell();
SBUNameCell.Controls.Add(SBUName);
SBUComments.Text = thisSBU.sSBUComments;
TableCell SBUCommentsCell = new TableCell();
SBUCommentsCell.Controls.Add(SBUComments);
SBUTable.Rows.Add(GenerateRow(SBUClientCell, SBUNameCell, SBUCommentsCell));
Button SBUSaveButton = new Button();
SBUSaveButton.Click += new EventHandler(this.SBUSaveChanges);
SBUSaveButton.Text = "Save SBU Changes";
TableCell SBUButtonCell = new TableCell();
SBUButtonCell.Controls.Add(SBUSaveButton);
SBUButtonCell.ColumnSpan = 3;
TableRow SBUFooter = GenerateRow(SBUButtonCell);
SBUFooter.TableSection = TableRowSection.TableFooter;
SBUTable.Rows.Add(SBUFooter);
}
}
void ShowMessage(string message)
{
OutputString.Text = "<div class=\"message\">" + message + "</div>";
}
ListItem GenerateItem(string input)
{
ListItem output = new ListItem();
output.Text = input;
return output;
}
TableCell GenerateCell(string text)
{
TableCell output = new TableCell();
output.Text = text;
return output;
}
TableRow GenerateRow(params TableCell[] cells)
{
TableRow output = new TableRow();
foreach (TableCell cell in cells)
output.Cells.Add(cell);
return output;
}
TableRow GenerateHeaderRow(params string[] columns)
{
TableRow output = new TableRow();
output.TableSection = TableRowSection.TableHeader;
foreach (string column in columns)
{
TableCell thisCell = new TableCell();
thisCell.Text = column;
output.Cells.Add(thisCell);
}
return output;
}
previousSBUClient and previousSBU will always be blank on each post back, so why do you compare against them on the Page_Load? If you want their values saved between postbacks you need to save them in ViewState, I suggest code like:
public string PreviousSBU
{
get { return Convert.ToString(ViewState["PreviousSBU"] ?? string.Empty); }
set { ViewState["PreviousSBU"] = value; }
}
Perhaps its because you add multiple header rows to the table, and only the contents between the first through the second get displayed? Any header rows after added don't get displayed?
On each postback you add a new header row. But the TextBox's are created on each postback and not saved between, so you shouldn't be seeing anything at all if thats the case.
To render txtName to the page, you should have something like:
this.Controls.Add(txtName); somewhere on the page, preferably in the Page_Init, though for what you've listed, at least before the LoadData() call in Page_Load.
Taking a guess at the missing code but are you databinding your dropdown list? If you are you may be doing it every time instead of just when the page is not a postback. Like I say, guessing at what's not in your question but you might want consider something like this instead:
if (!Page.IsPostback)
{
MyDropDownList.DataSource = blah;
MyDropDownList.DataBind();
}
myTextBox.Text = MyDropDownList.SelectedValue;
Create your controls in OnInit event, becouse viewstate serialization happens between oninit and onload. Also check if it is postback, to avoid overwriting values from viewstate.
I remember strange things happening if you don't supply an ID to the textbox, are you doing this?
txtName.ID="txtName";`
I have a DataTable which has columns that are generated dynamically at runtime. This DataTable is bound to a GridView that has AutoGenerateColumns set to true. I've run into a problem with this since some of the data in the DataTable are HyperLink objects, so instead of displaying the actual link in the table, it displays "System.Web.UI.WebControls.HyperLink".
Normally, I would just use a HyperLinkField in my GridView, but since the GridView's columns are generated automatically, I'm not sure how to do this. Any ideas?
You can add a new column dynamically, you'll just have to hide the automatically generated columns also.
For this solution you can either store the hyperlink in 2 columns - 1 for the link and 1 for the text you want displayed, or if you want something generic displayed (like 'Click Here') you can just store the link (eg "http://example.com.au/Default.aspx").
protected void GridView1_RowBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
//add new header
TableCell tc = new TableCell();
tc.Text = "Groovy Link";
e.Row.Cells.Add(tc);
//hide original column that has been autobound - skip column we just added
for (int i = 0; i < e.Row.Cells.Count - 1; i++)
{
BoundField field = (BoundField)((DataControlFieldCell)e.Row.Cells[i]).ContainingField;
if (field.DataField == "AutoGeneratedColumnName")
field.Visible = false;
}
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
//create new tablecell
TableCell tc = new TableCell();
//do a check to see if the data is stored as a hyperlink in DB
if (DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString().StartsWith("<a") == true)
{
//create hyperlink
HyperLink hyp = new HyperLink();
hyp.NavigateUrl = DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString();
hyp.Text = "click here";
tc.Controls.Add(hyp);
}
else
{
//just text
tc.Text = DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString()
}
//add tablecell to row
e.Row.Cells.Add(tc);
//hide original column that has been autobound
for (int i = 0; i < e.Row.Cells.Count - 1; i++)
{
BoundField field = (BoundField)((DataControlFieldCell)e.Row.Cells[i]).ContainingField;
if (field.DataField == "AutoGeneratedColumnName")
field.Visible = false;
}
}
}