Getting values from textbox in the repeater in button click event - asp.net

I have a TextBox in a repeater that is populated from the database in the ItemDataBound event. When I tried to get the text inside the TextBox in a Button_Click event I found the TextBox.Text empty. How can I get the Text?
foreach (RepeaterItem repeated in repEdit.Items)
{
DropDownList drp = (DropDownList)FindControlRecursive(repeated, "drpdown");
TextBox txt = (TextBox)FindControlRecursive(repeated, "txt");
CheckBox chk = (CheckBox)FindControlRecursive(repeated, "chk");
if (drp != null && !string.IsNullOrEmpty(drp.Attributes["ID"]))
{
loc.GetType().GetProperty(drp.Attributes["ID"].Split('#')[0] + "ID").SetValue(loc, int.Parse(drp.SelectedValue), null);
}
if (txt != null && !string.IsNullOrEmpty(txt.Attributes["ID"]))
{
if (txt.Attributes["ID"].Contains("#int"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, int.Parse(txt.Text), null);
}
else if (txt.Attributes["ID"].Contains("#decimal"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, decimal.Parse(txt.Text), null);
}
else
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, txt.Text, null);
}
}
if (chk!=null && !string.IsNullOrEmpty(chk.Attributes["ID"]))
{
loc.GetType().GetProperty(chk.Attributes["ID"].Split('#')[0]).SetValue(loc, chk.Checked, null);
}
}
HTML
<asp:Repeater ID="repEdit" runat="server" OnItemDataBound="repEdit_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Visible="false"></asp:Label>
<asp:TextBox ID="txt" runat="server" Visible="false"></asp:TextBox>
<asp:CheckBox ID="chk" runat="server" Visible="false" />
<asp:DropDownList ID="drpdown" runat="server" Visible="false">
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
Here is the itemdatabound event
protected void repEdit_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Label name = e.Item.FindControl("lblName") as Label;
TextBox text = e.Item.FindControl("txt") as TextBox;
CheckBox chk = e.Item.FindControl("chk") as CheckBox;
DropDownList drp = e.Item.FindControl("drpdown") as DropDownList;
Button but = e.Item.FindControl("butEdit") as Button;
//butEdit.Visible = true;
if (but != null)
{
but.Visible = true;
}
if (e.Item.ItemType == ListItemType.Item)
{
KeyValuePair<string, Dictionary<int, string>> kvp = (KeyValuePair<string, Dictionary<int, string>>)e.Item.DataItem;
if (name != null)
{
if (kvp.Key.Contains("#datetime"))
{
return;
}
name.Visible = true;
name.Text = kvp.Key.Split('#')[0].ToString();
}
if (kvp.Key.Contains("#int") || kvp.Key.Contains("#decimal"))
{
text.Visible = true;
text.ID = kvp.Key;
text.EnableViewState = true;
text.Attributes["ID"] = kvp.Key;
text.Text = kvp.Value[0].ToString();
if (kvp.Key.Split('#')[0] == "ID")
{
text.Enabled = false;
}
}

Here is your Repeater. It has a PlaceHolder and Button.
<asp:Repeater ID="rpNotifications" runat="server"
OnItemDataBound="rpNotifications_ItemDataBound">
<ItemTemplate>
<asp:PlaceHolder ID="commentHolder" runat="server"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnComment"
Text="Comment" CssClass="btn blue"
OnClick="btnComment_Click" CommandArgument='<%# Eval("id") %>' />
</ItemTemplate>
</asp:Repeater>
The button has the command argument set as the Id of the data I am binding to it.
Next here is where you need to Bind your Repeater. If you don't Bind it in the Page_Init the resulting values in the dynamically created controls will be lost.
protected void Page_Init(object sender, EventArgs e)
{
rpNotifications.DataSource = {datasource-here}
rpNotifications.DataBind();
}
And here is why (Image from: http://msdn.microsoft.com/en-us/library/ms972976.aspx)
Dynamically Create Control on ItemDataBound
You will need to add the textbox to the placeholder as this is the only way to dynamically assign an ID to the control.
protected void rpNotifications_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem)
{
Common.Models.Item item = (Common.Models.Item)e.Item.DataItem;
// Create new Control
TextBox txtComment = new TextBox();
txtComment.ID = String.Format("txtComment{0}", item.id.ToString());
// Ensure static so you can reference it by Id
txtComment.ClientIDMode = System.Web.UI.ClientIDMode.Static;
// Add control to placeholder
e.Item.FindControl("commentHolder").Controls.Add(txtComment);
}
}
Get Value On Button Click
Now you need to create the event handler for the button and get the resulting value
protected void btnComment_Click(object sender, EventArgs e)
{
// This is the ID I put in the CommandArgument
Guid id = new Guid(((Button)sender).CommandArgument);
String comment = String.Empty;
// Loop through the repeaterItems to find your control
foreach (RepeaterItem item in rpNotifications.Controls)
{
Control ctl = item.FindControl(
String.Format("txtComment{0}", id.ToString()));
if (ctl != null)
{
comment = ((TextBox)ctl).Text;
break;
}
}
}

Try to get ASP.Net controls using below code
DropDownList drp = (DropDownList)repeated.FindControl("drpdown");
TextBox txt = (TextBox)repeated.FindControl("txt");
CheckBox chk = (CheckBox)repeated.FindControl("chk");
Then you can get values from there respective properties.

Related

set text to textbox based on selected value from dropdownlist in gridview asp net

I have one Dropdown and one textBox in my gridview.
gridview contains some subject name and in database there is fees for particular
subject. I want to show that Fees into textbox on every value selected for dropdown.
i have done the same functionality which gives exact output what i want but not immediately after selection of subject, it gives value on button click.
may be i have done something wrong but not found exact solution please help.
ASPX code :
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false" OnRowDataBound="Gridview1_RowDataBound" CssClass="EU_DataTable">
<Columns>
<asp:TemplateField HeaderText="Program Name">
<ItemTemplate>
<asp:DropDownList ID="ddl_ProgList" runat="server" AppendDataBoundItems="true" OnSelectedIndexChanged="ddl_ProgList_SelectedIndexChanged" ControlStyle-Width="160px">
<asp:ListItem Value="-1">Select</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fees">
<ItemTemplate>
<asp:TextBox ID="txt_fees" runat="server" ControlStyle-Width="75px"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind :
protected void Gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Control ctrl = e.Row.FindControl("ddl_ProgList");
if (ctrl != null)
{
DropDownList dd = ctrl as DropDownList;
//SqlConnection conn = new SqlConnection(connStr);
clsProg_TB objprg = new clsProg_TB();
objprg.Center_Code = ddl_centerCode.SelectedItem.ToString();
DataSet ds = clsUserLogicLayer.LoadPrograms(objprg);
dd.DataTextField = "prg_Name";
dd.DataValueField = "prg_Name";
dd.DataSource = ds.Tables[0];
dd.DataBind();
}
}
}
protected void ddl_ProgList_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = sender as DropDownList;
foreach (GridViewRow row in Gridview1.Rows)
{
Control ctrl = row.FindControl("ddl_ProgList") as DropDownList;
if (ctrl != null)
{
DropDownList ddl1 = (DropDownList)ctrl;
if (ddl.ClientID == ddl1.ClientID)
{
TextBox txt2 = row.FindControl("txt_fees") as TextBox;
clsProg_TB objprg = new clsProg_TB();
objprg.Center_Code = ddl_centerCode.SelectedItem.ToString();
objprg.Prg_Name = ddl1.SelectedItem.ToString();
DataSet ds = clsUserLogicLayer.getProgFees(objprg);
if (ds.Tables[0].Rows.Count != 0)
{
txt2.Text = ds.Tables[0].Rows[0][0].ToString();
}
}
}
}
}
You can try to update Row and the bind the gridview again. You also need to set GridView.SetEditRow() before starting editing. Another way is to update your dataTable and bind it again.
protected void ddl_ProgList_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = sender as DropDownList;
foreach (GridViewRow row in Gridview1.Rows)
{
GridView.SetEditRow(row.RowIndex);
Control ctrl = row.FindControl("ddl_ProgList") as DropDownList;
if (ctrl != null)
{
DropDownList ddl1 = (DropDownList)ctrl;
if (ddl.ClientID == ddl1.ClientID)
{
TextBox txt2 = row.FindControl("txt_fees") as TextBox;
clsProg_TB objprg = new clsProg_TB();
objprg.Center_Code = ddl_centerCode.SelectedItem.ToString();
objprg.Prg_Name = ddl1.SelectedItem.ToString();
DataSet ds = clsUserLogicLayer.getProgFees(objprg);
if (ds.Tables[0].Rows.Count != 0)
{
txt2.Text = ds.Tables[0].Rows[0][0].ToString();
}
}
}
Gridview1.UpdateRow(row.RowIndex, false);
}
Gridview1.DataBind();
}

how to get checkbox is check in gridview OnRowEditing

