I have a pretty straight forward dynamically generated asp page. This is my first time using dynamically generated asp controls. The table renders correctly, however when I click on the "Query" button I cannot get the event to connect to the "OnClick" method. I get a webpage error "'ButtonClick' is undefined". I have stripped and simplified the code down for brevity.
DeviceStatus.aspx
<%# Page Title="Device Status" Language="C#" MasterPageFile="Secure.master"
'AutoEventWireup="true" CodeFile="DeviceStatus.aspx.cs" Inherits="Devices" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"></asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<div id="selectDiv" runat="server"></div>
</asp:Content>
DeviceStatus.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Devices : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e) {
int i, NumberOfDevices = 3;
string Contents;
string[] number = new string[] { "1", "2", "3"};
string[] name = new string[] {"mike", "bob", "cindy"};
string[] location = new string[] { "Austin", "Miami", "Atlanta" };
// Create event binding
PlaceHolder Placeholder1 = new PlaceHolder();
Button button = new Button();
button.Text = "Click";
button.Click += new System.EventHandler(ButtonClick);
Placeholder1.Controls.Add(button);
//Create Form and table header
Contents = "<form runat=\"server\"><table border=\"1\" >";
Contents += "<tr><th>Select</th><th>Number</th><th>Name</th><th>Status</tr>";
// Repeat for each table row
for (i = 0; i < NumberOfDevices; i++) {
// Creat each row
Contents += "<tr><td><asp:Button ID=\"row" + i + "\""
+ "runat=\"server\"OnClick=\"ButtonClick\" >Query</asp:Button></td>"
+ "<td>" + number[i] + "</td><td>" + name[i] + "</td><td>"
+ location[i] + "</td></tr>";
}
// Cleanup
Contents += "</table>";
Contents += "<asp:PlaceHolder ID=\"Placeholder1\" runat=\"server\"></asp:PlaceHolder>";
Contents += "</form>";
Contents += "</asp:Content>";
//Place dynamic asp controls in webpage
selectDiv.InnerHtml = Contents;
}
protected void ButtonClick(object sender, EventArgs e)
{
Response.Redirect("DataRendering.aspx");
}
}
I went with Garrison's suggestion. It took some time to get through the code to figure it out but once completed was the most straight forward solution. Thanks everyone for contributing.
Related
I have an ASP button on my page that is supposed to trigger an event on post back. This used to work but has stopped working on every single page that the search form is on. This particular code has not been updated since I got it all set up and working. The button code looks like:
<asp:Button id="search_button" class="search_button" runat="server" OnClick="search_button_click" />
And the post back event code looks like:
protected void search_button_click(Object sender, EventArgs e)
{
SessionHandler.sqlSearchTerm = searchBox.Text;
if (Int32.Parse(searchCatDdl.SelectedValue.ToString()) > 0)
{
SessionHandler.search_mcat_id = searchCatDdl.SelectedValue.ToString();
}
else
{
SessionHandler.search_mcat_id = "0";
}
Response.Redirect("/search.aspx");
Response.End();
}
I tried replacing the code inside of the event with just Response.Write("Hit");, but it never triggered at all. The page does post back though. There are no extra </form> tags on the page (or any page), leaving just one open form tag and one closing form tag. And like I said, this used to work but now is not.
The only code in the Page_Load method is code that creates drop down options for the search form (which has always worked and still does). There's nothing that would end the output or functionality. I'm trying to get debugging ideas as to how to figure out why this would stop working. I've tried to get the ID of the object used to cause post back but it's coming up blank. Then again, maybe I'm doing it wrong. In the Page_Load method, I did something along the lines of `Request["__(something)"];'. I don't remember exactly what it was, but it was setting that to a string variable which was supposed to have the object ID in it. Anyway, any help would be greatly appreciated.
EDIT
I also want to point out that if I change the OnClick attribute of my button to something that does not exist, it does err out. So it seems as if things are set correctly as I have them (to me, anyway). Also, every other control on the site still works and fires it's post back event.
Here is the panel my control is in:
<asp:Panel cssClass="search_items" id="pnlSearchButton" runat="server" DefaultButton="search_button">
<div class="search_bar">
<table>
<tr>
<td width="200"><h3 class="title">auction items</h3></td>
<td width="230"><asp:TextBox ID="searchBox" runat="server" placeholder="Search" name="search" /></td>
<td width="220">
<div class="select_cont option-set" id="filters">
<asp:DropDownList runat="server" ID="searchCatDdl" cssClass="option-set clearfix" data-filter-group="selectset">
</asp:DropDownList>
</div>
</td>
<td width="70"><asp:Button id="search_button" cssClass="search_button" runat="server" OnClick="search_button_click" /></td>
<td>
<a class="search_icon icon_collapse" id="toggle4"></a>
<div class="search_icon divider"></div>
<div class="search_icon divider"></div>
</td>
</tr>
</table>
</div>
</asp:Panel>
At the top of my page:
<%# Master Language="C#" MasterPageFile="~/master-pages/Site.Master" AutoEventWireup="true" CodeFile="HeaderFooter.master.cs" Inherits="master_pages.HeaderFooter" %>
The entire code behind for this particular page:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CowansRedesign.master_pages
{
public partial class HeaderFooter : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (!String.IsNullOrEmpty(Request.QueryString["logout"]))
{
SessionHandler.mailId = "";
SessionHandler.mailName = "";
SessionHandler.mailFirstName = "";
}
if (!String.IsNullOrEmpty(SessionHandler.mailId) && !String.IsNullOrEmpty(SessionHandler.mailFirstName) && Request.ServerVariables["SCRIPT_NAME"].ToString() != "/default.aspx")
{
if (hiName != null) {
hiName.Text = "Hi " + SessionHandler.mailFirstName;
}
}
}
if (!IsPostBack && searchCatDdl != null)
{
Dictionary<string, string> mainCatList = new Dictionary<string, string>();
mainCatList.Add("0", "All Categories");
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["wesdb1SQL"].ToString()))
using (SqlCommand strSQL = conn.CreateCommand())
{
strSQL.CommandText = "Select mcat_id, mcat_name " +
"From tblMcat " +
"ORDER BY mcat_name ASC";
try
{
conn.Open();
using (SqlDataReader itemReader = strSQL.ExecuteReader())
{
while (itemReader.Read())
{
mainCatList.Add(itemReader["mcat_id"].ToString(), itemReader["mcat_name"].ToString());
}
itemReader.Close();
}
}
catch (Exception e1)
{
Console.WriteLine(e1.ToString());
//Response.Write(e.ToString());
}
finally
{
conn.Close();
}
}
searchCatDdl.DataSource = mainCatList;
searchCatDdl.DataTextField = "Value";
searchCatDdl.DataValueField = "Key";
searchCatDdl.DataBind();
}
}
protected void overlay_itemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
bool isSaleOnline = Public.isSaleOnline(DataBinder.Eval(e.Item.DataItem, "EventSaleId").ToString());
bool isSaleLotted = Public.isSaleLotted(DataBinder.Eval(e.Item.DataItem, "EventSaleId").ToString());
Image overlayImage = (Image)e.Item.FindControl("overlayImage");
HyperLink auctionLink = (HyperLink)e.Item.FindControl("viewAuction");
HyperLink regLink = (HyperLink)e.Item.FindControl("viewReg");
HyperLink catalogLink = (HyperLink)e.Item.FindControl("viewCatalog");
Label slide_date = (Label)e.Item.FindControl("slide_date");
Label EventName = (Label)e.Item.FindControl("EventName");
EventName.Text = DataBinder.Eval(e.Item.DataItem, "EventName").ToString();
overlayImage.ImageUrl = "http://cowansauctions.com/webimages/events/" + DataBinder.Eval(e.Item.DataItem, "EventMain");
string[] formats = { "MM/dd/yyyy", "MM-dd-yyyy", "yyyy-MM-dd HH:mm:ss", "yyyyMMdd HH:mm:ss" };
IFormatProvider culture = new CultureInfo("en-US", true);
DateTime formattedDate;
//Response.Write(DataBinder.Eval(e.Item.DataItem, "homeDate").ToString());
//Response.End();
DateTime.TryParseExact(DataBinder.Eval(e.Item.DataItem, "homeDate").ToString(), formats, culture, DateTimeStyles.None, out formattedDate);
slide_date.Text = String.Format("{0:MM.dd.yy}", formattedDate);
if (DataBinder.Eval(e.Item.DataItem, "EventSaleId").ToString().Length >= 1)
{
auctionLink.Text = "More about the auction >";
auctionLink.NavigateUrl = "/auctions/details.aspx?id=" + DataBinder.Eval(e.Item.DataItem, "EventId");
if (isSaleOnline)
{
catalogLink.Text = "View Catalog >";
catalogLink.NavigateUrl = "/auctions/catalog.aspx?id=" + DataBinder.Eval(e.Item.DataItem, "EventSaleId") + "" + (!String.IsNullOrEmpty(DataBinder.Eval(e.Item.DataItem, "EventStartPage").ToString()) ? "&page=" + DataBinder.Eval(e.Item.DataItem, "EventStartPage") : "");
regLink.Text = "Register to bid online >";
regLink.NavigateUrl = "/auctions/live-bid.aspx";
}
else
{
if (Convert.ToBoolean(DataBinder.Eval(e.Item.DataItem, "EventRegister")))
{
regLink.Text = "Register to bid online >";
regLink.NavigateUrl = "/auctions/live-bid.aspx";
}
if (isSaleLotted)
{
catalogLink.Text = "View Catalog >";
catalogLink.NavigateUrl = "/auctions/catalog.aspx?id=" + DataBinder.Eval(e.Item.DataItem, "EventSaleId") + "" + (!String.IsNullOrEmpty(DataBinder.Eval(e.Item.DataItem, "EventStartPage").ToString()) ? "&page=" + DataBinder.Eval(e.Item.DataItem, "EventStartPage") : "");
}
}
}
else
{
catalogLink.Text = "View Event Details >";
catalogLink.NavigateUrl = "/event.aspx?id=" + DataBinder.Eval(e.Item.DataItem, "EventId");
auctionLink.Visible = false;
regLink.Visible = false;
}
}
}
protected void search_button_click(Object sender, EventArgs e)
{
SessionHandler.sqlSearchTerm = searchBox.Text;
if (Int32.Parse(searchCatDdl.SelectedValue.ToString()) > 0)
{
SessionHandler.search_mcat_id = searchCatDdl.SelectedValue.ToString();
}
else
{
SessionHandler.search_mcat_id = "0";
}
Response.Redirect("/search.aspx");
Response.End();
}
public static string StripHTML(string htmlString)
{
string pattern = #"<(.|\n)*?>";
return Regex.Replace(htmlString, pattern, string.Empty);
}
}
}
Well, I finally found the issue. I was thinking back and realized the very last change I made was adding Google's Tag Manager code to the website for some SEO tracking. That code turned out to be what was causing this one thing to stop working. I have no clue why. I removed it and everything is working.
<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-5XQX2B"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-fdsafdsa');</script>
<!-- End Google Tag Manager -->
I have the following code for a tab container and i am able to create a tab dynamically but as soon as i try to click to add another tab the previous tab disappears, i can't figure out how to keep viewstate, can someone please help me with this.
test5.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test5.aspx.cs" Inherits="test5" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<cc1:tabcontainer id="TabContainer1" visible="true" runat="server" Height="150px">
<cc1:TabPanel ID="Tab0" runat="server" HeaderText="Step 1">
<ContentTemplate>
Test
<asp:Button ID="add" Text="Add" OnClick="add_Click" runat="server" />
</ContentTemplate>
</cc1:TabPanel>
</cc1:tabcontainer>
</div>
</form>
</body>
</html>
test5.aspx.cs
using AjaxControlToolkit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void add_Click(object sender, EventArgs e)
{
int currentTab = TabContainer1.ActiveTabIndex;
int nextTab = currentTab + 1;
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
}
}
Here's what I'd do:
Wrap the following code:
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
Into its own method called RenderDynamicTabs(int nextTab)
At the end of add_Click, add this code:
if(null == ViewState["NumDynamicControls"])
{
ViewState["NumDynamicControls"] = 0;
}
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"]);
dynamicControlCount++;
In Page_Load, add the following:
if(null != ViewState["NumDynamicControls"])
{
// There are controls that need to be re-generated
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"]);
for(int i = 1; i <= dynamicControlCount; i++)
{
RenderDynamicTabs(i);
}
}
That should both store and re-render your controls after each PostBack.
Finally, to avoid duplication of code, in add_Click, replace the code you copy-pasted into RenderDynamicTabs with just a call to RenderDynamicTabs(nextTab);.
i removed the additions i added before, but here is what i got so far
using AjaxControlToolkit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (null != ViewState["NumDynamicControls"])
{
// There are controls that need to be re-generated
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"].ToString());
for (int i = 1; i <= dynamicControlCount; i++)
{
RenderDynamicTabs(i);
}
}
}
public void RenderDynamicTabs(int nextTab)
{
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
}
protected void add_Click(object sender, EventArgs e)
{
int currentTab = TabContainer1.ActiveTabIndex;
int nextTab = currentTab + 1;
RenderDynamicTabs(nextTab);
if (null == ViewState["NumDynamicControls"])
{
ViewState["NumDynamicControls"] = 0;
}
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"].ToString());
dynamicControlCount = dynamicControlCount + 1;
}
}
I need to create an HTML button dynamically in my ASP.NET C# codebehind, I must insert this button in my literal control, I use following syntax:
literal.Text+=<button id=\"MyButton\" runat=\"server\" OnServerClick=\"MyButton_Click\">Click Me</Button>";
button is displayed, it causes postback but my server click function (MyButton_Click) is not called, what is going wrong here? I should certainly use a literal, can I use ASP.NET controls in my literal?
I want to call a function after this button causes postback, can I use another objects in my literal? I should certainly use literals
thanks for your answers, I have a lot of codes in my literal, something like this:
......
......
dynTable += "</td></tr>";
dynTable += "<tr><td></td></tr>";
dynTable += "<tr><td></td></tr>";
dynTable += "<tr><td></td></tr>";
dynTable += "<tr><td></td></tr>";
dynTable += "<tr><td align=\"left\">";
dynTable += "<button id=\"MyButton\" type=\"submit\" runat=\"server\" OnServerClick=\"MyButton_Click\">Foo</button>";
dynTable += "</tr></td> </table> ";
}
}
//=====================================
dynTable += " </td>";
dynTable += " </tr>";
dynTable += " </table>";
dynTable += " </td>";
dynTable += " </tr>";
dynTable += " </table>";
dynTable += " </td>";
dynTable += " </tr>";
}
dynTable += "</table>";
}
ReviewPlace.Text = dynTable;
ReviewPlace is my asp.net literal object
You can't add Server - Html/Web controls that way. You have to create an object of Control in Page_Init/Page_Load event and add it to PlaceHolder's Controls collection.
Add PlaceHolder1 control in markup (.aspx)
<form id="form1" runat="server">
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
and write Page_Init handler,
protected void Page_Init(object sender, EventArgs e)
{
System.Web.UI.HtmlControls.HtmlButton button = new System.Web.UI.HtmlControls.HtmlButton();
button.InnerText = "OK";
//Event handler - Lambda (anonymous method) expression
button.ServerClick += (sa, ea) =>
{
Response.Write("button is pressed");
};
//Named Event handler
button.ServerClick += new EventHandler(button_ServerClick);
PlaceHolder1.Controls.Add(button);
}
void button_ServerClick(object sender, EventArgs e)
{
Response.Write("Another handler");
}
EDIT: I suggest you to use jQuery/JavaScript - ajax to request server resources instead of handling server-events if you wish/want to generate markup by hand. Alternative solution to this issue is to use Server constrols - especially GridView/ListView and I'm sure these controls and binding mechanism will solve that issue.
Another possibility is use of Table Server control. Have a look at sample:
//For ease of use I'v subclass the `TableRow`
public class Row : TableRow
{
public Row(int col)
{
for(int i=0;i<col;i++)
Cells.Add(new TableCell());
}
public TableCell this[int index]
{
get { return Cells[index]; }
}
}
and Page_Init code to populate Table object.
protected void Page_Init(object sender, EventArgs e)
{
Table table = new Table();
Row row1 = new Row(3);
row1[0].ColumnSpan = 3;
row1[0].Text = "Search";
table.Rows.Add(row1);
Row row2 = new Row(3);
row2[0].Text = "Enter keyword";
row2[1].Controls.Add(new TextBox());
table.Rows.Add(row2);
Row row3 = new Row(3);
row3[0].ColumnSpan = 3;
Button button = new Button();
button.Text = "Search";
button.Click += (sa, ea) => Response.Write("Button is pressed");
row3[0].Controls.Add(button);
table.Rows.Add(row3);
PlaceHolder1.Controls.Add(table);
}
As AVD points out, this isn't a very good idea.
However, if you do decide to continue down this path, you will need to post back by calling the client script function __doPostBack() function with the correct __EVENTTARGET and __EVENTARGUMENT properties set.
This SO post shows a quick and dirty hack workaround here for doing this, by placing a hidden asp:button on the screen, and then changing your code to call the hidden button click.
When I click my Remove button it is my intent to remove the Panel, then iterate through the remaining panels and give them a new ID from scratch I.E. if I removed Panel(3) from a list of 6 Panels I would iterate through and give them all new IDs Panels 0-5.
My issue is that I keep running into an error after I delete my panel where I have duplicate ID names. For the life of me I cannot see where I am going wrong so I am reaching out hoping I am just blind or for advice.
I was setting a breakpoint at my btnDelete function and step through it but I am not seeing my logic shortcoming in why I experience an issue with multiple Panels of the same ID.
ASPX:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage/MasterPage.master" AutoEventWireup="true" CodeFile="Search.aspx.cs" Inherits="Search" EnableTheming="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
<link href="App_Themes/ui-lightness/jquery-ui-1.7.2.custom.css" rel="stylesheet"
type="text/css" />
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css"
rel="stylesheet" type="text/css" />
<script src="Includes/JavaScript/jquery-1.7.1.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.datepicker.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.widget.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.core.js" type="text/javascript"></script>
<%--Script for the Dropdown Datepicker--%>
<script type="text/javascript">
$(function () {
$("input.datepicker").datepicker({ showOn: 'button', buttonImage: 'Includes/Images/calender.gif', buttonImageOnly: false, onSelect: function () { }
});
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server">
<h1>
Search
<asp:HyperLink ID="HyperLink1" runat="server" ImageUrl="Includes/Images/action_help.gif"
NavigateUrl="~/user_manual.pdf" Target="_blank" ToolTip="Search Help"></asp:HyperLink></h1>
<table border="0" cellpadding="6" cellspacing="0">
<tr>
<td>
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click" />
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" />
</td>
<td>
<asp:TextBox ID="txtTitle" class="searchPage" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder>
</td>
Code behind:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
public partial class Search : BasePage
{
List<Users> userroles = new List<Users>();
//Panel that contains all our Dynamically added user controls.
List<Panel> persistControls = new List<Panel>();
public int userid = 0;
public byte IsActive = 1;
public int error = 0;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
// Calls three functions responsible for pulling from the Database and binding the Datagrid.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetClustersFromDB(userid);
BindGrid();
BindState();
}
else
{
// Where I am recreating my controls.
DynamicQueryRecreateLogic();
}
}
protected void DynamicQueryRecreateLogic()
{
if (Session["persistControls"] != null)
{
// Local Value that contains the members of the current persistControls session, not yet pushed to the page.
persistControls = (List<Panel>)Session["persistControls"];
int count = 0;
foreach (Panel panel in persistControls)
{
//AddQuestionTypeDropDownList(count);
panel.ID = "panel" + "(" + count.ToString() + ")";
foreach (Control control in panel.Controls)
{
if (control.GetType() == typeof(DropDownList))
{
control.ID = "list" + "(" + count.ToString() + ")";
DropDownList list = (DropDownList)panel.FindControl(control.ID);
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
}
if (control.GetType() == typeof(TextBox))
{
control.ID = "txtBox" + "(" + count.ToString() + ")";
}
}
// Re-Adding our Remove Button
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = count.ToString();
// Pushing to Placeholder
myPlaceholder.Controls.Add(panel);
myPlaceholder.Controls.Add(btnRemove);
count++;
}
}
}
private DropDownList AddQuestionTypeDropDownList()
{
DropDownList list = new DropDownList();
list.ID = "list" + "(" + persistControls.Count.ToString() + ")";
list.Items.Add(new ListItem("--Select One--", ""));
list.Items.Add(new ListItem("Title", "1"));
list.Items.Add(new ListItem("Contact", "2"));
list.Items.Add(new ListItem("Date Created", "3"));
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
return list;
}
private TextBox AddFieldTypeTextBox(int count)
{
TextBox box = new TextBox();
box.ID = "txtBox" + "(" + count.ToString() + ")";
return box;
}
protected void btnAdd_Click(object sender, EventArgs e)
{
try
{
Panel panelContainer = new Panel();
panelContainer.ID = "panel" + "(" + persistControls.Count.ToString() + ")";
panelContainer.Controls.Add(AddQuestionTypeDropDownList());
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = persistControls.Count.ToString();
persistControls.Add(panelContainer);
myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page.
myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page.
Session["persistControls"] = persistControls; // put it in the session
}
catch
{
throw;
}
}
protected static string DecipherCountNumber(string IDHolder)
{
int start = IDHolder.IndexOf("(");
if (start == -1)
{
return IDHolder;
}
else
{
return IDHolder.Substring(start + 1).Replace(")", string.Empty);
}
}
protected void list_SelectedIndexChanged(object sender, EventArgs e)
{
//I need to fix the dynamic Add location. I need to track some type of enumeration or attributes of the panel for recreation.
try
{
DropDownList list = (DropDownList)sender;
string IDHolder = list.ID.ToString();
int count = Convert.ToInt32(DecipherCountNumber(IDHolder));
Panel panelContainer = persistControls.Find(delegate(Panel panel) { return panel.ID == "panel" + "(" + count.ToString() + ")"; });
if (list.SelectedIndex == 1)
{
//panelContainer.Controls.Add(AddFieldTypeTextBox(count));
}
if (list.SelectedIndex == 2)
{
//panelContainer.Controls.Remove(FindControl("txtBox" + "(" + count.ToString() + ")"));
}
if (list.SelectedIndex == 3)
{
//panelContainer.Controls.Remove(FindControl("txtBox" + "(" + count.ToString() + ")"));
}
Session["persistControls"] = persistControls;
}
catch
{
throw;
}
}
protected void btnClear_Click(object sender, EventArgs e)
{
try
{
Session["persistControls"] = null;
Response.Redirect(Request.Url.ToString());
}
catch
{
throw;
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
persistControls.Remove(persistControls[deleteThisOne]);
Session["persistControls"] = persistControls;
Response.Redirect(Request.Url.ToString(), false);
}
catch
{
throw;
}
}
I modified my DynamicQueryControls to do the recreation OnInit rather than at PageLoad. Quite a few issues arise from creating this at the PageLoad level.
I want to create dynamic text box when user click on Add more link button.
For this I am using this code. And I have to mention that I am using master page.
protected void lnkAddMore_Click(object sender, EventArgs e)
{
if (Request.Cookies["value"] != null)
{
i = Convert.ToInt32(Request.Cookies["value"].Value) + 1 ;
}
for (int k = 1; k <= i; k++)
{
LiteralControl literal = new LiteralControl();
literal.Text = "<br /><br />";
Label newLabel = new Label();
newLabel.Text = "Choice" + " " + k.ToString();
newLabel.ID = "lblChoice_" + k.ToString();
newLabel.Attributes.Add("runat", "Server");
this.panelLabel.Controls.Add(newLabel);
this.panelLabel.Controls.Add(literal);
LiteralControl literal1 = new LiteralControl();
literal1.Text = "<br /><br />";
TextBox nexText = new TextBox();
nexText.ID = "txtChoice_" + k.ToString();
nexText.Attributes.Add("TextMode", "MultiLine");
nexText.Attributes.Add("runat", "Server");
panelTextbox.Controls.Add(nexText);
this.panelTextbox.Controls.Add(literal1);
Response.Cookies["value"].Value = i.ToString();
Session["Panel"] = panelTextbox;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["Panel"] != null)
{
ContentPlaceHolder content=new ContentPlaceHolder();
content.Controls.Add(Session["Panel"] as Panel);
}
}
}
Now I am facing trouble how to retrieve the data of the these text boxes after the clicking on the submit button so that I can store the values of there text boxes to database.
What will be code written for the click event of btnSave
protected void btnSave_Click(object sender, EventArgs e)
{
if (Session["Panel"] != null)
{
ContentPlaceHolder content_new = new ContentPlaceHolder();
for (int i = 1; i <= count; i++)
{
strControlName = "txtChoice_" + i.ToString();
TextBox objTextBox = (TextBox)content_new.FindControl(strControlName);
strTextBoxValues[i] = objTextBox.Text;
string str3 = strTextBoxValues[2];
}
}
}
This code is showing error for objTextBox. The error is NullReferenceException.
How to write stored procedure for saving data of above code?
The main problem is handling the parameter declaration, how to declare dynamic parameter for passing values so that value is saved for dynamic textbox?
Thanks.
I have already answered it here.
Lost dynamically created text box values
You can try this.
private string GetValue(string ControlID)
{
string[] keys = Request.Form.AllKeys;
string value = string.Empty;
foreach (string key in keys)
{
if (key.IndexOf(ControlID) >= 0)
{
value = Request.Form[key].ToString();
break;
}
}
return value;
}
Then to get the value
string txtChoice1value = GetValue("txtChoice1");
First of all when you dynamically create a control it doesn't need to be set "runat = sever".
Problem is in this line `ContentPlaceHolder content_new = new ContentPlaceHolder();` you make a new ContentPlaceHolder, this mean it doesn't have any control to be found.
Check this page. How To Create TextBox Control Dynamically at Runtime
You need to find the reference of your already created ContentPlaceHolder like-
ContentPlaceHolder cnt =(ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
and then add the dynamically created Control in that ContentPlaceHolder as-
cnt.Controls.Add(Session["Panel"] as Panel);
Why you creating a new ContentPlaceHolder each time even when you have mentioned that you are using masterPage, so there must exists a ContentPlaceHolder..
Controls wont persist on postback have a look at http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx