asp button add through span not firing Click event - c#

This is my front End Code in asp.net form
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<span id="Message" runat="server"></span>
<span id="myid" runat="server">
</span>
</asp:Content>
here is my code behind
protected void Page_Load(object sender, EventArgs e)
{
myid.InnerHtml = myid.InnerHtml + "<asp:Button ID=" + dbLayer.AddDoubleQuotes("Button_Update") + " name=" + dbLayer.AddDoubleQuotes("Button_Update") + " runat=" + dbLayer.AddDoubleQuotes("server") + " class=" + dbLayer.AddDoubleQuotes("btn btn-success") + " OnClick=" + dbLayer.AddDoubleQuotes("Button_Update_Click") + " Text=" + dbLayer.AddDoubleQuotes("UpdateButton") + " />";
}
protected void Button_Update_Click(Object sender, EventArgs e)
{
Message.InnerHtml = "This Event Fired Sucessfully ...";
}
i am using web Method for Double Quotes
[WebMethod]
public string AddDoubleQuotes(string value)
{
return "\"" + value + "\"";
}
Not Able to get button click event
your reply helps me lot, i am stuck due to this

First of all, you cannot just simply render Server Control as string literal in ASP.Net Web Form.
Dynamically added server controls are a little bit tricky since they are not in control tree. You need to reload them back with same ID inside either Page_Init or Page_Load event.
<asp:PlaceHolder ID="PlaceHolder1" runat="server" />
<asp:Label runat="server" ID="MessageLabel" />
protected void Page_Init(object sender, EventArgs e)
{
var button = new Button {ID = "Button1"};
button.Click += Button_Click;
PlaceHolder1.Controls.Add(button);
}
private void Button_Click(object sender, EventArgs e)
{
MessageLabel.Text = "Button is clicked!";
}
FYI: Use ASP.Net Server control as much as possible instead of regular html control with runat="server", unless you absolutely certain that you do not need ViewState and some extra features offered by those server controls.

If EnableViewState is false, you can repopulate placeholder controls with different controls dynamically on a postback. The ids do not matter then.

Related

Inject a textbox in WebForms and retain the value on postback

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"];
}

tooltip computed links for asp button after button is clicked

<ItemTemplate>
<tr>
<asp:LinkButton ID="btnID" runat="server"
ToolTip='The calculated IDs are: ' OnCommand="showIds"
CommandArgument='<%# Convert.ToInt32(Eval("Year")) + "," +
Convert.ToInt32(Eval("Month")) %>'>
<%# Convert.ToInt32(Eval("Count")) - Convert.ToInt32(Eval("LittleCount"))%>
</asp:LinkButton>
</tr>
</ItemTemplate>
As you can notice the tooltip text is static. In code behind, I do calculate and get some integers ( IDs ) every time the above button is clicked ( protected void showIds(object sender, CommandEventArgs e) { .... }) contained as a List<ExpressionListDictionary>. ( the asp:LinkButton is contained inside an asp:ListView )
What I want to do, is to change the tooltip into a dynamic one, containing all the already obtained IDs as links. ( Something like this: http://jsfiddle.net/IrvinDominin/jLkcs/5/ - but in my case I do need firstly to click the button for calculating the IDs, and after this I would need to change the tooltip text from code as it needs to show the respective IDs, as links if it is possible)
How can I achieve this?
If you have a class (or id or something) to identify the buttons you can make an jQuery document ready function to change the tooltip with ids to a link containing the ids.
I modifyed your fiddle: http://jsfiddle.net/jLkcs/545/
$(document).ready(function () {
$(".myLinkButton").each(function() {
createlink(this);
});
});
function createlink(obj){
var ids= $(obj).attr('title');
var linkHtml="<a href='javascript:alert(" + ids + ")'>link</a>"
$(obj).attr('title',linkHtml);
}
Why not simply adjust the ToolTip in the codebehind during postback?
protected void showIds(object sender, CommandEventArgs e)
{
((LinkButton)sender).ToolTip = "blahblah";
}
You can set your sender attributes if the CommandEventArgs CommandName is equal with your defined one
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
if (e.CommandName.Equals("showIds"))
{
//
}
}
Here is an working example, this will work, not counting in what user control LinkButton is used:
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : Page
{
public string btnNoTooltip = "No IDs are calculated";
public string btnTooltip = "The calculated IDs are:";
protected void Page_Load(object sender, EventArgs e)
{
}
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
if (e.CommandName.Equals("LinkButtonOrder"))
{
LinkButton lkTrigger = (LinkButton)sender;
if (lkTrigger.ToolTip.Equals(btnNoTooltip))
{
lkTrigger.ToolTip = btnTooltip + " " + e.CommandArgument;
}
else
{
lkTrigger.ToolTip += " " + e.CommandArgument;
}
Random random = new Random();
lkTrigger.CommandArgument = random.Next(0, 100).ToString();
Label1.Text = "Triggered: " + e.CommandName + " with Argument " + e.CommandArgument;
}
}
}
Markup:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<h3>LinkButton Command Event Example</h3>
<asp:LinkButton id="LinkButton1"
Text="Order Item Here"
CommandName="LinkButtonOrder"
ToolTip='No IDs are calculated'
CommandArgument="01"
OnCommand="LinkButton_Command"
runat="server"/>
<br />
<asp:LinkButton id="LinkButton2"
Text="Or Order Item Here"
CommandName="LinkButtonOrder"
CommandArgument="02"
ToolTip='No IDs are calculated'
OnCommand="LinkButton_Command"
Runat="server"/>
<br />
<br />
<asp:Label id="Label1" runat="server"/>
<asp:PlaceHolder id="plhInjectId" runat="server" Visible="false"></asp:PlaceHolder>
</asp:Content>
You can use jquery to generate Tool Tip on Page itself.
Add a hidden field for your all the already obtained IDs (comma sepearted) to asp:ListView
Populate this hidden in ItemCreated event on server
add a class to your link button, say 'ShowHyperlinkOnHover'
Bind mouseenter event to class ShowHyperlinkOnHover document.ready function of jquery, this will dynamically generate tool tip. and then on Mouse Over tool tip will be displayed.
$(document).ready(function () {
$(document).on("mouseenter", ".ShowHyperlinkOnHover", function(this){
// 2 is index of hidden field having comma seperated Ids
var dynaToolTip;
$(this).parent("td:nth-child(2)").split(',').each(
function(oneId) dynaToolTip=dynaToolTip+ anyFomationLogic(oneId);
);
$(this).attr('title',dynaToolTip);
});
});

