0

I have an existing table which is dynamically generated, the row contains set of controls like textboxes and dropdowns again dynamically generated. There is a "Add new row" button on the main page. On clicking the button a new blank row gets added to the table with all the previous entries set.

The problem occurs when we click the button, it causes the main form to refresh, is there a way to prevent this?

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
ks_baba
  • 29
  • 3
  • 11
  • Sure, but you'd have to use JavaScript to add the new blank row. – Mike Perrenoud Jan 15 '14 at 17:21
  • If you don't want to use Javascript, you might want to use an UpdatePanel. – Aycan Yaşıt Jan 15 '14 at 17:23
  • @Michael But the row which gets added itself has other asp.net controls which may not be possible to create using javascript – ks_baba Jan 15 '14 at 17:24
  • 1
    Have you tried looking at the UpdatePanel control? You could use it to refresh just the table and not the whole form. See here: http://msdn.microsoft.com/en-us/library/bb399001.aspx – sr28 Jan 15 '14 at 17:25
  • 1
    @user1577780: In that case you may want to consider some re-engineering of the table itself. ASP.NET "controls" can't be added via JavaScript, but the resulting markup *can*. However, at that point you'd likely be breaking some of the statefulness tracked by the ASP.NET controls. Perhaps another approach for the table would work? Does it *need* to be an ASP.NET table or can it be something like one of the many JavaScript table plugins? – David Jan 15 '14 at 17:25
  • @AycanYaşıt I tried the update panel but it causes a conflict. On some of the textboxes I have registered event on text change to check for valid values. Including the table inside UpdatePanel causes the validation to fail. Kindly suggest any good example of update panel and which elements must be kept inside and outside UpdatePanel – ks_baba Jan 15 '14 at 17:27
  • To add a row with javascript is simple enough. You said `a set of controls [textboxes, dropdowns are] generated... on clicking the button a new row gets added ... with all previous entries set`. But what do you want to do afterwards? Are you using webforms? – surfmuggle Jan 15 '14 at 17:27
  • @threeFourOneSixOneThree Since the table and the controls within the row are dynamically generated, when adding new row causes the page to get refreshed and all the controls need to be regenerated to retain their previous state [if user had filled any values in the cells]. How i use this table is after submission of the form i use the table to set an class object designed to hold this data. – ks_baba Jan 15 '14 at 17:48
  • If you already tried using an update panel and were having conflicts why not ask a question in this direction. Without code that shows what you have and what you have tried it is difficult to help. – surfmuggle Jan 15 '14 at 18:15
  • Thanks all I have finally found the solution...using the Update Panel and dynamic controls – ks_baba Jan 17 '14 at 16:30

2 Answers2

0

You will have to use UpdatePanel/Ajax to make this work without a complete page refresh. This answer is pretty good.

Community
  • 1
  • 1
xoail
  • 2,978
  • 5
  • 36
  • 70
0

The .aspx files code here :

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="step_by_step.aspx.cs" Inherits="Test_ankit_27Oct_Research_step_by_step" %>
<!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>
<style type="text/css">
    #form1
    {
        height: 199px;
    }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <br />
    <asp:Button ID="Button2" runat="server" onclick="Button2_Click" 
        Text="Outside Update Button (+2)" />
    <br />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            &nbsp;<asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
                Text="Inside Update  Button (+1)" />
            <br />
            &nbsp;
            <asp:Label ID="Label1" runat="server" Font-Bold="True" Text="Label"></asp:Label>
            &nbsp;<br /> &nbsp;
            <asp:Label ID="Label2" runat="server" style="font-weight: 700" Text="Label"></asp:Label>
            <br /> &nbsp;<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
            <br />
            &nbsp;
            <br />
            &nbsp;
            <br />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
        </Triggers>

    </asp:UpdatePanel>
</div>
</form>

