Creation of TextBox dynamicly cause to lose the "name" attribute - c#

I have this code to add a new TextBox to my UserControl:
/// <summary>
/// Create a new TextBox
/// </summary>
/// <returns>a new TextBox with the right name attribute</returns>
private TextBox createTextBox()
{
TextBox textbox = new TextBox();
textbox.Attributes["name"] = name + "_" + (textBoxList.Count + 1);
textbox.ID = name + "_" + (textBoxList.Count + 1);
return textbox;
}
on the output HTML the "name" attribute of this TextBox is changed, and the UserControl name is added...
<input name="multipleTextBox$test_1" type="text" id="multipleTextBox_test_1">
how can i avoid the "multiplartTextBox$" part of the name to be added ? it's important since i need my unique name to be right...

Set the TextBox.ClientIDMode to Static.
TextBox textbox = new TextBox();
textbox.ClientIDMode = ClientIDMode.Static;
ClientIDMode in ASP.NET 4.0

by default you cant. this is how ASP.NET and control name generation works especially if you are adding it in a user control. this is how ASP.NET differentiates with controls and naming conflicts on the client side. This is quite normal. why would it matter to you though you? why do you need access to the element at runtime? if you need access to it, simply user document.getElementById('multipleTextBox$test_xxx') :)
you can set the ClientIDMode to static though however I would advise against this unless you have good reason to do so - this would be the ID, and not the name

you can always access your control by ClientId property to get rendered Control ID and UniqueId to get rendered Control Name.

Related

Why aren't the ASP.NET User Control properties updated within the control?

Overview
I have a ASCX user control that I am trying to use for my web application.
The control has multiple properties that need to be set in order for the control to work properly.
The control is used in a GridView. Each instance of the control needs data from the row it is on.
What I Have Tried
I have tried setting the property values using the attributes and the Eval method to assign the values. For example:
Page Code:
<cm:TestManagerEditor runat="server" id="TestManagerEditor" FilePath='<%# System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Some\\Path\\In\\The\\WebApp\\" + AccountYearPeriodOptionsGroupRandomTestManager.SelectedAccountValue + "\\" %>' />
I have also tried setting the values on the RowDataBound event. For example:
Page Code:
private string PathToUserFiles = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Some\\Path\\In\\The\\WebApp\\";
protected void GridViewData_RowDataBound(object sender, GridViewRowEventArgs e)
{
// this is the customized path to files for the selected account.
string UserFilePath = PathToUserFiles + AccountYearPeriodOptionsGroupRandomTestManager.SelectedAccountValue + "\\";
// set modal dialog properties and add the scripting to open those dialogs.
if (e.Row.RowType == DataControlRowType.DataRow)
{
Controls_Modals_TestManagerEditor EditorModal = e.Row.FindControl("TestManagerEditor") as Controls_Modals_TestManagerEditor;
EditorModal.FilePath = UserFilePath;
}
}
The Problem
When I access the properties that I set using either of the methods above from the page the control is on, the values return correctly. However, if I am attempting to access the value of the property from within the codebehind of the control, it returns the default value of the property (usually NULL or string.Empty) and not the value that was set.
For example, the FilePath property used above is declared just like any other:
UserControl Code:
/// <summary>
/// The path to the location of the uploaded files.
/// </summary>
private string _FilePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Some\\Path\\In\\The\\WebApp\\";
/// <summary>
/// Gets or sets the path to the location of uploaded files.
/// </summary>
public string FilePath
{
get
{
return _FilePath;
}
set
{
_FilePath = value;
}
}
But when the user clicks a button on the control to perform some operation, the value of FilePath, when accessed in the UserControl's code is
System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Some\\Path\\In\\The\\WebApp\\"
and not the expected
System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Some\\Path\\In\\The\\WebApp\\" + AccountYearPeriodOptionsGroupRandomTestManager.SelectedAccountValue
(essentially missing the AccountYearPeriodOptionsGroupRandomTestManager.SelectedAccountValue from the string).
The odd thing is that the properties will actually perform the set operation. One of them for sure will perform the operation but then promptly loses it's value. The ModalTitle property will set the UX correctly, but accessing the value of the property afterwards fails to return what is displayed on the screen.
For example, the following set accessor will correctly set the TestManagerEditor_label values on the screen, but fails to set the value of _ModalTitle:
UserControl Code:
/// <summary>
/// The text to display in the title of the Modal Dialog Box.
/// </summary>
private string _ModalTitle = "Test Manager";
/// <summary>
/// Gets or sets the text to display in the title of the Modal Dialog Box.
/// </summary>
public string ModalTitle
{
get
{
return _ModalTitle;
}
set
{
_ModalTitle = value;
TestManagerEditor_label.InnerText = value + " ";
TestManagerEditor_label.InnerHtml = TestManagerEditor_label.InnerHtml + "<span class=\"fa fa-pencil\"></span>";
}
}
Does anyone know what's going on here and why my control isn't able to access or save the value of the properties that are set by its parent page?
The design of ASP.NET webforms is that the "state" or value of the controls is written to viewstate when the page is rendered. That way when you do a postback, the server code can read back what those values were and persist them between postbacks. But if you declare a string in your code, ASP.NET doesn't know that it needs to save and restore that string. So while the properties of your server controls get saved and restored, your value gets lost.
Just as ASP.NET does that for controls within a page, it also does that for server controls that are nested within your UserControl.
One real easy fix is to include a control like this as part of your UserControl:
<asp:hiddenfield id="filepath" runat="server">
Then use that to store your value instead of a string variable. Assuming that viewstate is enabled for your control, the value of that field will get written to viewstate when you do a postback. It won't get lost between postbacks.
Another thought - do you want a user to be able to see your server path (some\path\etc) by viewing the page source? Even in viewstate it's only encoded, not encrypted by default. It's probably better to only store in your control the part of that path that changes based on user input, not the whole path. You can retrieve the rest of the path - System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath - in your server code when you need it instead of saving it in viewstate.
If you don't want to store values in a hidden field - suppose there are multiple values or it's more complex - you can also do something like this:
You could just use a string, but I like to create a single class to store all of the state that I want to save between postbacks. That way if I need to persist another value I don't need to write the same code again to save and reload multiple values.
[Serializable]
public class ControlState
{
public string FilePath{get;set;}
}
And then do this in your control:
public partial class YourControl : System.Web.UI.UserControl
{
private ControlState _controlState;
public ControlState State { get { return _controlState; } }
protected void Page_Load(object source, EventArgs e)
{
_controlState= ViewState["controlState"] as ControlState ?? new ControlState();
}
protected void Page_PreRender(object sender, EventArgs e)
{
ViewState["controlState"] = _controlState;
}
Then you can read and set your values through the State property.
The PreRender part saves those values into viewstate when the page is rendered.
The Page_Load part reads those values back from viewstate so that they're accessible from your code.

Get clientID for multi userControl with same Server ID

I have ASP.Net application that have multiple User Controls in the same page every one have its hidden field that holds a value, and every one have button that calls pop-up and through this value from hidden field to it.
The problem that when i try to access the hidden field and get the value inside , the program always get the last one (which created last).
How can i get the value of the inner hidden field in the current UserControl (Which i'm clicking the button from)?
Attempts:
var hdnRegion = "<%=hdnRegionId.ClientID%>";
var regionIdVal = $("#" + hdnRegion).val();
methodName(regionIdVal);
another one:
var currentControl = "<%=this.ClientID%>";
var hdnRegion = currentControl + "_" + "hdnRegionId";
var regionIdVal = $("#" + hdnRegion).val();
methodName(regionIdVal);
I also tried to call a property from code behind that returns the value and one that returns the whole control with no correct result.
Any suggestions would be appreciated...
Accourding to your comment under the question, your btnUpdate and hdnRegionId controls are in the same container (for instance in the same div) so try this:
$('input[id*="btnUpdate"]').click(function(){
var regionIdVal = $(this).parent().children('input[id*="hdnRegionId"]').val();
methodName(regionIdVal);
});
This is a JSFiddle Demo that simulate your HTML code that is rendered by ASP.NET.

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

using findcontrol to find a control within a literalcontrol

i have a custom control that renders a number of literalcontrols in the createchildcontrols method. as below (there are other lines of literalcontrols being added that i have not uncluded here)
this.Controls.Add(new LiteralControl(string.Format("<input type=\"text\" style=\"display:none\" value=\"{0}\" id=\"{1}\" name=\"{1}\" />", MediaId.ToString(), this.UniqueID)));
i am then trying to validate this textbox via adding the [ValidationProperty("myprop")] at the top of the class.
basically i need to validate against the value entered into the textbox. the myprop property is as follows
public string myprop
{
get
{
Control ctrl = this.FindControl(this.UniqueID);
string txt = ((TextBox)ctrl).Text;
try
{
MediaId = Convert.ToInt32(txt);
}
catch { MediaId = 0; }
return txt;
}
}
unfortunately the findcontrol does not find the textbox at all, i presume because as far as .net is concerned its a literalcontrol, not a textbox at all
now for sure i could change the createchildcontrols to do this
TextBox tb = new TextBox();
tb.Text = this.MediaId.ToString();
tb.ID = this.UniqueID;
this.Controls.Add(tb);
but because of other limitations of what i am doing i would have to change a great deal more stuff in other places..
is there anyway of getting findcontrol to find the textbox rendered inside the literal, or another method?
thanks
nat
unfortunately the findcontrol does not
find the textbox at all, i presume
because as far as .net is concerned
its a literalcontrol, not a textbox at
all
That is correct. You have to use some other control like a textbox.

On which Page life cycle are the Client IDs generated?

i am programatically adding Webcontrols in to a User Control i am also adding a javascript event passing the controlID as a parameter but the clientID is the one i assigned a it does not contain the one that asp.net generates
var txt = new TextBox();
txt.ID = "MyID"+Number;
chkBox.Attributes.Add("onClick", "EnableTxtBox('" +txt.ClientID + "');");
i can workAround this by adding the parent control ID
chkBox.Attributes.Add("onClick", "EnableTxtBox('" + this.ClientID+"_"+txt.ClientID + "');");
On which Page life cycle are the Client IDs generated?
You need to add the control to the control hierarchy before you add the attribute.
var txt = new TextBox();
txt.ID = "MyID"+Number;
Controls.Add ( txt );
chkBox.Attributes.Add("onClick", "EnableTxtBox('" +txt.ClientID + "');");
ControlCollection is no ordinary collection; it notifies the owner control when controls are added, and the control can take appropriate actions.
You should be able to add the attribute during OnPreRender(). INamingContainer is so painful sometimes...

Categories

Resources