Dynamically Created Controls losing data after postback

Actually, I am Creating 1 TextBox on Pageload and adding that TextBox to Panel.
Now, I have a LinkButton like Add Another.
I am entering Text in that TextBox and if needed I need to Create New TextBox,by clicking Add Another LinkButton.
Actually, I am able to get the count and recreate the TextBoxes.
But,the Problem is that, My Entered text in the Previously Generated Textboxes is Missing.
Can Anyone,Suggest me a solution for this?
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
for (int i = 0; i < 5; i++)
{
TableRow row = new TableRow();
for (int j = 0; j < 5; j++)
{
TableCell cell = new TableCell();
TextBox tb = new TextBox();
tb.ID = "TextBoxRow_" + i + "Col_" + j;
cell.Controls.Add(tb);
row.Cells.Add(cell);
}
Table1.Rows.Add(row);
}
}
}
catch (Exception ex)
{
throw;
}
}
This is a Sample Code, the same code is written in Button_Click Also
protected void ASPxButton1_Click(object sender, EventArgs e)
{
int k = Table1.Controls.Count;
}
I am getting a Count=0 on Button_Click.
All you need to do is to re-instantiate / reinitialize dynamic controls before or within page load event each and every time during postback and add this control to page / forms / placeholders. Then, the posted data will automatically be assigned to the control by calling the LoadPostData method by the parent control.
check the article and how to write code for dynamic control -
How to maintain dynamic control events, data during postback in asp.net
When using dynamic controls, you must remember that they will exist only until the next postback.ASP.NET will not re-create a dynamically added control. If you need to re-create a control multiple times, you should perform the control creation in the PageLoad event handler ( As currently you are just creating only for first time the TextBox using Condition: !IsPostabck ). This has the additional benefit of allowing you to use view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the PageLoad event, ASP.NET will apply any view state information that it has after the PageLoad event handler ends.
So, Remove the Condition: !IsPostback, So that each time the page Loads, The TextBox control is also created. You will also see the State of Text box saved after PageLoad handler completes. [ Obviously you have not disabled ViewState!!! ]
Example:
protected void Page_Load(object sender, EventArgs e)
{
TextBox txtBox = new TextBox();
// Assign some text and an ID so you can retrieve it later.
txtBox.ID = "newButton";
PlaceHolder1.Controls.Add(txtBox);
}
Now after running it, type anything in text box and see what happens when you click any button that causes postback. The Text Box still has maintained its State!!!
The dynamically generated control do not maintain state. You have to maintain it at your own. You can use some hidden field to keep the state of controls, which will be used on server side to extract the state. Asp.net uses hidden field to maintain the state between requests, you can see __VIEWSTATE in the source.
In ASP.NET pages, the view state represents the state of the page when
it was last processed on the server. It's used to build a call context
and retain values across two successive requests for the same page. By
default, the state is persisted on the client using a hidden field
added to the page and is restored on the server before the page
request is processed. The view state travels back and forth with the
page itself, but does not represent or contain any information that's
relevant to client-side page display, Reference.
Just remove this line
if (!IsPostBack)
This is My final answer after working a lot with Dynamic Controls
.aspx
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div style="text-align: center">
<div style="background-color: Aqua; width: 250px;">
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:PlaceHolder runat="server" ID="myPlaceHolder"></asp:PlaceHolder>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddTextBox" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<br />
</div>
<br />
<asp:Button ID="btnAddTextBox" runat="server" Text="Add TextBox" OnClick="btnAddTextBox_Click" />
<br /><br />
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button runat="server" ID="MyButton" Text="Get Values." OnClick="MyButton_Click" />
<br /><br />
<asp:Label runat="server" ID="MyLabel"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
.aspx.cs
static int myCount = 0;
private TextBox[] dynamicTextBoxes;
protected void Page_PreInit(object sender, EventArgs e)
{
Control myControl = GetPostBackControl(this.Page);
if ((myControl != null))
{
if ((myControl.ClientID.ToString() == "btnAddTextBox"))
{
myCount = myCount + 1;
}
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
dynamicTextBoxes = new TextBox[myCount];
int i;
for (i = 0; i < myCount; i += 1)
{
TextBox textBox = new TextBox();
textBox.ID = "myTextBox" + i.ToString();
myPlaceHolder.Controls.Add(textBox);
dynamicTextBoxes[i] = textBox;
LiteralControl literalBreak = new LiteralControl("<br />");
myPlaceHolder.Controls.Add(literalBreak);
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
// Handled in preInit due to event sequencing.
}
protected void MyButton_Click(object sender, EventArgs e)
{
MyLabel.Text = "";
foreach (TextBox tb in dynamicTextBoxes)
{
MyLabel.Text += tb.Text + " :: ";
}
}
public static Control GetPostBackControl(Page thePage)
{
Control myControl = null;
string ctrlName = thePage.Request.Params.Get("__EVENTTARGET");
if (((ctrlName != null) & (ctrlName != string.Empty)))
{
myControl = thePage.FindControl(ctrlName);
}
else
{
foreach (string Item in thePage.Request.Form)
{
Control c = thePage.FindControl(Item);
if (((c) is System.Web.UI.WebControls.Button))
{
myControl = c;
}
}
}
return myControl;
}
When you are working with dynamic controls they will not able to maintain its state during postback and their data lost Cause they dont have any viewstate to maintain their data.
You only need to maintain the created controls data into ViewState
dynamically and loads the data into page at the time of postback and you
done.
public Dictionary<Guid, string> UcList
{
get { return ViewState["MyUcIds"] != null ? (Dictionary<Guid, string>)ViewState["MyUcIds"] : new Dictionary<Guid, string>(); }
set { ViewState["MyUcIds"] = value; }
}
public void InitializeUC()
{
int index = 1;
foreach (var item in UcList)
{
var myUc = (UserControls_uc_MyUserControl)LoadControl("~/UserControls/uc_MyUserControl.ascx");
myUc.ID = item.Value;
pnlMyUC.Controls.AddAt(index, myUc);
index++;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadControl();
else
InitializeUC();
}
Actually, I have used Javascript for accomplishing my task.
and it goes like this :
<form id="form1" runat="server" enctype="multipart/form-data" method="post">
<span style="font-family: Arial">Click to add files</span>
<input id="Button1" type="button" value="add" onclick="AddFileUpload()" />
<br />
<br />
<div id="FileUploadContainer">
<!--FileUpload Controls will be added here -->
</div>
<asp:HiddenField ID="HdFirst1" runat="server" Value="" />
<br />
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" />
</form>
Script :
<script type="text/javascript">
var counter = 0;
function AddFileUpload() {
var div = document.createElement('DIV');
div.innerHTML = '<input id="file' + counter + '"name = "file' + counter + '"type="text"/><input id="file' + counter + '" name = "file' + counter + '" type="file" /><input id="Button' + counter + '" type="button" value="Remove" onclick = "RemoveFileUpload(this)" />';
document.getElementById("FileUploadContainer").appendChild(div);
counter++;
}
function RemoveFileUpload(div) {
document.getElementById("FileUploadContainer").removeChild(div.parentNode);
}
function mydetails(div) {
var info;
for (var i = 0; i < counter; i++) {
var dd = document.getElementById('file' + i).value;
info = info + "~" + dd;
}
document.getElementById('<%= HdFirst1.ClientID %>').value = info;
}
</script>
and In the Upload_Click Button :
for (int i = 0; i < Request.Files.Count; i++)
{
string strname = HdFirst1.Value;
string[] txtval = strname.Split('~');
HttpPostedFile PostedFile = Request.Files[i];
if (PostedFile.ContentLength > 0)
{
string FileName = System.IO.Path.GetFileName(PostedFile.FileName);
// string textname=
//PostedFile.SaveAs(Server.MapPath("Files\\") + FileName);
}
}

Adding controls to a Panel in an UpdatePanel

I have a Panel in an UpdatePanel, a Button and a TextBox.
<asp:UpdatePanel ID="updatepanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="commentBox" Rows="1" Columns="60" placeholder="Add a comment..." TextMode="MultiLine" ClientIDMode="Static" runat="server"></asp:TextBox>
<asp:LinkButton ID="commentButton" runat="server" OnClick="commentButton_Click"> CommentButton </asp:LinkButton>
<asp:Panel ID="commentPanel" runat="server"></asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
on Button Click I am trying add what's in the TextBox to the Panel like this
Literal myComment = new Literal();
myComment.Text = "<p>"+commentBox.Text+"</p><br />";
commentPanel.Controls.Add(myComment);
This adds whats currently in the TextBox, but what was there in the panel gets removed.
So every time it starts from 0 count for controls in the panel. what am I missing?
you can check this out:
List<Literal> persistControls = new List<Literal>();
protected void Page_Load(object sender, EventArgs e)
{
// if you already have some literal populated
if (Session["persistControls"] != null)
{
// pull them out of the session
persistControls = (List<Literal>)Session["persistControls"];
foreach (Literal ltrls in persistControls)
commentPanel.Controls.Add(ltrls); // and push them back into the page
}
}
protected void commentButton_Click(object sender, EventArgs e)
{
Literal myComment = new Literal();
myComment.Text = "<p>" + commentBox.Text + "</p><br />";
commentPanel.Controls.Add(myComment);
persistControls.Add(myComment);// add it to the list
Session["persistControls"] = persistControls; // put it in the session
}
Literal comment = new Literal();
comment.Text="";
Panel1.Controls.Add(comment);
if (Panel1.Controls.Contains(comment))
{
comment.Text = comment.Text + "<p>" + commentbox.Text + "</p>";
}

How I can fill the DropDownList in the page_load

I have a DropDownList and I want to check what language does the browser have and set the values in the dropdown accordingly.
protected void Page_Load(object sender, EventArgs e)
{
string language = Request.UserLanguages[0].ToString().Substring(0, 2);
drpAnrede.DataSource = Server.MapPath("~/App_Data/" + language + ".xml");
}
UPDATE:
I have the solution for this problem...
aspx:
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="drpAnrede" runat="server" DataTextField="display" DataValueField="id">
</asp:DropDownList>
<asp:XmlDataSource ID="xmldata" runat="server"></asp:XmlDataSource>
</div>
</form>
c#:
protected void Page_Load(object sender, EventArgs e)
{
string language = Request.UserLanguages[0].ToString().Substring(0, 2);
//drpAnrede.DataSource = Server.MapPath("~/App_Data/" + language + ".xml");
xmldata.DataFile = Server.MapPath("~/App_Data/" + language + ".xml");
drpAnrede.DataSourceID = xmldata.ID;
}
You have to call DataBind() on your dropdown list after you set the datasource, no?
As in:
Databinding DropDown Control in .Net
Assuming the XML is Ok, you need to call
drpAnrede.DataBind();
after applying the datasource.

Categories