UpdatePanel and Placeholder Control Problem

Hello everyone,

I am having some problems with this page that has a Placeholder control inside an UpdatePanel control. When the updatepanel is triggered, then the page seems to do a full postback and I end up with 2 sets of controls added to the page instead of 1.

Here is where I'm creating the updatepanel and placeholder:
<asp:UpdatePanel ID="upd3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
      <asp:PlaceHolder ID="plhSemesters" Runat="server" />
</ContentTemplate>
<Triggers>
      <asp:AsyncPostBackTrigger ControlID="btnSave1" EventName="Click" />
      <asp:AsyncPostBackTrigger ControlID="btnSave2" EventName="Click" />
</Triggers>
</asp:UpdatePanel>

Here is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
      ...
      if (!IsPostBack)
      {
            //Enable Save Buttons
            btnSave1.Enabled = true;
            btnSave2.Enabled = true;
            //Set Course Title
            lblCourseTitle.Text = crs.courTitle;
      }
      //Display Semesters and each Location
      ArrayList sems = Semester.getSemesterList(DateTime.Now, sqlCon);
      DisplaySemesters(crs, sems, sqlCon);
      ...
}
private void DisplaySemesters(Course crs, ArrayList Semesters, SqlConnection sqlCon)
{
      //Go through each semester, and display all location frequencies
      plhSemesters.Controls.Clear();
      ...
      //TextBox for Course Frequency
      TextBox txtCFLoc = new TextBox();
      txtCFLoc.ID = "txt" + sem.semId + loc.locId;
      txtCFLoc.CssClass = "TextBox";
      txtCFLoc.MaxLength = 2;
      ...
      if (i % 2 == 0) { plhSemesters.Controls.Add(new LiteralControl("<tr class='ItemRow1'>")); }
      else { plhSemesters.Controls.Add(new LiteralControl("<tr class='ItemRow2'>")); }
      plhSemesters.Controls.Add(new LiteralControl("<td vAlign='middle' align='left' width='25%' class='LabelBold'>" + loc.locCity + "</td>"));
      plhSemesters.Controls.Add(new LiteralControl("<td vAlign='middle' align='left' width='10%'>"));
      plhSemesters.Controls.Add(txtCFLoc);
      plhSemesters.Controls.Add(new LiteralControl("</td>"));
      plhSemesters.Controls.Add(new LiteralControl("<td vAlign='middle' align='left' width='65%'></td>"));
      plhSemesters.Controls.Add(new LiteralControl("</tr>"));
      ...
}


When I click on one of the linkbuttons to trigger the updatepanel, I get a full page postback and 2 sets of controls.

Is there a bug with the updatepanel and placeholder controls or am I doing something wrong?
LVL 3
quanmacAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
I am confused why you don't just define an HtmlTable, and add that to the UpdatePanels controls:

            HtmlTable table = new HtmlTable();
            HtmlTableRow row = new HtmlTableRow();
            HtmlTableCell cell = new HtmlTableCell();
            cell.InnerText = "Bob";

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

            upd3.Controls.Add(table);

Bob
0
quanmacAuthor Commented:
I don't add the table programatically, I'm just adding the rows dynamically:



<tr>
	<td vAlign="top" align="center" width="100%" class="Label" height="5" colspan="3"></td>
</tr>
<asp:UpdatePanel ID="upd3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
	<asp:PlaceHolder ID="plhSemesters" Runat="server" />
</ContentTemplate>
<Triggers>
	<asp:AsyncPostBackTrigger ControlID="btnSave1" EventName="Click" />
	<asp:AsyncPostBackTrigger ControlID="btnSave2" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<tr>
	<td align="right" valign="top" width="100%" colspan="3">
    		<asp:UpdatePanel ID="upd4" runat="server">
		<ContentTemplate>
			<asp:LinkButton ID="btnSave2" Font-Underline="True" CssClass="LabelButton" Enabled="False" Text="Save"
		    		Width="30" Runat="server" OnClick="btnSave_Click" ToolTip="Save Course Semester Frequencies" />
		</ContentTemplate>
		</asp:UpdatePanel>
	</td>
</tr>
</table>

Open in new window

0
Bob LearnedCommented:
Well, then, where is the table defined?

Bob
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

quanmacAuthor Commented:
in the aspx page
0
Bob LearnedCommented:
Nope, I don't see that anywhere.

Bob
0
quanmacAuthor Commented:
That's because I didn't post the whole aspx page. I only posted a snippet where I declared the updatepanel and placeholder control
0
Bob LearnedCommented:
1) I don't see why you are getting multiple controls.

2) I don't understand the need for the placeholder.

3) Dynamically altering an HTML table can be done in a different way.

Bob
0
quanmacAuthor Commented:
I will attach my complete aspx page and screenshots of what is happening. I'm aware that there are other ways to dynamically add controls to a table, but the way I do it has been working great for me.


