Call a Function on Dynamically Generated ASP:Button in ASP.NET c# - 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);
}

Related

Dynamically created button - onclick event not triggering

I have created a file upload control and a upload button in c# code as below: The controls are getting created and are shown in the UI- aspx
TableCell uploadCell = new TableCell();
uploadCell.ColumnSpan = 4;
tRow.Cells.Add(uploadCell);
FileUpload fu = new FileUpload();
fu.ID = "fu_" + BU + "_" + artifact.LookupValue + artifact.LookupId;
fu.AllowMultiple = false;
Button btnUpload = new Button();
btnUpload.ID = "btnUpload_" + BU + "_" + artifact.LookupValue + artifact.LookupId;
btnUpload.Text = "Upload";
btnUpload.Click += new EventHandler(this.btnUpload_Click);
PostBackTrigger trigger = new PostBackTrigger();
trigger.ControlID = btnUpload.ID;
uploadCell.Controls.Add(fu);
uploadCell.Controls.Add(btnUpload);
Up1.Triggers.Add(trigger);
private void btnUpload_Click(object sender, EventArgs e)
{
}
when I click on the upload button, the click event is not getting fired. I have attached a debug on the btnUpload_Click, but that is not hit.
How to trigger the click event for dynamically added control?

Dynamically Created Button refuses to call it's onClick

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.

Link button to display grid view asp.net dynamically

I have to display n grids, n is variable, then I dont know how many grids I'll have.
My problem is, I have to init this grids with Visible false and when click in a button show the grid specific for that button, then how can I link a button to a gridview?
My code that generate the grids:
foreach (List<DataRow> lst in grids)
{
dt = lst.CopyToDataTable();
GridView grv = new GridView();
grv.AlternatingRowStyle.BackColor = System.Drawing.Color.FromName("#cccccc");
grv.HeaderStyle.BackColor = System.Drawing.Color.Gray;
grv.ID = "grid_view"+i;
grv.Visible = false;
grv.DataSource = dt;
grv.DataBind();
Label lblBlankLines = new Label();
lblBlankLines.Text = "<br /><br />";
Label lblTipo = new Label();
string tipoOcorrencia = lst[0]["DESC_OCORRENCIA"].ToString();
tipoOcorrencia = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(tipoOcorrencia);
int quantidade = lst.Count;
lblTipo.Text = tipoOcorrencia + ": " + quantidade;
LinkButton lkBtn = new LinkButton();
lkBtn.ID = "link_button"+i;
lkBtn.Text = "+";
place_grids.Controls.Add(lblBlankLines);
place_grids.Controls.Add(lkBtn);
place_grids.Controls.Add(lblTipo);
place_grids.Controls.Add(grv);
place_grids.DataBind();
i++;
}
Thanks in advance.
Modify your foreach loop as below.
private void GenerateControls()
{
int i = 0;
foreach (List<DataRow> lst in grids)
{
dt = lst.CopyToDataTable();
GridView grv = new GridView();
grv.AlternatingRowStyle.BackColor = System.Drawing.Color.FromName("#cccccc");
grv.HeaderStyle.BackColor = System.Drawing.Color.Gray;
grv.ID = "grid_view" + i;
//grv.Visible = false;//Commented as the grid needs be generated on client side, in order to make it visible from JavaScript/jQuery
grv.Attributes.Add("style", "display:none;");
grv.DataSource = dt;
grv.DataBind();
//Adding dynamic link button
LinkButton lnkButton = new LinkButton();
lnkButton.Text = "button " + i;
//lnkButton.Click += new EventHandler(lnkButton_Click);
lnkButton.ID = "lnkButton" + i;
lnkButton.OnClientClick = "ShowGrid('" + grv.ClientID + "');";
Label lblTipo = new Label();
lblTipo.Text = "text " + i;
lblTipo.ID = "lbl" + i;
tempPanel.Controls.Add(lblTipo);
tempPanel.Controls.Add(grv);
tempPanel.Controls.Add(lnkButton);
tempPanel.DataBind();
i++;
}
}
Then you will have to add a link button click event as below, if you want server side event to fire. (Un-comment the line where event handler is assigned to link button.)
protected void lnkButton_Click(Object sender, EventArgs e)
{
LinkButton lnkButton = (LinkButton)sender;
String index = lnkButton.ID.Substring(lnkButton.ID.Length - 1);
GridView grv = (GridView)tempPanel.FindControl("grid_view" + index);
grv.Visible = true;
}
You will need to add all dynamically added controls in the Page_Init event for maintaining their state. Refer below links can be useful.
Dynamically Created Controls losing data after postback
ViewState in Dynamic Control
Call method GenerateControls from Page_Init event as below.
protected void Page_Init(object sender, EventArgs e)
{
GenerateControls();
}
EDIT :
JavaScript function...
function ShowGrid(gridID) {
document.getElementById(gridID).style.display = ''
}
I have kept the server side click event as it is. But I have commented the line where the event handler is assigned to the link button.

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