Dynamically Created Button refuses to call it's onClick - c#

So while fooling around with webforms, I tried to create a page that outputs a table from a sql server to a html table on Page_Load. I then tried to add a button to a column which would redirect to a page. The only problem is, when I press the button nothing happens at all... I've tried putting breakpoints at the onclick method but they are never reached.
num = ds.Tables[0].Rows.Count;
htmlTable.Append("<tr style='background-color:#bd0000; color: White;'><th>ID</th><th>Job #</th><th>Project</th><th>Completed By</th><th>Date Created</th><th></th></tr>");
if (!object.Equals(ds.Tables[0], null))
{
if (ds.Tables[0].Rows.Count > 0)
{
int MAX_VIEW = (ds.Tables[0].Rows.Count > 15) ? 15 : ds.Tables[0].Rows.Count;
for (int i = 0; i < MAX_VIEW; i++)
{
htmlTable.Append("<td>" + ds.Tables[0].Rows[i]["CCPOF_ID"] + "</td>");
htmlTable.Append("<td>" + ds.Tables[0].Rows[i]["Job_Number"] + "</td>");
htmlTable.Append("<td>" + ds.Tables[0].Rows[i]["Project_Name"] + "</td>");
htmlTable.Append("<td>" + ds.Tables[0].Rows[i]["CompletedBy"] + "</td>");
htmlTable.Append("<td>" + ds.Tables[0].Rows[i]["DateCreated"] + "</td>");
htmlTable.Append("<td width=\"10%\"><button class=\"astext\" name=\"Btn" + ds.Tables[0].Rows[i]["CCPOF_ID"] + "\" id =\"" + ds.Tables[0].Rows[i]["CCPOF_ID"] + "\" OnClick =\"btnEdit_Click\" runat=\"server\" >Edit</button> | Details</td>");
htmlTable.Append("</tr>");
}
htmlTable.Append("</table>");
DBDataPlaceHolder.Controls.Add(new System.Web.UI.WebControls.Literal { Text = htmlTable.ToString() });
}
else
{
htmlTable.Append("<tr>");
htmlTable.Append("<td align='center' colspan='4'>There is no Record.</td>");
htmlTable.Append("</tr>");
}
}
}
protected void btnEdit_Click(object sender, EventArgs e)
{
String id = ((System.Web.UI.WebControls.Button)sender).ID;
Server.Transfer("CcpofDetails.aspx?ID=" + id);
}
}
When I inspect the button in the live form this is what I see
<button class="astext" name="Btn10" id="10" onclick="btnEdit_Click" runat="server">Edit</button>

Your way of generating dynamic controls seems very strange to me. It is not the way web-forms work.
To run an event on a control, it has to be loaded into servers memory first. But you are just filling some html text that is understandable only for the browser, not for asp.net engine.
take a look at this sample
To give you a better idea, create your buttons like this
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
AddControls();
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (ViewState["controsladded"] == null)
AddControls();
}
private void AddControls()
{
TextBox dynamictextbox = new TextBox();
dynamictextbox.Text = "(Enter some text)";
dynamictextbox.ID = "dynamictextbox";
Button dynamicbutton = new Button();
dynamicbutton.Click += new System.EventHandler(dynamicbutton_Click);
dynamicbutton.Text = "Dynamic Button";
Panel1.Controls.Add(dynamictextbox);
Panel1.Controls.Add(new LiteralControl("<BR>"));
Panel1.Controls.Add(new LiteralControl("<BR>"));
Panel1.Controls.Add(dynamicbutton);
ViewState["controlsadded"] = true;
}
private void dynamicbutton_Click(Object sender, System.EventArgs e)
{
TextBox tb = new TextBox();
tb = (TextBox) (Panel1.FindControl("dynamictextbox"));
Label1.Text = tb.Text;
}

I believe your problem comes from the fact that ASP.NET doesn't know you created a button. As far as it's concerned, all you did was pump out some text to the page.
As a result, when you post back to the server, it doesn't know it needs to do anything on the server side when you click.
Try creating it as an object (a System.Web.UI.WebControls.Button) and adding that to your page's Controls collection. Be aware that you'll have to do this both on the initial page build and on postback: if the control doesn't exist after postback, events that were hooked up to it don't fire.
Getting it to appear in the middle of your table may require you to do your HTML table creation in some other way, such as building a WebControls Table object and adding that to your Controls collection.

You are not adding corectl the button to the web form. Try this way:
Button btnEdit = New Button();
btn.Edit.Click += btnEdit_Click;
frmMain.Controls.Add(btnSave)
As shown in this question too.

Related

Call a Function on Dynamically Generated ASP:Button in ASP.NET c#

I'm trying to call a function created in code through <asp:Button>'s on click event but its not working...
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["Con"].ToString());
ArrayList myArrayList = ConvertDataSetToArrayList();
Literal objliteral = new Literal();
StringBuilder objSBuilder = new StringBuilder();
// Display each item of ArrayList
foreach (Object row in myArrayList)
{
objSBuilder.Append("<div class='AppItem'>");
objSBuilder.Append("<label class='control-label span3'>" + ((DataRow)row)["PlanName"].ToString() + "</label>");
objSBuilder.Append("<label class='control-label span3'> Plan Description :" + ((DataRow)row)["PlanDesc"].ToString() + "</label>");
objSBuilder.Append("<label class='control-label span3'> Price :" + ((DataRow)row)["PlanCost"].ToString() + "</label>");
objSBuilder.Append("<label class='control-label span3'> Total Visitors :" + ((DataRow)row)["PlanVisitors"].ToString() + "</label>");
objSBuilder.Append("<div class='control-group'><asp:Button Text='AddtoCart' runat='server' id='" + ((DataRow)row)["PlanId"].ToString() + "' class='btn btn-small btn-success' onclick='AddPlanToCart();' /></div>");
//<asp:Button ID="ImageButton1" runat="server" Text="Upload" CssClass="btn btn-small btn-success" onclick="ImageButton1_Click" />
objSBuilder.Append("</div>");
}
objliteral.Text = objSBuilder.ToString();
PlanContent.Controls.Add(objliteral);
}
private void AddPlanToCart()
{
//This does not get called.
}
Click here to see code behind!
The problem here is that you're generating the code to run on the client-side, but including scripts and tags designed to be run through the asp.net processor:
objSBuilder.Append("<div class='control-group'><asp:Button Text='AddtoCart' runat='server' id='" + ((DataRow)row)["PlanId"].ToString() + "' class='btn btn-small btn-success' onclick='AddPlanToCart();' /></div>");
which produces HTML including [slightly reformatted]:
<div class='control-group'>
<asp:Button ... onclick='AddPlanToCart();' />
</div>
instead of the <button> control that you're obviously expecting.
Fixing this to work in the manner its written in would be a significant amount of work. Instead, I'd strongly recommend rewriting it to use an <asp:repeater> control instead.
Your onclick is attempting to call a javascript function AddPlanToCart(). You have a couple of options. Here's 2:
1) Create a javascript that does a postback with a specific query string. Check for the query string in page_load, if it exists then call the function.
2) Create an actual dynamic control. It should be created in Page_init if you want to track it's viewstate, not Page_load. Then Add an event handler for the button.
Button b2 = new Button();
b2.Text = "Add To Cart";
b2.Click += new EventHandler(AddPlanToCart);
When creating the button, you can also bind the click event, to a delegate like the following:
Button btn = new Button();
btn.Text = "Button text";
btn.AutoSize = true;
btn.Location = new Point(y, 0);
btn.Click += delegate(object sender, EventArgs e)
{
solution.Invoke();
};
In this case I am passing an Action<>, as a parameter within the method. When you click on the button, the delegate would be triggered. For instance, this button would be created, and when clicked, a messagebox would show:
Button btn = new Button();
btn.Text = "Button text";
btn.AutoSize = true;
btn.Location = new Point(y, 0);
btn.Click += delegate(object sender, EventArgs e)
{
MessageBox.Show("Clicked!");
};
For your scenario, try something within these lines:
int counter = 0;
// Display each item of ArrayList
foreach (Object row in myArrayList)
{
Control ctrl = new Control();
Label lbl = new Label();
lbl.Text = "Label " + counter.ToString();
Button btn = new Button();
btn.Text = "Button text " + counter.ToString();
btn.Click += delegate(object sender, EventArgs e)
{
Response.Write("<script>alert('Message for button " + counter.ToString() + "');</script>");
};
ctrl.Controls.Add(lbl);
ctrl.Controls.Add(btn);
counter++;
PlanContent.Controls.Add(ctrl);
}

Event handler not working perfectly with C#

I am dynamically creating buttons which each selection of a dropdownlist.
With the following code I am adding an event handler to each button.
button.Click += new System.EventHandler(button_Click);
PlaceHolder1.Controls.Add(button);
private void button_Click(object sender, EventArgs e)
{
//Do something...
Response.Write("hello");
}
But unfortunately it does not fire that event and gives me an error as following
button_Click 'Index.button_Click(object, System.EventArgs)' is a 'method', which is not valid in the given context
How do I handle this?
protected void DropDownList1_SelectedIndexChanged1(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, typeof(Page), "Close", "javascript:OpenPopUp1();", true);
if (Session["filter"] == DropDownList1.SelectedValue)
{
}
else
{
if (Session["filter"] == "")
{
Session["filter"] = DropDownList1.SelectedValue + ":";
}
else
{
Session["filter"] = DropDownList1.SelectedValue + ":" + Session["filter"];
}
}
string asd = Session["filter"].ToString();
string[] split = asd.Split(':');
DropDownList1.Items.RemoveAt(DropDownList1.SelectedIndex);
for (int i = 0; i < split.Count(); i++)
{
string filter = split[i].ToString();
Button button = new Button();
button.Text = split[i].ToString();
button.ID = split[i].ToString();
button.Attributes.Add("onclick", "remove(" + split[i].ToString() + ")");
button.Click += new System.EventHandler(button_Click);
PlaceHolder1.Controls.Add(button);
}
}
The above shows the whole code of dropdownselected index.
button.Click += new System.EventHandler(button_Click);
PlaceHolder1.Controls.Add(button);
} // <-- end your current method with a curly brace
// Now start a new method
private void button_Click(object sender, EventArgs e)
{
//do something...
Response.Write("hello");
}
It's hard to say what you're going after, as there are a number of issues going on here. Since your dynamically generated buttons are being created in the SelectedIndexChanged event handler of your dropdown, they are not going to exist, nor are their event bindings, on the next postback. This means they can show up on the page, but clicking them won't do anything.
Secondly, since you are storing the SelectedValue to Session, and then using that value to set the Button IDs, you are going to be creating buttons with duplicate IDs if the user ever comes back to the page. (I noticed you are removing the list item once selected, but it would come back if the user refreshed the page, while the session object would remain populated.)
Last oddity, I wasn't able to find where your particular exception is handling, nor able to reproduce it. Which version of .NET are you programming against? Are you invoking the button click event anywhere from code-behind?
Now, that all said, I'm providing the following fix (or at least improvement):
protected void Page_Init(object sender, EventArgs e)
{
CreateButtons();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, typeof(Page), "Close", "javascript:OpenPopUp1();", true);
if (Session["filter"] == DropDownList1.SelectedValue)
{
}
else
{
if (Session["filter"] == "")
{
Session["filter"] = DropDownList1.SelectedValue + ":";
}
else
{
Session["filter"] = DropDownList1.SelectedValue + ":" + Session["filter"];
}
}
DropDownList1.Items.RemoveAt(DropDownList1.SelectedIndex);
CreateButtons();
}
private void CreateButtons()
{
PlaceHolder1.Controls.Clear();
if (Session["filter"] != null)
{
string asd = Session["filter"].ToString();
string[] split = asd.Split(':');
for (int i = 0; i < split.Count(); i++)
{
string filter = split[i].ToString();
Button button = new Button();
button.Text = split[i].ToString();
button.ID = split[i].ToString();
button.Attributes.Add("onclick", "remove(" + split[i].ToString() + ")");
button.Click += new System.EventHandler(button_Click);
PlaceHolder1.Controls.Add(button);
}
}
}
private void button_Click(object sender, EventArgs e)
{
//do something...
Response.Write("hello");
}

button1.Attributes.Add("onclick", "javascript:window.open('page1.aspx?CheckedItem=" + checkedItem.ToString() + "'');"); is not working properly