if anyone can help me, I have problems with gridview, when I use OnRowEditing and OnRowDeleting and inside asp: TemplateField, ItemTemplate I am using a checkbox, when checked the checkbox in checkbox.checked value is never true,
below is my C # script
<asp: Button ID = "Button1" runat = "server" BackColor = "# EFF1F1" BorderStyle = "None"
onclick = "Button1_Click" Text = "Submit Work Program" />
<asp: GridView ID = "GV_program" runat = "server" AutoGenerateColumns = "False"
Its DataKeyNames = "KD_BIDANG" Width = "100%" AutoGenerateEditButton = "True"
AutoGenerateDeleteButton = "true" OnRowEditing = "GV_program_RowEditing"
OnRowDeleting = "GV_program_RowDeleting" OnRowDataBound = "GV_kegiatan_RowDataBound"
BackColor = "White" EmptyDataText = "No Data Activity" AllowPaging = "True">
<EmptyDataRowStyle BackColor="#FF9900" />
<Columns> <asp:TemplateField HeaderStyle-Width="20px"> <ItemTemplate>
<asp:CheckBox ID="cbSelect" runat="server" /> </ItemTemplate> </asp:TemplateField>
</ Columns> </ asp: GridView>
C #
protected void Button1_Click (object sender, EventArgs e)
{
foreach (GridViewRow row in GV_program.Rows)
{
if (((CheckBox) row.FindControl ("cbSelect")). Checked)
{
// Delete something (never get here)
}
}
}
take it one step at a time until you get it working......
Try this:
/* put this value at the "class level" */
public static readonly int GRID_VIEW_COLUMN_ORDINAL_chkBoxSELECT = 3; /* Your number may be different, its the ordinal column number. A static readonly or const value makes your code more readable IMHO */
/*Then in your method */
if (null != this.GV_program)
{
Control cntl = null;
foreach (GridViewRow gvr in this.GV_program.Rows)
{
cntl = gvr.Cells[GRID_VIEW_COLUMN_ORDINAL_chkBoxSELECT].FindControl("cbSelect");
CheckBox cbIsApproved = cntl as CheckBox;
if (null != cbIsApproved)
{
bool myValue = cbIsApproved.Checked;
}
}
}
I just ran this code, and it worked for me.
protected void imgbutSave_Click(object sender, ImageClickEventArgs e)
{
if (null != this.gvMain)
{
Control cntl = null;
string finalMsg = string.Empty;
int counter = 0;
StringBuilder sb = new StringBuilder();
foreach (GridViewRow gvr in this.gvMain.Rows)
{
counter++;
cntl = gvr.Cells[GRID_VIEW_COLUMN_ORDINAL_chkBoxIsApproved].FindControl("chkBoxIsApproved");
CheckBox cbIsApproved = cntl as CheckBox;
if (null != cbIsApproved)
{
sb.Append(string.Format("Row '{0}' (chkBoxIsApproved.Checked) = '{1}'", counter, cbIsApproved.Checked) + System.Environment.NewLine);
}
}
finalMsg = sb.ToString();
}
}
and my aspx code
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkBoxIsApproved" runat="server" Checked='<%#Eval("IsApproved")%>'>
</asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
My StringBuilder had all of the checkboxes on my page, with the correct .Checked value.

ASP.NET button does not run the related function