The .cs file code here :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Test_ankit_27Oct_Research_step_by_step : System.Web.UI.Page
{
    static int start_number_rows = 1; //initial counter default row as 1
    static int counter = start_number_rows;
    protected void Page_Init(object sender, EventArgs e)
   {
       ViewState["RowsCount"] = start_number_rows;
       Label1.Text = "Total Rows : "+counter.ToString();

  }
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        generate_table();
    }
    else
    {
        //the below part of the code is required to distinguish between autopost back of textbox 
        //and the autopost back of button controls

        string CtrlID = string.Empty;
        if (Request.Form["__EVENTTARGET"] != null &&
                 Request.Form["__EVENTTARGET"] != string.Empty)
        {

             generate_table();
             // for all postbacks except external and internal clicks

        }
        else
        {


            //to check which button or image button click caused the postback
            foreach (string controlID in Request.Form)
            {
                Control objControl = Page.FindControl(controlID);
                if (objControl is Button)
                {
                    CtrlID = objControl.ID;
                    if (CtrlID == "Button1")
                    {

                        //now the call will go to Button1_Click function


                    }
                    if (CtrlID == "Button2")
                    {

                        //now the call will go to Button2_Click function


                    }
                }
            }
        }
       //then let the control flow to button click events
    }
}
protected void generate_table()
{

    Table table = new Table();
    TableRow row;
    TableCell cell;
    TextBox tb;
    table.ID = "Table1";

    int s_rows = Convert.ToInt32(ViewState["RowsCount"].ToString());

    for (int k = 1; k <= s_rows; k++)
    {
        row = new TableRow();
        cell = new TableCell();

        tb = new TextBox();
        tb.ID = "tb_" + k;
        tb.TextChanged += new EventHandler(tb_TextChanged);
        tb.AutoPostBack = true;
        cell.Controls.Add(tb);

        row.Cells.Add(cell);
        table.Rows.Add(row);
    }

   PlaceHolder1.Controls.Add(table);
}

protected void setdata()
{
    Table table = (Table)Page.FindControl("Table1");
    if (table != null)
    {

        foreach (TableRow tr in table.Rows)
        {
            foreach (TableCell tc in tr.Cells)
            {
                foreach (Control ct in tc.Controls)
                {
                    if (ct is TextBox)
                    {

                        ((TextBox)ct).Text = Request.Form[ct.ID];
                    }
                    if (ct is DropDownList)
                    {
                        ((DropDownList)ct).Text = Request.Form[ct.ID];
                    }
                }
            }
        }
    }
}


protected void Button1_Click(object sender, EventArgs e)
{

    counter++;
    Label1.Text = "Total Rows : "+counter.ToString();
    //Label1.Text = "Refreshed at " + DateTime.Now.ToString();

    int new_rows_count = Convert.ToInt32(ViewState["RowsCount"]) + 1; //add one rows at a time
    ViewState["RowsCount"] = new_rows_count;
    generate_table();
    setdata();        //set the values of any of the previously generated  controls
}
protected void Button2_Click(object sender, EventArgs e)
{


     counter=counter+2;
     Label1.Text = "Total Rows : " + counter.ToString();
    //Label1.Text = "Refreshed at " + DateTime.Now.ToString();

    int new_rows_count = Convert.ToInt32(ViewState["RowsCount"]) + 2; //add 2 rows at a time
    ViewState["RowsCount"] = new_rows_count;

    generate_table();
    setdata();        //set the values of any of the previously generated  controls
}

protected void tb_TextChanged(object sender, EventArgs e)
{

    TextBox tb = (TextBox)sender;
    Label2.Text = "Text of textbox "+ tb.ID+ " changed to " + tb.Text;

}
}
Kalu Singh Rao
  • 1,671
  • 1
  • 16
  • 21
ks_baba
  • 29
  • 3
  • 11
  • How do I use this logic with the content page having a master page? When I use a master page, the textbox doesn't retain the the text it had. – Jeff Mcbride Dec 18 '16 at 00:29