I have a WebForms page that I would like to inject some additional controls into at runtime. Currently I am achieving this in the Page_Load event using a Literal control.
For example the page looks like this (note that the TextBox1 is not an asp control just to show that it works):
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<input id="TextBox1" type="text" runat="server"/>
<asp:Literal ID="Literal1" runat="server" Visible="false"></asp:Literal>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</asp:Content>
And the code behind:
protected void Page_Load(object sender, EventArgs e)
{
Literal1.Visible = true;
if (!IsPostBack) Literal1.Text = "<input id=\"TextBox2\" type=\"text\" runat=\"server\"/>";
}
This works fine and both textboxes appear on the screen but if I type a value in to both and trigger a postback only the value of TextBox1 is retained.
I have tried moving my code to OnPreRender and OnPreLoad but still have the same issue.
I have noticed that when I view the page source TextBox1 has a UniqueId (e.g. ctl00$MainContent$TextBox1) while Textbox2 still has runat="server" as an attribute.
You can't inject server controls like this. You would need to add them as suggested in #Arvin's answer.
However, you use inject non-ASP.NET HTML controls similar to what you are doing and get their values.
From your code change the input's id to a name and drop the runat="server":
protected void Page_Load(object sender, EventArgs e)
{
Literal1.Visible = true;
if (!IsPostBack) Literal1.Text = "<input name=\"TextBox2\" type=\"text\" />";
}
Then you can get it's value on postback:
string textbox2value = Request.Form["TextBox2"];
Then, if you want to add the control on postback with it's value:
Literal1.Text = "<input name=\"TextBox2\" type=\"text\" value=\"" +
Server.HTMLEncode(textbox2value) + "\" />";
if you want to inject a textbox you should use placeholder like this :
<input id="TextBox1" type="text" runat="server"/>
<asp:PlaceHolder ID="plh" runat="server"></asp:PlaceHolder>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
protected void Page_Load(object sender, EventArgs e)
{
TextBox TextBox = new TextBox();
TextBox.ID = "TextBox2";
plh.Controls.Add(TextBox);
}
protected void Button1_Click(object sender, EventArgs e)
{
var Text1 = TextBox1.Value;
var Text2 = Request.Form["TextBox2"];
}
Related
Hi i am busy creating a asp.net project that needs to get three values from the user. I am using a textbox with a range textmode to get these values and the first time the user moves the slider it works perfectly but after that the user can.t adjust any of the textboxes anymore.
I tried using a slider extender but this does not seem to work and only a textbox shows.
my html code to create the textboxes and labels showing the value
body>
<form id="form1" runat="server">
<p>
Quantum 1 Length:
<asp:TextBox ID="txtVal1" runat="server" TextMode="Range" min="1" Max="8" OnTextChanged="txtVal1_TextChanged1" AutoPostBack="True"></asp:TextBox>
<asp:Label ID="lblVal1" runat="server" Text="/////"></asp:Label>
</p>
<p>
Quantum 2 Length:
<asp:TextBox ID="txtVal2" runat="server" TextMode="Range" min="1" Max="8" OnTextChanged="txtVal2_TextChanged1" AutoPostBack="True"></asp:TextBox>
<asp:Label ID="lblVal2" runat="server" Text="/////"></asp:Label>
</p>
<p>
Quantum 3 Length:
<asp:TextBox ID="txtVal3" runat="server" TextMode="Range" min="1" Max="8" AutoPostBack="True" OnTextChanged="txtVal3_TextChanged1"></asp:TextBox>
<asp:Label ID="lblVal3" runat="server" Text="/////"></asp:Label>
</p>
<p>
<asp:Button ID="btnNext" runat="server" AutoPostBack="true" Height="24px" OnClick="btnNext_Click" style="margin-left: 0px" Text="Next" Width="150px" />
<script type="text/javascript" __designer:mapid="129">
function NextPage() {
window.open('Execution.aspx', 'Execution');
}
</script>
<asp:Label ID="lblError" runat="server" ForeColor="Red" Text="Invalid input; Please ensure that Quantum 1 <= Quantum 2 <= Quantum 3" Visible="False"></asp:Label>
</p>
</form>
</body>
My C# code used to control the boxes and change their values
public partial class Quantums : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
txtVal1.Text = HttpContext.Current.Session["Q1"].ToString();
}
catch { }
try
{
txtVal2.Text = HttpContext.Current.Session["Q2"].ToString();
}
catch { }
try
{
txtVal3.Text = HttpContext.Current.Session["Q3"].ToString();
}
catch { }
lblVal1.Text = txtVal1.Text;
lblVal2.Text = txtVal2.Text;
lblVal3.Text = txtVal3.Text;
//UpdatePanel1.Triggers.Add(new AsyncPostBackTrigger() { ControlID = "btnNext" });
}
protected void txtVal1_TextChanged1(object sender, EventArgs e)
{
HttpContext.Current.Session["Q1"] = txtVal1.Text;
}
And then the same code for textbox 2 and 3. Any suggestions on why the textboxes vaklue keeps resetting and autopostback is enabled on all three buttons.
I just noticed you were missing if(Page.IsPostBack()) return;. Your problem is that every time you change your textbox, the 'Page_Load' event is enacted, then the respective event handler (see page life cycle). So you were setting the text to the sessions, then setting the sessions to the text, effectively doing nothing.
You actually don't need anything for this page in the Page_load method, at least for now. Try the following:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void txtVal1_TextChanged(object sender, EventArgs e)
{
Session["Q1"] = txtVal1.Text;
lblVal1.Text = txtVal1.Text;
}
protected void txtVal2_TextChanged(object sender, EventArgs e)
{
Session["Q2"] = txtVal2.Text;
lblVal2.Text = txtVal2.Text;
}
protected void txtVal3_TextChanged(object sender, EventArgs e)
{
Session["Q3"] = txtVal3.Text;
lblVal3.Text = txtVal2.Text;
}
You can then access the user input values using the respective session values. For example:
protected void Submit(object sender, EventArgs e)
{
List<string> answers = new List<string>();
answers.Add(Session["Q1"].ToString());
answers.Add(Session["Q2"].ToString());
answers.Add(Session["Q3"].ToString());
// Do stuff with answers
}
I am trying to generate textboxes when the I press button add more so this is the code for onclick
protected void Add_TextBoxes(object sender, EventArgs e)
{
int index = int.Parse(ViewState["pickindex"].ToString());
TextBox MyTextBox = new TextBox();
MyTextBox.ID = "tbautogenerated"+index.ToString();
MyTextBox.Text = "tbautogenerated" + index.ToString();
MyTextBox.Width= 250;
MyTextBox.MaxLength = 128;
MyTextBox.Attributes.Add("runat", "server");
MyTextBox.CausesValidation = false;
MyTextBox.AutoPostBack = true;
MyTextBox.TextChanged += new EventHandler(MyTextBox_TextChanged);
picktexts.Controls.Add(MyTextBox);
}
void MyTextBox_TextChanged(object sender, EventArgs e)
{
TextBox MyTextBox = sender as TextBox;
}
but when I change in the textbox the textChanged doesn't work !!! what's wrong ?
HTML Code
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div id="picktexts" runat="server">
<asp:TextBox ID="txtAdress" runat="server" MaxLength="128" Width="250" />
<asp:RequiredFieldValidator ControlToValidate="txtAdress" Display="Dynamic" ID="rfvAddress" Text="* Required" runat="server" />
<asp:Button ID="bt_addtxtbox" runat="server" Text="Add more" OnClick="Add_TextBoxes" CausesValidation="false" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
I think the event handlers are getting lost between posts. the way ASP.NET works, every time you post a page back to itself, all objects are instantiated again, and their state is recovered from the ViewState. Normally a control that's declared in the aspx would reassociate itself with events by the declaration in its tag, which is not the case here.
So try associating the event handlers again during the page load. Like this:
void Page_Load (object sender, EventArgs e)
{
foreach (Control c in picktexts.Controls)
{
((TextBox)c).TextChanged += new EventHandler(MyTextBox_TextChanged);
}
}
And see if it works.
I want to know that how can I trace out the value of Textbox from ViewState.
As user enters any value into Textbox and click submit button because of postback Textbox value disappears ,
But if I used ViewState in this case , then is there any way to see or display that value from Viewstate?
<html>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /
</form>
</body>
</html>
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text += "X";
}
In your page load use this.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (ViewState["Values"] == null)
{
ViewState["Values"] = new string();
}
}
TextBox1.Text = ViewState["Values"].ToString();
}
After that use this.
protected void Button1_Click(object sender, EventArgs e)
{
ViewState["Values"] += TextBox1.Text;
}
In the first Page_Load method, You will create a ViewState if its not a postback and its null. After that write the textbox your viewstate, in Button1_Click you will add your new textbox1 to your viewstate.
I want to find "Label" control with ID = "Label" inside the "ListView" control. I was trying to do this with the following code:
((Label)this.ChatListView.FindControl("Label")).Text = "active";
But I am getting this exception: Object reference not set to an instance of an object .
What is wrong here ?
This is aspx code:
<asp:ListView ID="ChatListView" runat="server" DataSourceID="EntityDataSourceUserPosts">
<ItemTemplate>
<div class="post">
<div class="postHeader">
<h2><asp:Label ID="Label1" runat="server"
Text= '<%# Eval("Title") + " by " + this.GetUserFromPost((Guid?)Eval("AuthorUserID")) %>' ></asp:Label></h2>
<asp:Label ID="Label" runat="server" Text="" Visible="True"></asp:Label>
<div class="dateTimePost">
<%# Eval("PostDate")%>
</div>
</div>
<div class="postContent">
<%# Eval("PostComment") %>
</div>
</div>
</ItemTemplate>
</asp:ListView>
Listview is a databound control; so controls inside it will have different ids for different rows. You have to first detect the row, then grab the control. Best to grab such controls is inside an event like OnItemDataBound. There, you can do this to grab your control:
protected void myListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var yourLabel = e.Item.FindControl("Label1") as Label;
// ...
}
}
If you want to grab it in Page_Load, you will have to know specific row and retrieve the control as:
var theLabel = this.ChatListView.Items[<row_index>].FindControl("Label1") as Label;
This function will get Author Name from a database, you just need to call your method to get Author Name and then return it
protected string GetUserFromPost(Guid? x)
{
// call your function to get Author Name
return "User Name";
}
And to bind label in the list view you have to do it in list view ItemDataBound Event
protected void ChatListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Label lbl = e.Item.FindControl("Label") as Label;
lbl.Text = "Active";
}
}
Here are the list view aspx code changes (just add onitemdatabound="ChatListView_ItemDataBound"):
asp:ListView
ID="ChatListView"
runat="server"
DataSourceID="EntityDataSourceUserPosts"
onitemdatabound="ChatListView_ItemDataBound"
It should be Label1 in the arguement:
((Label)this.ChatListView.FindControl("Label1")).Text = "active";
This should be in a databound event.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemdatabound.aspx
Try it:
protected void ChatListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item is ListViewDataItem)
{
var yourLabel = e.Item.FindControl("Label1") as Label;
// ...
}
}
One simple solution to this problem, which avoids the FindControl code is to place OnInit on your label.
This would change your page code to this: <asp:Label ID="Label" runat="server" Text="" Visible="True" OnInit="Label_Init"></asp:Label>
And in your code behind you will now have a function like this:
protected void Label_Init(object sender, EventArgs e)
{
Label lblMyLabel = (Label)sender;
lblMyLabel.Text = "My Text";
}
I added a checkbox to my form.
When the checkbox is checked, some information (TextBox, Label etc.) should appear right under the checkbox.
How can I do this?
Code:
<asp:CheckBox ID="CheckBox1" runat="server"
oncheckedchanged="CheckBox1_CheckedChanged" />
C#:
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
}
Don't forget autopostback = true
<asp:CheckBox ID="CheckBox1" runat="server" oncheckedchanged="CheckBox1_CheckedChanged" AutoPostBack="true" />
<asp:Panel runat="server" ID="panel1"></asp:Panel>
-
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
panel1.Controls.Add(new Label { Text = "Text goes here" });
}
This allows you to add any control you want.
Just add TextBox, Label etc. controls and make them invisible.
Then in the CheckBox1_CheckedChanged function make them visible.
This is done by setting the bool Visible property
<asp:CheckBox ID="CheckBox1" runat="server" oncheckedchanged="CheckBox1_CheckedChanged" />
<asp:TextBox ID="textBox" runat="server" Visible=false />
and
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
textBox.Visible = true;
}
Add a new literal control under your checkbox tags,
<asp:Literal id="lblMsg" runat="server"/>
then in your CheckBox1_CheckedChanged event to this:
lblMsg.Text = "Checked";
and yes set the AutoPostBack property of your checkbox to true
I would suggest doing this using javascript. Your users won't have to "postback" and the feeling on the application will be better, and you will reduce the server charge.
Using jQuery, you can use something like this:
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$("#chk").onclick(function() {
$("#content").toggle();
});
});
</script>
<input type="Checkbox" id="chk"/>
<div id="content" style="display:none">
<asp:TextBox runat="Server" id="oneOfYourControls" />
</div>
jQuery is not mandatory... you can use standard simple getElementById().
The only drawback, is that you cannot dynamically build the content, but in most case it's a not actually a matter
In Checked Changed Event write your code like this:
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
Label1.Text = "Text";
}