Can't Add RegularExpressionValidator to Panel - c#

I'm having an issue with programmatically adding a RegularExpressionValidator to any Container control (Panel, Placeholder, etc.). Here is my code:
// Get the path of the file on the server
string page = Page.Request.FilePath;
int managementCompanyId = Convert.ToInt32(Session["ManagementCompanyId_AddResident"].ToString().Trim());
// Get field validation details
Collection<ExportFieldValidation> details = ValidationBL.GetValidationDetails(managementCompanyId, page);
ContentPlaceHolder body = Page.Form.FindControl("ContentBody") as ContentPlaceHolder;
foreach (ExportFieldValidation detailItem in details)
{
// Check if the control exists on the page
TextBox control = body.FindControl(detailItem.FieldToValidate) as TextBox;
if (control != null)
{
RegularExpressionValidator regex = new RegularExpressionValidator()
{
ControlToValidate = control.UniqueID.ToString(),
ID = detailItem.ValidatorFieldName,
ValidationExpression = detailItem.RegularExpression,
Page = this,
SetFocusOnError = true,
Text = detailItem.ErrorMessage,
Enabled = true,
EnableViewState = true,
CssClass = "Error"
};
Panel validationPanel = body.FindControl("PanelAddResident") as Panel;
validationPanel.Controls.Add(regex);
}
}
When I go to the page I get the error Unable to find control id 'myControl' referenced by the 'ControlToValidate' property of 'RegularExpressionValidatorResidentId', where my control is the control.UniqueID.ToString() from above, which we store in the database and is for sure correct, as I've double-, triple- and quadruple-checked the value.
However, if I replace validationPanel.Controls.Add(regex); with Page.Form.Controls.Add(regex); everything works perfectly.
Is there a way to add my validator to the container? I'm sure I'm just doing something wrong or missing a step in the middle somewhere. Any help would be greatly appreciated.

This part is wrong:
ControlToValidate = control.UniqueID.ToString()
You need to use this:
ControlToValidate = control.ID;
You must provide an ID for control before.
UniqueID is the name the component will have in the client but Validator Controls use the server side control name to do this.

Related

Asp.net Custom Table Cell ClientID not set

I have a class derived from WebControls.TableCell.
When the Text property is set, I call a method that dynamically adds asp:Panels and asp:LiteralControls to the Cell. I want to reference these controls in Javascript, so naturally I tried using the ClientId of the panels in my JS functions. However, these controls have no ClientId set (the string is empty). Why is this? How do I force the ClientIds to be set?
As a temporary solution, I set the ClientIDMode to "static" and created the IDs on my own, but this is not satisfactory because it's hard to reference those IDs in JS. Why? If you assign, for example, "12345" to one control, it gets changed on client side to something like "MainContent_123456". This is bad because the "MainContent" part is not fixed; thus I never know for sure what the real Id on the client side will be. Currently, I can get the control with jQuery using $ctrl = $('[id$='12345']');, but this is dirty because it would get any control that has '123456' in its id.
So, back to the original question: how do I get my ClientIds set automatically for my panels in my custom TableCells?
Edit: Code added
protected void Page_Load(object sender, EventArgs e)
{
this.ClientIDMode = System.Web.UI.ClientIDMode.Static;
}
Code in the method that adds the controls to the custom TableCell:
Panel remainingTextPanel = new Panel();
remainingTextPanel.ID = Guid.NewGuid().ToString();
remainingTextPanel.Style["display"] = "none";
LiteralControl remainingText = new LiteralControl(myText.Substring(initialStringLength, myText.Length - initialStringLength));
remainingTextPanel.Controls.Add(remainingText);
this.Controls.Add(remainingTextPanel);
Panel linkBtnPanel = new Panel();
LinkButton lnkBtn = new LinkButton() {Text = "...", OnClientClick = "toggleDynamicText('" + remainingTextPanel.ID + "'); return false;" };
lnkBtn.Font.Bold = true;
linkBtnPanel.Controls.Add(lnkBtn);
this.Controls.Add(linkBtnPanel);
And the JS Code:
function toggleDynamicText(id) {
$ctrl = $('[id$=' + id + ']');
$(document).ready(function () {
$ctrl.toggle(1000);
});
}
Without seeing any code it's difficult to say what's going on but to access your controls using jQuery you can do the following:
$("#<%=myElement.ClientID%>")
This way it doesn't matter what .NET assigns as the ID.