I have an UpdatePanel, in it a GridView, and in it a Repeater. There is a button to add comment. This button post backs but id does not run the function code behind. Here is my code
<updatepanel>
<gridview>
<repeater>
<asp:Button ID="kitapVarYorumEkle" runat="server"
CommandArgument='<%#Eval("id") %>'
CommandName='<%# GridView1.Rows.Count.ToString() %>'
Text="Yorum ekle" class="blueButton"
OnClick="kitapVarYorumEkle_Click" />
</repeater>
</gridview>
</updatepanel>
Code inside the js is:
protected void kitapVarYorumEkle_Click(object sender, EventArgs e)
{
kitapVarYorum temp = new kitapVarYorum();
if (Session["id"] != null)
{
temp.uyeId = Convert.ToInt32(Session["id"]);
}
Button btn = (Button)sender;
temp.kitapVarId = Convert.ToInt32(btn.CommandArgument);
string text = "";
GridViewRow row = GridView1.Rows[Convert.ToInt32(btn.CommandName)];
if (row != null)
{
TextBox txt = row.FindControl("txtYorum") as TextBox;
if (txt != null)
{
text = txt.Text;
}
}
temp.icerik = text;
var db = Tools.DBBaglanti();
db.kitapVarYorums.InsertOnSubmit(temp);
db.SubmitChanges();
// Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
I have tried it outside the the controls and it works
Have you tried the ItemCommand approach?
<asp:Button
CommandArgument='<%#Eval("id") %>'
CommandName="yourCommandNameOfChoice"
Text="Yorum ekle"
ID="kitapVarYorumEkle"
class="blueButton" runat="server"
OnClick="kitapVarYorumEkle_Click" />
now add an ItemCommand event for your repeater:
protected void yourRepeater_ItemCommand(object source , RepeaterCommandEventArgs e)
{
switch(e.CommandName)
{
case "yourCommandNameOfChoice":
// Your Code Here
break;
}
}

Cannot find selected value of dynamically added controls in repeater

I am creating a survey page that has a list of questions and answers that can be radiobuttonlists, checkboxlists or textboxes. These controls are added dynamically to a Repeater in its ItemDataBound event using Controls.Add.
I've managed to render the page ok but when I submit the form and iterate over the controls in the repeater to get the selectedvalues of the radiobuttons and textbox values, FindControl returns null. What do I need to do to get get the selected values? I've tried iterating over the RepeaterItems but that returned null too. I've tried different types of FindControl but it never resolves the control types.
It works if I add a declarative DataBinder in the Repeater like this
<asp:Repeater ID="rptSurvey" runat="server" Visible="true" EnableViewState="true" >
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Question") %>
</ItemTemplate>
</asp:Repeater>
However, I want want to dynamically add the controls but in doing this i cant get the selectedvalues when submitting. This is tha main structure of my code...
<html>
<asp:Repeater ID="rptSurvey" runat="server" Visible="true">
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
</html>
protected void Page_Load(object sender, EventArgs e)
{
...
if (!IsPostBack)
{
rptSurvey.DataSource = GetQuestions();
rptSurvey.DataBind();
}
...
}
protected void rptSurvey_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string question = (DataBinder.Eval(e.Item.DataItem, "Question")).ToString();
litQuestion = new Literal();
litQuestion.Text = question;
RadioButtonList rblAnswer = (RadioButtonList)item;
rptSurvey.Controls.Add(rblAnswer);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
...
Dictionary<int, string> answers = new Dictionary<int, string>();
try
{
var list = FindControls(rptSurvey, c => c is RadioButtonList || c is CheckBoxList || c is TextBox);
foreach (Control item in list)
{
QuestionId = int.Parse(Questions.Rows[list.IndexOf(item)][0].ToString());
if (item is TextBox)
{
TextBox txtAnswer = (TextBox)item;
answers.Add(QuestionId, txtAnswer.Text);
}
else if (item is RadioButtonList)
{
RadioButtonList rblAnswer = (RadioButtonList)item;
answers.Add(QuestionId, rblAnswer.SelectedItem.Text);
}
else if (item is CheckBoxList)
{
// Iterate through the Items collection of the CheckBoxList
string cblMultiAnswer = "";
for (int i = 0; i < cblAnswer.Items.Count; i++)
{
if (cblAnswer.Items[i].Selected)
{
cblMultiAnswer += cblAnswer.Items[i].Value + ",";
}
}
answers.Add(QuestionId, cblMultiAnswer);
}
}
bSurvey.BLInsertSurveyAnswers(answers, dateCreated, _userEmail);
}
}
public static List<Control> FindControls(Control parent, Predicate<Control> match)
{
var list = new List<Control>();
foreach (Control ctl in parent.Controls)
{
if (match(ctl))
list.Add(ctl);
list.AddRange(FindControls(ctl, match));
}
return list;
}
you have to create the control tree first (always - not only on non-postbacks). do it in the oninit or onpreload event.
look here: https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx

Why is the footer-item not included in Repeater.Items?

I need to get a value from a textbox inside a FooterTemplate in the OnClick event of a button. My first thought was to loop through the items-property on my repeater, but as you can see in this sample, it only includes the actual databound items, not the footer-item.
ASPX:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
Item<br />
</ItemTemplate>
<FooterTemplate>
Footer<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
Code-behind.cs:
protected void Page_Load(object sender, EventArgs e)
{
ListItemCollection items = new ListItemCollection();
items.Add("value1");
items.Add("value2");
Repeater1.DataSource = items;
Repeater1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(Repeater1.Items.Count);
}
This code will only output "2" as the count, so how do I get to reference my textbox inside the footertemplate?
From the MSDN documentation, the Items is simply a set of RepeaterItems based off the DataSource that you are binding to and does not include items in the Header or FooterTemplates.
If you want to reference the textbox, you can get a reference on ItemDataBound event from the repeater where you can test for the footer.
E.g.
private void Repeater_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
TextBox textBox = e.Item.FindControl("TextBox1") as TextBox;
}
}
You can find controls in the repeater. That will give you all the controls in the repeater (RepeaterItems collection). Now you can do something like this:
RepeaterItem footerItem=null;
foreach(Control cnt in Repeater1.Controls)
{
if(cnt.GetType() == typeof(RepeaterItem) && ((RepeaterItem)cnt).ItemType == ListItemType.Footer)
{
footerItem = cnt;
break;
}
}
The footer should be the last child control of the repeater so you can do something like..
RepeaterItem riFooter = Repeater1.Controls[Repeater1.Controls.Count - 1] as RepeaterItem;
if (riFooter != null && riFooter.ItemType == ListItemType.Footer) {
TextBox TextBox1 = riFooter.FindControl("TextBox1") as TextBox;
if (TextBox1 != null) {
TextBox1.Text = "Test";
}
}

Resources