I am trying to add a new row to HtmlTable on click of button Add Row.
It adds one row. But it doesn't add further rows. Please advise.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="eLaundrySearchWeb.Test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table id="myTable" runat="server">
<tr>
<td>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</td>
<td>
<asp:TextBox ID="txtQty" runat="server">
</asp:TextBox>
</td>
<td>
<asp:Button ID="Button1" runat="server" Text="Add Row" OnClick="AddRow_Click"
/>
</td>
</tr>
</table>
</div>
</form>
protected void AddRow_Click(object sender, EventArgs e)
{
//Random r=new Random();
//int rv=r.Next(0,100);
int numOfRows = myTable.Rows.Count;
HtmlTableRow row = new HtmlTableRow();
row.ID = "tbl_row"+(numOfRows+1);
HtmlTableCell cell1 = new HtmlTableCell();
cell1.ID = "tbl_cell1"+ (numOfRows+1);
TableCell cell2 = new TableCell();
cell2.ID = "tbl_cell2" + (numOfRows + 1);
TextBox tb = new TextBox();
tb.ID = "tbQty" + (numOfRows + 1);
cell1.Controls.Add(tb);
row.Cells.Add(cell1);
myTable.Rows.Add(row);
myTable.DataBind();
}
It is adding the rows every time you click the button.The only problem here is that the button is causing the postback and on postback the controls that were dynamically created are getting cleared.Then your button click event adds a row again.So it seems to you that the row is only added once.But in reality it is getting added everytime,it's just that on postback the earlier ones are getting cleared.
Trying converting your code into a function and call that function on postback.
Similar SO Question
Related
Folks,
Need one help in creating the dynamic controls in C#.
Like, I am putting ID, Text and all the mandatory validation properties into the database and from that values I need to create a control in ASP WinForm or Web page.
Please suggest me the view part to achieve the same.
here is my database table template
CREATE TABLE CONTROL(
PK_CONTROL_ID VARCHAR(128) NOT NULL,
CONTROL_NAME VARCHAR(128) NOT NULL,
PRIMARY KEY(CONTROL_ID)
);
CREATE TABLE CONTROLPROPERTY(
PK_PROPERTY_ID INT NOT NULL IDENTITY(1,1),
FK_CONTROL_ID INT NOT NULL FOREIGN KEY REFERENCES CONTROLPROPERTY(PK_CONTROL_ID),
CONTROLPROPERTY VARCHAR(128) NOT NULL,
CONTROLVALUES VARCHAR(128) NOT NULL,
PRIMARY KEY(PK_PROP_VALUE_ID)
);
**Example**
PK_CONTROL_ID CONTROL_NAME
1 TextBox
PK_PROPERTY_ID FK_CONTROL_ID CONTROLPROPERTY CONTROLVALUES
1 1 ID txtName
2 1 Visible true
3 1 ToolTip Name
Refered this example but I need to implement same table structure for the different types of controllers
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="TestControlFirst.index" %>
<%# Import Namespace="System.Data" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load (object sender, EventArgs e)
{
if (!IsPostBack)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Firstname");
dt.Columns.Add("Lastname");
for (int i = 0; i < 10; i++)
{
DataRow row = dt.NewRow();
row.ItemArray = new object[] {i,"Joe_"+i.ToString(),"Blow" +i.ToString()};
dt.Rows.Add(row);
Repeater1.DataSource = dt;
Repeater1.DataBind();
}
}
}
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
int rowid = (e.Item.ItemIndex);
TextBox tb = (TextBox)Repeater1.Items[rowid].FindControl("txtOne");
Label2.Text = tb.Text;
}
</script>
ASPX page
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Repeater Demo</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Repeater1" runat="server" onitemcommand="Repeater1_ItemCommand">
<HeaderTemplate>
<table border="1" width="50%">
<tr>
<th>SELECT</th>
<th>ID</th>
<th>FIRST</th>
<th>LAST</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Button ID="btnOne" runat="server" Text="SELECT" /></td>
<td> <asp:TextBox ID="txtOne" runat="server" Text='<%# Eval("ID") %>' /></td>
<td><%# Eval("Firstname") %></td>
<td><%# Eval("LastName") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
<asp:Label ID="Label2" runat="server"></asp:Label>
</form>
</body>
</html>
Thanks in advance
Your best bet is to create dynamic Controls and add them to a PlaceHolder by looping the database rows and create Controls based on the row values. This needs to happen every time the page is loaded, and that includes a PostBack
while (reader.Read())
{
string controlType = reader["CONTROL_NAME"].ToString();
if (controlType == "TextBox")
{
TextBox textbox = new TextBox();
textbox.ID = reader["ID"].ToString();
textbox.Visible = Convert.ToBoolean(reader["Visible"]);
textbox.ToolTip = reader["ToolTip"].ToString();
PlaceHolder1.Controls.Add(textbox);
}
else if (controlType == "Label")
{
Label label = new Label();
label.ID = reader["ID"].ToString();
label.Visible = Convert.ToBoolean(reader["Visible"]);
label.Text = reader["Text"].ToString();
PlaceHolder1.Controls.Add(label);
}
else if (controlType == "Button")
{
//etc
}
}
And to read the form values on submit you basically need to do the same. Loop all the ID's and Control types from the database, create them dynamically and read their values.
As you can see this process can become complex real fast if you have a lot of different controls and rows, so think about your approach and see if this is the best solution.
I have GridView with a Button beneath it. Upon clicking the button I want to Add a new blank row just beneath the GridView
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnTest" Text="Test" runat="server" OnClick="btnTest_Click" />
</div>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<strong>Dynamic Grid</strong></td>
</tr>
<tr>
<td>
<asp:GridView ID="GrdDynamic" runat="server" AutoGenerateColumns="true"
OnRowDataBound="GrdDynamic_RowDataBound" >
</asp:GridView>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</form>
</body>
</html>
and the data is being populated by below way....
In pageLoad I am calling the bind
DataTable dt = GroupBudgetSetUpBLL.Instance.GetAllGroupBudgetSetUp();
GrdDynamic.DataSource = dt;
GrdDynamic.DataBind();
and in rowdatabound I am making the Grid Editable textbox.
protected void GrdDynamic_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 1; i < e.Row.Cells.Count; i++)
{
TextBox txt = new TextBox();
string budget = e.Row.Cells[i].Text.Split('_').LastOrDefault();
string txtID = e.Row.Cells[i].Text.Split('_').FirstOrDefault() + "_" + e.Row.Cells[i].Text.Split('_').Skip(1).FirstOrDefault();
txt.ID = txtID;
txt.Text = budget;
e.Row.Cells[i].Text = "";
e.Row.Cells[i].Controls.Add(txt);
}
}
}
Now upon clicking the "Button" below the Grid I want to display a blank row just beneath the MainGrid , cells control type will be TextBox so that it remains editable.
What I could infer from your question is that you need to add a new blank row beneath the GridView (looking like the last row of the GridView is blank on button_click).
I am not sure how feasible it is to add a new Row to the databound Grid View but instead what you could do is to add a blank row in the data table like below:
Add the below code to your button1_Click():
protected void Button1_Click(object sender, EventArgs e)
{
DataTable dt = GroupBudgetSetUpBLL.Instance.GetAllGroupBudgetSetUp();
DataRow myRow = dt.NewRow();
dt.Rows.InsertAt(myRow, dt.Rows.Count);
GrdDynamic.DataSource = dt;
GrdDynamic.DataBind();
}
I'm absolutliy confused.
I try to Change the default Text for a Textbox.
Here a simple Code to reproduce the Problem.
TextBox Textbox1 and the label become updated on any click to the Button.
Textbox var will never get updated. Only on first PageLoad.
The Problem is, I have to add my Textboxes from Code behind and not in aspx Page.
Any Ideas whats going on and how I can get it working?
%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="tbtester.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div >
<asp:Panel ID="mypanel" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</asp:Panel>
</div>
</form>
</body>
</html>
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace tbtester
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.Web.UI.WebControls.TextBox var = new System.Web.UI.WebControls.TextBox();
//if (!this.Page.IsPostBack)
Label test = new Label();
mypanel.Controls.Add(test);
mypanel.Controls.Add(var);
var.Text = DateTime.Now.ToLongTimeString();
test.Text = DateTime.Now.ToLongTimeString();
var.ReadOnly = false;
TextBox1.Text = DateTime.Now.ToLongTimeString();
}
}
}
Disable its read only flag before adding it to your panel:
TextBox var = new TextBox();
var.ReadOnly = false;
mypanel.Controls.Add(var);
I have the following simple page;
<%# Import namespace="System.IO" %>
<script runat="server">
int pageSize = 10;
int pageNum = 1;
protected override void OnInit(EventArgs e)
{
var currentPage = Directory.GetFiles(#"C:\mypath", "*.pdf").Skip((pageNum - 1) * pageSize).Take(pageSize).OrderBy(c => c).ToArray();
Listview1.DataSource = currentPage;
Listview1.DataBind();
base.OnInit(e);
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test project</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ListView ID="Listview1" runat="server">
<LayoutTemplate>
<table cellpadding="0" cellspacing="0">
<tr>
<td>Titel</td>
<td>Size</td>
</tr>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><a href=''><%#Eval("Name") %></a></td>
<td>0 kb</td>
</tr>
</ItemTemplate>
</asp:ListView>
</form>
</body>
</html>
How do i get Filename, size, path etc into my Listview. If i just had a simple for each directly on the GetFiles, i could do something like
FileInfo f = new FileInfo(pdfFile);
long pdfSize = f.Length;
Response.Write(Path.GetFileName(pdfFile) + " - " + pdfSize.ToString() + "<br/>");
But how do i achive this in my ListView?
You are selecting the paths to the files not the files itself. Hence you cannot get the FileInfo's properties what raises your exception "DataBinding: 'System.String' does not contain a property with the name 'Name'"
This should work:
var currentPage = Directory.GetFiles(#"C:\mypath", "*.pdf").Skip((pageNum - 1) * pageSize).Take(pageSize).OrderBy(c => c).ToArray();
.Skip((pageNum - 1) * pageSize)
.Take(pageSize)
.OrderBy(c => c)
.Select(path => new System.IO.FileInfo(path)).ToArray();
You may need to create a new listviewitem collection and add your values to the collection using a loop. Then add the listviewitems back to the listview.
http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.items.aspx
In my winforms aplication I have a WebBrowser control named webBrowser1.
In code all I added is navigating to a page:
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("http://localhost:6489/Default.aspx");
}
The code for the page to which I navigate is:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TableRowShow.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
window.onload = function()
{
document.getElementById('addDestination').setAttribute('onclick', 'addDest();');
}
function attach()
{
document.getElementById('addDestination').setAttribute('onclick', 'addDest();');
}
var i = 1; // position of next tr to be shown
function addDest()
{
var trs = document.getElementById('travelTable').getElementsByTagName('tr');
if (trs[i] != null)
trs[i++].style.display = "";
}
</script>
</head>
<body>
<form id="form1" runat="server">
<table id="travelTable">
<tr>
<td>
<asp:TextBox runat="server" />
</td>
</tr>
<tr style="display: none">
<td>
<asp:TextBox runat="server" />
</td>
</tr>
<tr style="display: none">
<td>
<asp:TextBox runat="server" />
</td>
</tr>
</table>
<asp:HyperLink runat="server" ID="addDestination"
ClientIDMode="Static" NavigateUrl="javascript:;" >
Add Destination
</asp:HyperLink>
</form>
</body>
</html>
Seen in a browser like IE or Chrome the page looks like this:
Clicking on Add Destination anchor creates a new input:
The problem that I'm having with WebBrowser control is that it loads the page but the JavaScript doesn't work.
If I click on Add Destination nothing happens, even though the same page works well in Chrome or IE.
Placing a breakpoint and using:
webBrowser1.Document.InvokeScript("addDestination");
inside the Immediate window and then continuing to run the program activates the JavaScript in that function adding a new input.
Thanks for replies!
Try attaching the click handlers like this instead of using setAttribute in the onload and attach functions:
document.getElementById('addDestination').onclick = addDest;
You could try setting the ScriptErrorsSuppressed property to false to see whether any JavaScript errors occur.