asp.net textbox dynamic creation with .CssClass attribute - c#

I am having a scenario by which I have to dynamically create the form based on the user selection. In the form, there are few textboxes which should be added at the end to the Total Textbox.
The way I am distinguishing the textboxes to be added at the end is by specifying as below..
TextBox txt1 = new TextBox();
txt1.ID = "txt1";
txt1.CssClass = "addToTotal";
TextBox txt2 = new TextBox();
txt2.ID = "txt2";
txt2.CssClass = "addToTotal";
TextBox txt3 = new TextBox();
txt3.ID = "txt3";
txt3.CssClass = "txtTotalPoints";
PlaceHolder1.Controls.Add(txt1);
PlaceHolder1.Controls.Add(txt2);
PlaceHolder1.Controls.Add(txt3);
In reality, there is no css class named 'addToTotal' in the site css file. It's just used as a flag to notify me for adding at the end.
Is it a good practice to add a .CssClass even though the actual class does not exist. Are there any pitfalls in using this methodology?

I would assume that the overhead of using a CSS class which does not exist as a marker is minimal, so I wouldn't change your implementation based on that. If you're concerned about best practices - which you could rightly be, CSS classes were never intended to be used like this - you could add a data-* attribute to the input and use that instead:
txt2.Attributes["data-addToTotal"] = "true";
...then finding those elements with JQuery:
$("input[data-addToTotal='true']")
data-* attributes are part of HTML5, but are fully backwards compatible.

Related

Alternative Text in treeview control in asp.net

I am looking for a solution. My treeview control contains the menuitems for my web application and its populated from a sitemap and it's working fine. Now I need to add alternative text to that menu items created. How can I add alternative text to these treeview items.
My treeview code is like below
protected void MainMenu_NodeDataBound(object sender, TreeNodeEventArgs e)
{
var siteMapnode = e.Node.DataItem as SiteMapNode;
e.Node.Value = siteMapnode.Url;
e.Node.NavigateUrl = string.Empty;
e.Node.SelectAction = (siteMapnode.Url != String.Empty) ? TreeNodeSelectAction.Select : TreeNodeSelectAction.None;
e.Node.PopulateOnDemand = false;
}
Not really sure what you mean by 'alternative text' but you may be looking for the Tag property.
Example:
...
e.Node.Tag = "Alternative Text, whatever that means.";
...
You can set a Node's Tag property to whatever you want since it's type object, which I find pretty handy. Reference here.
There is no alt. I believe what you want is title, which is set using the ToolTip attribute:
e.Node.ToolTip = "I provide useful info about the link."
Which will get rendered as:
Some Text
alt is used to specify alternate text for elements when they can't be rendered (i.e. NOT anchor tags). Outside of IE, browsers will not use this to provide text that displays when the element is hovered.
From HTML Techniques for Web Content Accessibility Guidelines 1.0:
In addition to clear link text, content developers may specify a value
of the "title" attribute that clearly and accurately describes the
target of the link.
If more than one link on a page shares the same link text, all those
links should point to the same resource. Such consistency will help
page design as well as accessibility.
If two or more links refer to different targets but share the same
link text, distinguish the links by specifying a different value for
the "title" attribute of each A element.
Alternate text in ASP.Net :
AlternateText="Your Text"

add DIV around every asp:DropDownList control code behind

I try to simply add a div wrapper around every control of type <asp:DropDownList> at a global level (if possible). At this point I have solved it with a asp skin adding "default-select" class to all <asp:DropDownList> and then jquery just adding a div for each of them.
$j(".default-select").wrap("<div class='myClass'></div>");
Now, my question. Is it possible to add this div wrapper from the code-behind instead of relying on a javascript.
Control Adapter:
I know this should be possible by writing a control adapter that override <asp:DropDownList> render method (as described here: Dropdownlist control with <optgroup>s for asp.net (webforms)?). However, I just want to add a wrapping div, not rewrite the entire rendering of the <asp:DropDownList> control (which I have to do if i override the method?). Any suggestions? Maybe there is a way to just add something to the existing adapter??
Custom User Control: Another solution would be to build a custom <mycustom:DropDownList> with the wrapping, but, this would force me to replace every instance of <asp:DropDownList> trough the whole project (large project). I rather just change the original control some how so that my styling applies everywhere.
So summary: Is there an easy way to just make all <asp:DropDownList> render as:
<div class="myClass">
<select><option...></select>
</div>
instead of just:
<select><option...></select>
My first attempt (on Page load): I tried to add this code in the Page_load method but I don't find any way to render that div out?
var j = 0;
foreach (DropDownList control in Page.Controls.OfType<DropDownList>())
{
HtmlGenericControl div = new HtmlGenericControl();
div.ID = "div" +j;
div.TagName = "div";
div.Attributes["class"] = "myClass";
div.Controls.Add(control); // or control.Controls.Add(div); but this wouldn't wrap it.
j++;
}
Your solution just about works. Server control can only exist within the scope of a server form, you will need to perform a recursive search on the page or look directly in the form controls collection. Once you have the DropDownList and wrapped it around a div container it will need to be added to the controls collection.
Also, I think it better to perform this in OnPreInit.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
var j = 0;
foreach (DropDownList control in form1.Controls.OfType<DropDownList>().ToList())
{
var div = new HtmlGenericControl();
div.ID = "div" + j;
div.TagName = "div";
div.Attributes["class"] = "myClass";
div.Controls.Add(control); // or control.Controls.Add(div); but this wouldn't wrap it.
j++;
form1.Controls.Add(div);
}
}
I hope this is helpful. Let me know how you get on.
Either way what you're wanting is custom and you have to code for it. So IMO, the best and simplest option is the custom control. You may have to spend some time refactoring references to replace your <asp:DropDownList>, but in all the time you've spent trying another way, you could've been done by now. :)
I've learned the hard way that keeping it simple is usually the best way to go.