RequiredFieldValidator not working in a repeater

I'm trying to dynamically add a RequiredFieldValidator to a RadioButtonList in a repeater, but it fails with the error:
Unable to find control id 'rblAccessory_40' referenced by the 'ControlToValidate' property of ''.
The code for this section is:
if ((e.Item.ItemType != ListItemType.Header) && (e.Item.ItemType != ListItemType.Footer))
{
Label lblAccID = (Label)e.Item.FindControl("lblAccID");
RadioButtonList rblCondition = (RadioButtonList)e.Item.FindControl("rblCondition");
rblCondition.ID = "rblAccessory_" + lblAccID.Text;
if (conditionList.Count() > 0)
{
RequiredFieldValidator rfv = new RequiredFieldValidator();
rfv.ControlToValidate = "rblAccessory_" + lblAccID.Text;
rfv.ErrorMessage = "Please complete the accessories section";
pnlValidation.Controls.Add(rfv);
rblCondition.DataSource = conditionList;
rblCondition.DataValueField = "id";
rblCondition.DataBind();
}
foreach (ListItem li in rblCondition.Items)
{
li.Text = "";
li.Value = "AccessoryID_" + lblAccID.Text + "-ConditionID_" + li.Value;
}
}
}
It is definitely finding the RadioButtonList (rblCondition) because the data is binding correctly at this point:
rblCondition.DataSource = conditionList;
rblCondition.DataValueField = "id";
rblCondition.DataBind();
So I don't understand why the error says it is unable to find the control ID.
I've tried specifying the control ID manually, as below:
rfv.ControlToValidate = "rblAccessory_" + lblAccID.Text;
and have also tried:
rfv.ControlToValidate = rblCondition.ID;
lblAccID is a hidden text field used to store the ID of the row in the repeater.
Assign the control to validate property AFTER the ItemCreated event. I know this sounds weird, how would you still have the reference to the dynamically created control? I've gotten around this by keeping a reference to a List<Action> reference which I add things to during ItemCreated to be executed later.
In your control class you'll declare your List<Action> object:
List<Action> deferringControlToValidateUntilPreRender = new List<Action>();
Inside the ItemCreated event you'll have a line that looks like:
deferringControlToValidateUntilPreRender.Add(() => rfv.ControlToValidate = rblCondition.UniqueID);
And then, later, perhaps in PreRender:
foreach(var deferredAction in deferringControlToValidateUntilPreRender) action();
Since the RequiredFieldValidator is client-side code, you need to use the client id of the control. Like this:
rfv.ControlToValidate = rblCondition.ClientID;
Some more information from MSDN if you are interested:
Control.ClientIDMode Property
Also, an SO discussion on the differences between ClientID and UniqueID (as referenced in #MushinNoShin's answer, which, IMHO, is incorrect):
Why is there a difference between ClientID and UniqueID?

How to find the Controls in panel (which is added through literal)

Textbox1.text is user can enter html page name, so that its is appending to panel through literal.(loading html page to pannel).
string val = TextBox1.Text;
string location = Server.MapPath(".");
string path = location + "\\HTML\\" + val + ".html"; // HTML IS FOLDER NAME IN MY PROJECT
string readText = System.IO.File.ReadAllText(path);
Panel1.Controls.Clear();
Literal lit = new Literal();
lit.Text = readText;
Panel1.Controls.Add(lit);
Actually in Html page few controls which are in format of input (<input style="position: relative;" id="T0" onmouseup="mUp(this.id)" class="ui-draggable" onmousedown="mDown(this.id)" value="" type="text">)
I have to find those id's and text to save in database.
how to find the controls in panel now?
Give an ID to the control when you add it.
Literal lit = new Literal();
lit.Text = readText;
lit.ID = "myLiteral";
Panel1.Controls.Add(lit);
Then you can get it back as follows:
Literal lit = (Literal)Panel1.FincControl("myLiteral");
Remember that dynamically added controls must be created added again on every PostBack that follows as long as you want to have access to them.
Give your Literal an ID and then you can access it via FindControl...
Literal myLiteral = Panel1.FindControl("litId") as Literal;
if (myLiteral != null)
{
// ... do something
}
EDIT: (Missed the last part of your question)
You need to use ParseControl([string value]) on the HTML content which returns a control and then add that control (containing all child controls) to the Panel. Then you can use FindControl to locate child controls. For this method, the controls must be .NET controls (ie.
Since you did not give id to the control, u can find them by Panel1.Controls[index], since it is the first control added u can access at Panel1.Controls[0]

How to get HiddenField control in Masterpage and set it's value?

I have a MasterPage that contains a hidden field control. I want to get the current value of the hidden field and set the value of it from pages that use the MasterPage.
I have the following code so far: (in one of the pages)
//Get the textbox and set it's value
TextBox txt1 = new TextBox();
txt1 = (TextBox)this.Master.FindControl("txtHiddenField");
txt1 .Text = "true";
The above code does not seem to work. What code would I need to get the hidden field control and set it's value? (and get it's value)
I would recommend to provide a public property/method in your MasterPage, that you can use to set/get the HiddenField's value.
in your Master(assuming it's type is called SiteMaster):
public String HiddenValue {
get{return txtHiddenField.Value;}
set{txtHiddenField.Value = value;}
}
In your page:
SiteMaster master = (SiteMaster)Page.Master;
master.HiddenValue = "true";
This approach is straight-forward, less prone to errors and easily readable. You could even change the control in your master without needing to change the pages(f.e. if you want to replace the hidden-field with a TextBox).
Assuming that your "true" value indicates that you actually want to store a boolean, i would recommend to use a bool as data-type for the property and a self-explanatory name. Then you can store it in the hiddenfield but the client(the page) does not need to know.
HiddenField sets its text as VALUE, while TextBox has a TEXT property. Of course casting one to the other and setting text property won't help.
Do this instead:
HiddenField hiddenField = (HiddenField)Master.FindControl("txtHiddenField");
hiddenField.Value = "true";
Assuming you have added hidden field control like this ->>
<input type="hidden" ID="hiddenFieldID" runat="server" />
you can access it like -->>
HtmlInputHidden hiddenfield = (HtmlInputHidden)this.Master.FindControl(
May be you are missing ContentPlaceHolder
Try something like this
ContentPlaceHolder mpContentPlaceHolder;
TextBox mpTextBox;
mpContentPlaceHolder =
(ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
if(mpContentPlaceHolder != null)
{
mpTextBox =
(TextBox) mpContentPlaceHolder.FindControl("TextBox1");
if(mpTextBox != null)
{
mpTextBox.Text = "TextBox found!";
}
}
Read more about Reference ASP.NET Master Page Content

How can i access a server side control from asp.net code behind file using reflection?

For example, if i have on the aspx page:
<asp:PlaceHolder ID="tab_0" runat="server" Visible="false"></asp:PlaceHolder>
<asp:PlaceHolder ID="tab_1" runat="server" Visible="false"></asp:PlaceHolder>
and i want to access these properties in the code behind page using values from a configuration file for example
string enabledTabs = "0,1,2,3";
if there a way i can use reflection to set them to enabled or disabled e.g.
foreach(var id in enabledTabs.Split(','))
{
// <use reflection to get the correct tab control>
// Set property of the tab
tab.Visible = true;
}
I could acheive the result i want by using a switch statement and setting the particular control property, but i'd like to use reflection to get the tab to make it cleaner.
Could anyone help?
Thanks!
You don't need reflection. Use Page.FindControl:
foreach(var id in enabledTabs.Split(','))
{
PlaceHolder control = (PlaceHolder)this.FindControl("tab_"+id));
control.Visible = true;
}
foreach(var id in enabledTabs.Split(','))
{
// Set property of the tab
Page.FindControl("tab_" + id.ToString()).Visible = true;
}
Try the following:
Control tab = Control.FindControl("tab_"+id);

Categories

Resources