my client side code button1.Attributes.Add("onclick", "javascript:window.open('page1.aspx?CheckedItem=" + checkedItem.ToString() + "','mywindow',');"); is not executing on the first click.But it is working fine from second click onwards.I wrote this code inside the button click event.
I had tried to put this inside the page_load ,but the problem is i need to return a value from this page.
here is the code
protected void btnPreview_Click(object sender, EventArgs e)
{
//StringBuilder checkedItem = new StringBuilder();
checkedItem.Length = 0;
foreach (ListItem i in chkValidation.Items)
{
if (i.Selected)
{
if (string.IsNullOrEmpty(Convert.ToString(checkedItem)))
{
checkedItem.AppendFormat(i.Text);
}
else
{
checkedItem.AppendFormat(",");
checkedItem.AppendFormat(i.Text);
}
}
btn_Preview.Attributes.Add("onclick",
"javascript:window.open('TimePhaseAttributePreview.aspx?CheckedItem=" +
checkedItem.ToString() + "','mywindow','menubar=0,resizable=0,width=350,height=250');");
}
Please help me
put the code in any page event. like page_load,init.. or use RegisterClientScriptBlock
You need to use OnClientClick, not OnCLick
Change your code to
button1.OnClientClick = "javascript:window.open('page1.aspx?CheckedItem=" + checkedItem.ToString() + "'
,'mywindow',')";

How to add button and associated on click in ASP.net

I am working on a ASP.NET site, in which i display results returned by internal search engine to the end user. I am parsing the result creating HTML string to display those results as following
foreach (XmlNode result in results)
{
srHtml = "<li class=\"\" style=\"\">";
srHtml += " <span class=\"title\">" + result.SelectSingleNode("./web:Title", nsmgr).InnerText + "</span> <button>Short This URL</button>\n";
if (result.SelectSingleNode("./web:Description", nsmgr) != null)
srHtml += "<br />" + result.SelectSingleNode("./web:Description", nsmgr).InnerText + "<br />";
srHtml += "<span class=\"url\">" + result.SelectSingleNode("./web:Url", nsmgr).InnerText + "</span></li>\n";
phResults.Controls.Add(new System.Web.UI.LiteralControl(srHtml));
}
I can see that button on result page. But I dont know where can I put the code that run when user clicks on this button. When User clicks on that button, I want to change that button textfield with shorten url.
Can anyone help me out here ?
Regards,
Sumit Lonkar
What about doing it this way?:
Button button = new Button();
button.ID = "Button1";
button.Click += new EvandHandler(Button1_Click);
phResults.Controls.Add(button);
And your event handdler:
protected void Button1_Click(object sender, EventArgs e)
{
//Event handler code here
}

Programmatically create asp:Button and attach event in SharePoint

I'm trying to create ASP.NET buttons programmatically inside an update panel in my SharePoint instance, but because of the page life cycle, I can not attach server side events on buttons.
Here is the code:
TableCell tcellbutton = new TableCell();
b.Click += new EventHandler(b_Click);
b.CausesValidation = true;
tcellbutton.Controls.Add(b);
tr.Cells.Add(tcellbutton);
table.Rows.Add(tr);
panel1.Controls.Add(table);
void b_Click(object sender, EventArgs e)
{
string studentnumber = (sender as Button).ID.ToString().Substring(3, (sender as Button).ID.ToString().Length - 3);
TextBox t = panel1.FindControl("txt" + studentNumber) as TextBox;
}
Is there another way to create and attach buttons in Sharepoint?
Ok here is how I solved it, Thanks for all replies, I was looking for a way to attach an event to a button that is created dynamically during runtime (after initialization). Hope It works for others as well.
<script type="text/javascript">
function ButtonClick(buttonId) {
alert("Button " + buttonId + " clicked from javascript");
}
</script>
protected void Button_Click(object sender, EventArgs e)
{
ClientScript.RegisterClientScriptBlock(this.GetType(), ((Button)sender).ID, "<script>alert('Button_Click');</script>");
Response.Write(DateTime.Now.ToString() + ": " + ((Button)sender).ID + " was clicked");
}
private Button GetButton(string id, string name)
{
Button b = new Button();
b.Text = name;
b.ID = id;
b.Click += new EventHandler(Button_Click);
b.OnClientClick = "ButtonClick('" + b.ClientID + "')";
return b;
}
You should add your code in PreInit event, code below work good:
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
Button bb = new Button();
bb.Click += new EventHandler(bb_Click);
bb.CausesValidation = true;
bb.ID = "button1";
Panel1.Controls.Add(bb);
}
private void bb_Click(object sender, EventArgs e)
{
Response.Write("any thing here");
}
You are creating dynamic controls. Your code should execute in each PageLoad event.
Remove IsPostBack for the part of code where you are creating the buttons is my advice.
If you don't do this, you will create the controls, but each time when PageLoad event occurs, your control will be deleted and the application will not follow your events. With other words you should always recreate the controls.

Categories