<form runat="server">
<AJAXToolKit:ToolkitScriptManager ID="scriptManager" runat="server" />
<table class="Content" cellSpacing="0" cellPadding="0" width="540" border="0">
    <tr>
	    <td vAlign="top" align="left" width="100%" colspan="3">
		    <table cellSpacing="0" cellPadding="0" background="graphics/border_c_2.jpg" border="0">
			    <tr>
				    <td><IMG height="15" src="graphics/border_c_1.jpg" width="303" border="0"></td>
			    </tr>
			    <tr>
				    <td>
					    <table class="Content3" cellSpacing="0" cellPadding="0" border="0">
						    <tr>
							    <td>Please assign the minimum course frequency for each location,
								in each of the semesters.
							    </td>
						    </tr>
					    </table>
				    </td>
			    </tr>
			    <tr>
				    <td><IMG height="8" src="graphics/border_c_3.jpg" width="303" border="0"></td>
			    </tr>
		    </table>
	    </td>
    </tr>
    <tr>
	    <td vAlign="top" align="center" width="100%" class="Label" height="10" colspan="3"></td>
    </tr>
    <tr>
	    <td vAlign="top" align="left" width="100%" colspan="3">
		<asp:UpdatePanel ID="upd1" runat="server">
		<ContentTemplate>
		    <asp:label id="lblStatus" Runat="server" CssClass="Error"></asp:label>
		</ContentTemplate>
    <Triggers>
	<asp:AsyncPostBackTrigger ControlID="btnSave1" EventName="Click" />
	<asp:AsyncPostBackTrigger ControlID="btnSave2" EventName="Click" />
    </Triggers>
    </asp:UpdatePanel>
	    </td>
    </tr>
    <tr>
	    <td vAlign="top" align="center" width="100%" class="Label" height="5" colspan="3"></td>
    </tr>
    <tr>
	    <td vAlign="top" align="left" width="100%" colspan="3">
		<asp:Label ID="lblCourseTitle" CssClass="LabelBold" runat="server" />
	    </td>
    </tr>
    <tr>
	    <td vAlign="top" align="center" width="100%" class="Label" height="10" colspan="3"></td>
    </tr>
    <tr>
		<td align="right" valign="top" width="100%" colspan="3">
		    <asp:UpdatePanel ID="upd2" runat="server">
		<ContentTemplate>
	<asp:LinkButton ID="btnSave1" Font-Underline="True" CssClass="LabelButton" Enabled="False" Text="Save"
				    Width="30" Runat="server" OnClick="btnSave_Click" ToolTip="Save Course Semester Frequencies" />
			</ContentTemplate>
			</asp:UpdatePanel>
		</td>
	</tr>
	<tr>
	    <td vAlign="top" align="center" width="100%" class="Label" height="5" colspan="3"></td>
    </tr>
    <asp:UpdatePanel ID="upd3" runat="server" UpdateMode="Conditional">
	<ContentTemplate>
		<asp:PlaceHolder ID="plhSemesters" Runat="server" />
	    </ContentTemplate>
	    <Triggers>
	<asp:AsyncPostBackTrigger ControlID="btnSave1" EventName="Click" />
	<asp:AsyncPostBackTrigger ControlID="btnSave2" EventName="Click" />
	</Triggers>
    </asp:UpdatePanel>
    <tr>
		<td align="right" valign="top" width="100%" colspan="3">
		    <asp:UpdatePanel ID="upd4" runat="server">
		<ContentTemplate>
	<asp:LinkButton ID="btnSave2" Font-Underline="True" CssClass="LabelButton" Enabled="False" Text="Save"
				    Width="30" Runat="server" OnClick="btnSave_Click" ToolTip="Save Course Semester Frequencies" />
			</ContentTemplate>
			</asp:UpdatePanel>
		</td>
	</tr>
</table>
</form>

Open in new window

0
quanmacAuthor Commented:
Attached is a screenshot of the page when it first loads and a screenshot of the top of the page where I'm getting multiple controls after I click on the linkbutton.
FirstLoad.JPG
AfterButtonClick.JPG
0
AngryBinaryCommented:
First, try setting EnableViewState="false" in the UpdatePanel and PlaceHolder controls.

When that (probably) doesn't work, then the problem is you're attempting to add 'tr' rows inside of a 'div' (which is how an 'UpdatePanel' renders) inside of a 'td' table cell. This makes broken HTML. When the client side update occurs, and your browser attempts to cram a div full of rows into the DOM, the DOM silently dies. On the second refresh, it cannot make sense out of the HTML and gets lost attempting to replace the contents of the UpdatePanel div.

An alternative that may minimize the impact on your methodology is to put the entire table inside a single UpdatePanel and store all the static HTML in string constants in the code-behind. When the page loads, piece the strings together and insert the dynamic rows on the fly. From the looks of things, there is no performance benefit gained by doing the async postbacks, since all the dynamic pieces update together anyway. The only reason to use AJAX here is to get that 'no flicker' refresh, which you will still get if you do it in a single panel

Randall
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AngryBinaryCommented:
BTW, breaking up the tables per that last thing I said will also probably mean you will have to write plain ol' HTML links into the table that call __doPostBack and target another conrol's ID (that is specified as a trigger for the UpdatePanel) to get the UpdatePanel to refresh - which also means you have to disable event validation for the page - unless you can place the LinkButtons outside the UpdatePanel.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.