Is it possible to dynamically add embedded code blocks to asp.net page similar to how controls are added dynamically from code?

One can dynamically add controls to an asp.net page.
Label myLabel = new Label();
myLabel.Text = "Sample Label";
Panel1.Controls.Add(myLabel);
I want to know if it is possible to add embedded code blocks dynamically?
If I do something like the code below, the embedded code will be rendered literally.
// Use <%#Page.Title%> or <%=Page.Title%> for example
LiteralControl literal = new LiteralControl("<%=Page.Title%>");
Panel1.Controls.Add(literal);
The output of the above code will be
<%=Page.Title%>
Is there a way to make ASP.NET evaluate the embedded code blocks that are added dynamically?
LiteralControl literalContols = new LiteralControl();
literalContols.Text = Page.Title;
this.MasterForm.Controls.Add(literalContols);

Creating aspx textbox from codebehind

how can I create aspx textbox from code behind in C# and how to access its value in code behind ? I do as follows but on every post backs text box is getting cleared. I need to keep its values on post backs.
TextBox txt = new TextBox();
txt.ID = "strtxtbox";
txt.CssClass = "CSS1";
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
txt.RenderControl(htmlWriter);
//lbl is an aspx label
lbl.text += #"<td style='width: 5%;'>" + sb.ToString() + "</td>";
And I access text box value as follows
string tb = Request.Form["strtxtbox"].ToString();
You can start by creating the TextBox control. It must be done in the Init() (Page_Init()) or PreInit() (Page_PreInit()) method, and you have to do it regardless of Page.IsPostBack. This will put the element on the page before the ViewState is loaded, and will allow you to retrieve the value on postback.
var textBox = new TextBox();
Then you should set a few properties on it, including an ID so you can find it later:
textBox.ID = "uxTxtSomeName";
textBox.MaxLength = 10; // maximum input length
textBox.Columns = 20; // character width of the textbox
etc...
Then you need to add it to an appropriate container on the page (Page, or whichever control you want it to appear within):
parentControl.Controls.Add(textBox);
Then on post back, you can retrieve the value, probably in the Load() method (Page_Load()) using the parent's FindControl() function:
var input = (parentControl.FindControl("uxTxtSomeName") as TextBox).Text;
Note: The built-in FindControl() only iterates through immediate children. If you want to search through the entire tree of nested server controls, you may need to implement your own recursive FindControl() function. There are a million and one examples of recursive FindControl() functions on [so] though, so I'll leave that up to you.
The problem is that the control won't be available on postback unless you recreate it every time, which is problematic.
One solution I've used in the past is the DynamicControlsPlaceholder, you can check it out here.
Check this out, it gives you complete example for adding controls at runtime
http://www.codeproject.com/Articles/8114/Dynamically-Created-Controls-in-ASP-NET
http://geekswithblogs.net/dotNETvinz/archive/2009/03/17/dynamically-adding-textbox-control-to-aspnet-table.aspx
Create the textbox as per the code in the comment
TextBox myTextBox=new TextBox();
however, you must set an ID/Name. Additionally, you must create the text box on every postback, in the pre-render or before, so that the value will be populated. If you delay creation of the textbox to later in the page lifecycle, the value will not be populated from the postback, and then you would have to retrieve it from the Request.Response[] collection manually.

Persisting a control's properties

OK Time for another dumb Q from yours truly.
I have a control that has some properties that need to be persisted in the ViewState. I also need to make sure that the properties aren't overwritten if the control appears more than once on the page.
I thought to write something like...
ViewState[String.Format("{0}_{1}", "BaseKey", this.ClientID)] = ...
But the value of ClientID changes partway through the page's lifecycle. It starts out as something like "MyControl1" and then becomes "ctl001_MyControl1". So any values applied before it changes are lost.
The same thing happens if I use UniqueID instead.
I know I'm missing something obvious, and I'm going to blame the pills I'm taking so I don't look too dumb.
--
Stuart
it looks like you are doing this inside the user control, if that is true you do not need to make a unique key for the viewstate, each instance of every control manages it's own viewstate so all you need is a key known to your control, something like that:
ViewState[#"somekey"] = ...
Try doing it on Page_PreRender rather than Page_Load?
Don't store the value named relative to the output name of the control itself. Provide it with a unique, unchanging name and then make sure all of your binding rules adjust to that name instead of the client name.
Edit:
As a small example of what I mean:
MyControl ctrl1 = new MyControl();
ctrl1.ID = "MyControlA";
ctrl1.Text = "Some text";
ViewState[ctrl1.ID] = ctrl1.Text;
MyControl ctrl2 = new MyControl();
ctrl2.ID = "MyControlB";
ctrl2.Text = "Some other text";
ViewState[ctrl2.ID] = ctrl2.Text;

Categories