I'm working on an ASP.NET form based application.
I have a repeater bound to database. It has any of the the following controls per row:
RadioButtonList
TextBox
DropDownList
CheckBoxList
There are one of the following validation controls per row:
RequiredFieldValidator
CustomValidator
I have a button outside the repeater. When I click on save button, the code will loop through each repeater item, read selected data and saves it in database.
The problem I'm facing is as soon as I click on save button, it gives me error:
The ControlToValidate property of 'reqValidator' cannot be blank.
I made sure that repeater is loaded for the first time only and not when the page is posted back. Also, the code in save button does not seem to be executed. Here is my code:
<cms:CMSUpdatePanel runat="server" ID="updatePanelCampaignQuestions">
<ContentTemplate>
<asp:Repeater ID="repeaterQuestions" runat="server" OnItemDataBound="repeaterQuestions_ItemDataBound">
<ItemTemplate>
<div class="repeater-container">
<asp:Label ID="lbQuestion" runat="server" Text='<%# Eval("Question") %>' />
<asp:Label ID="lbQuestionType" runat="server" Text='<%# Eval("QuestionType") %>' Style="display: inline; visibility: hidden" />
<asp:Label ID="lbAnswers" runat="server" Text='<%# Eval("Answers") %>' Style="display: inline; visibility: hidden" />
<asp:Label ID="lbArticleCampaignQuestionID" runat="server" Text='<%# Eval("ArticleCampaignQuestionID") %>' Style="display: inline; visibility: hidden" />
<div class="row validation-container">
<div class="col-md-12 col-lg-12">
<asp:TextBox ID="txtAnswer" CssClass="form-control" runat="server" TextMode="MultiLine" Rows="2" ValidationGroup="Campaign"></asp:TextBox>
<asp:RadioButtonList ID="rdAnswer" runat="server"></asp:RadioButtonList>
<asp:DropDownList ID="ddnAnswer" runat="server"></asp:DropDownList>
<asp:CheckBoxList ID="chkAnswer" CssClass="chkAnswer" runat="server"></asp:CheckBoxList>
<asp:RequiredFieldValidator ID="reqValidator" runat="server" Display="Dynamic" Style="color: #f00" />
<asp:CustomValidator ID="customValidator" runat="server" ClientValidationFunction="checkAnswer" Display="Dynamic" Style="color: #f00" />
<hr />
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
The code for repeater OnItemDataBound:
protected void repeaterQuestions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string questionType = (e.Item.FindControl("lbQuestionType") as Label).Text;
RequiredFieldValidator reqValidator = (RequiredFieldValidator)e.Item.FindControl("reqValidator");
CustomValidator customValidator = (CustomValidator)e.Item.FindControl("customValidator");
if (questionType.ToLower().Equals("text"))
{
e.Item.FindControl("txtAnswer").Visible = true;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = false;
reqValidator.ControlToValidate = e.Item.FindControl("txtAnswer").ID;
reqValidator.ErrorMessage = "Please fill the answer";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("single selection"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = true;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = false;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "@@" }, StringSplitOptions.None);
foreach(string answer in answers)
{
(e.Item.FindControl("rdAnswer") as RadioButtonList).Items.Add(answer);
}
reqValidator.ControlToValidate = e.Item.FindControl("rdAnswer").ID;
reqValidator.ErrorMessage = "Please select one";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("drop down"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = true;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "@@" }, StringSplitOptions.None);
(e.Item.FindControl("ddnAnswer") as DropDownList).Items.Add(new ListItem("- Please Select -", "0"));
foreach (string answer in answers)
{
(e.Item.FindControl("ddnAnswer") as DropDownList).Items.Add(answer);
}
reqValidator.InitialValue = "0";
reqValidator.ControlToValidate = e.Item.FindControl("ddnAnswer").ID;
reqValidator.ErrorMessage = "Please select one";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("multiple selection"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = true;
e.Item.FindControl("ddnAnswer").Visible = false;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "@@" }, StringSplitOptions.None);
foreach (string answer in answers)
{
(e.Item.FindControl("chkAnswer") as CheckBoxList).Items.Add(answer);
}
e.Item.Controls.Remove(reqValidator);
customValidator.ErrorMessage = "Please select at least one";
}
}
}
The code for save button:
private void SaveAnswer()
{
int userID = GetUserID();
int campaignID = GetCampaignID();
foreach (RepeaterItem item in repeaterQuestions.Items)
{
string answer = "";
string questionType = (item.FindControl("lbQuestionType") as Label).Text;
int articleCampaignQuestionID = int.Parse((item.FindControl("lbArticleCampaignQuestionID") as Label).Text);
if (questionType.ToLower().Equals("text"))
{
answer = (item.FindControl("txtAnswer") as TextBox).Text;
}
else if (questionType.ToLower().Equals("single selection"))
{
answer = (item.FindControl("rdAnswer") as RadioButtonList).SelectedItem.Text;
}
else if (questionType.ToLower().Equals("drop down"))
{
answer = (item.FindControl("ddnAnswer") as DropDownList).SelectedItem.Text;
}
else if (questionType.ToLower().Equals("multiple selection"))
{
CheckBoxList answerList = (item.FindControl("chkAnswer") as CheckBoxList);
foreach (ListItem checkItem in answerList.Items)
{
if (checkItem.Selected)
{
answer += checkItem.Text + "@@";
}
}
if (answer.EndsWith("@@"))
answer = answer.Substring(0, answer.Length - 2);
}
// save value of answer to database
}
I'm stuck on this for a very long time now. There is no other exception on the page other than the one mentioned above.
Edit
What is the flow of page postback?
Click on btnSaveAnswer , code for button executes , repeater is reloaded
Or
Click on btnSaveAnswer, repeater is reloaded , code for button executes
If I put repeater binding with:
if(!Page.IsPostBack)
I get the required field validator error
and
if I don't use above if, then I cannot read values from controls in repeater
ControlToValidateproperty, as the error says....<asp:RequiredFieldValidator ID="reqValidator" ControlToValidate="txtAnswer"- VDWWD