I want to create a dynamic form where user has a button to click on it.
When the button clicked, it will trigger a partial postback and add a new control into a placeholder.
My problem is, when the button is clicked for the first time, it able to create a new control in the placeholder. But it will not create more than that even though i have clicked the button for few times.
<asp:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Add images" OnClick="Button1_Click" />
<asp:HiddenField ID="HiddenField1" runat="server" Value="1" />
<br />
<asp:Panel ID="PlaceHolder1" runat="server">
<asp:FileUpload ID="FileUpload1" runat="server" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Code behind:
protected void Button1_Click(object sender, EventArgs e)
{
PlaceHolder1.Controls.Add(new FileUpload());
}
Unless a dynamically added control is added at the preinit or init stage, it does not persist beyond a post back. So when the button is clicked for the second time, the first added control is lost and then the button logic adds a control again, leaving you with one control every time. For a control added after the init stage, you would need to store its state and recreate it on each postback. This is described int this article:
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
You may also be able to achieve your goals without using dynamically added controls. One possible approach is to use a ListView control, add a FileUpload control to its ItemTemplate and add a new record to the list view data source every time the button is clicked.
Related
I have an ASP web form that includes divs, checkboxes, textboxes, buttons and dropdowns. Backend is c#.
I have an "Add" button at the bottom that when clicked, I want it to duplicate my form below the existing one.
Other than copying my form multiple times and toggling visibility based on a button click, is there some way I can put my form in a class and call on it based on the button click? Or any other way? Would think gridview is an option but I use divs within the form which is not allowed in gridview.
For Example:
<form id="form" runat="server">
<asp:ScriptManager ID="MainScriptManager" runat="server" />
<asp:UpdatePanel ID="updatepnl" runat="server">
<ContentTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
<asp:Button ID="add" runat="server" Text="Add" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
The Add button can be moved outside of the update panel if necessary. But I would like to duplicate the form below the original via clicking the Add button. Would also be handy if I could have a remove option as well.
I'm new in using UpdatePanel, I Have 2 DropDownList:
DropDownList_1 and DropDownList_2
where DropDownList_2 content will be dependent to DropDownList_1 selected value, here is my code:
ASPX:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DropDownList_1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList_1_SelectedIndexChanged" DataSourceID="businessgroup" DataTextField="BusinessGroupName" DataValueField="Id"></asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList_1" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
<asp:DropDownList ID="DropDownList_2" runat="server" DataSourceID="jobposition" DataTextField="JobPositionName" DataValueField="Id"></asp:DropDownList>
CS:
protected void DropDownList_1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlDataSource1.SelectCommand = "SELECT DISTINCT * FROM [JobPosition] WHERE BusinessGroupID ="+DropDownList_1.SelectedValue;
DropDownList_2.DataBind();
}
its working as stated above but what I doesn't want in my output is the whole page refreshes, I also tried removing AutoPostBack="true" in my DropDownList_1 but it stops working, what am I doing wrong in here? Thanks!
EDIT:
I also tried moving the DropDownList_2 inside UpdatePanel's ContentTemplate but still the whole page is refreshing.
Here is how you should do:
If you want to refresh the second drop-down, than the second drop-down should be inside an update panel
Set AutoPostBack="true" only for the second drop-down
Set UpdateMode="Conditional" for the update panel (otherwise they will refresh every time)
Set the AsyncPostBackTrigger of the panel to point to the first drop-down SelectedIndexChanged event
Set ChildrenAsTriggers="true" for the Update panel
:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" OnSelectedIndexChanged="DropDownList_1_SelectedIndexChanged" DataSourceID="businessgroup" DataTextField="BusinessGroupName" DataValueField="Id"></asp:DropDownList>
<asp:DropDownList ID="DropDownList_2" runat="server" AutoPostBack="true" DataSourceID="jobposition" DataTextField="JobPositionName" DataValueField="Id"></asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList_1" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
The controls should reside in the same update panel, it's simpler this way.
I found the fix, thanks to Cristina for reminding me to check the console errors. And just for reference to anyone who is having the same problem here is what I've done:
I have missing Ajax libraries, so I imported the MicrosoftAjax.js and MicrosoftAjaxWebService in this folder Scripts>WebForms>MSAjax.
After I imported the necessary Ajax library I've got this console error:
MicrosoftAjaxWebForms.js:6 Uncaught
Sys.WebForms.PageRequestManagerServerErrorException:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes,
this feature verifies that arguments to postback or callback events
originate from the server control that originally rendered them. If
the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to
register the postback or callback data for validation.
What I did is add EnableEventValidation="false" inside this Ajax page, in <%Page %> directive.
And after that I have no longer full page reload and all is working now on how I wanted.
If your panel still posts back after you've set it up as per guidelines, check that you have not set ClientIDMode="Static" either for the specific control performing the callback or by causing the ClientIDMode to default to static inherited from either in web.config, the Page or parent containers.
Search your solution for ClientIDMode="Static" and either change this for inherited controls including the one triggering the postback, or explicitly set ClientIDMode="Predictable" or ClientIDMode="AutoID" for each of your controls that trigger a postback.
While you are working with update panel you have to register your events while refreshing the page for that you have to use Microsoft's PageRequestManager
to re-subscribe every update.
You have to initialize your event in the document.ready(function(){})
of the javascript.
Ex: var test=Sys.WebForms.PageRequestManager.getInstance();
I have 2 pages each with an update panel. It has the same content and the same trigger on both pages.
This is how it looks:
<div id="rating">
<span class="rateTxt">Rate</span>
<telerik:RadRating ID="RadRating1" runat="server" ItemCount="5" SelectionMode="Continuous"
Precision="Item" Skin="Default" OnRate="RadRating1_Rate" AutoPostBack="true">
</telerik:RadRating>
</div>
</li>
</ul>
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div id="divAddMessage" runat="server" visible="false">
<span class="rateTxt">Do you want to add a comment?</span>
<asp:TextBox runat="server" ID="txtComment" TextMode="MultiLine" Rows="3" Width="195">
</asp:TextBox>
<br />
<br />
<asp:ImageButton runat="server" ID="lnkAddComment" ImageUrl="~/App_Themes/123reg/Images/submit-rating.png"
OnClick="lnkAddComment_Click" OnClientClick="showSuccessMessage();" />
<br />
<br />
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="RadRating1" EventName="Rate" />
</Triggers>
</asp:UpdatePanel>
Now when the user rates something with the RadRating the Rate event is triggered which causes a postback.
On the handler for the Rate event I do the following:
protected void RadRating1_Rate(object sender, EventArgs e)
{
divAddMessage.Visible = true;
}
The same code is exactly on 2 pages. On one page it updates the divAddMessage and it becomes visible but on another page it doesn't become visible. Even if I set it to visible on that page when it postback again the Visible property is still false even after setting it to true in the above handler.
I only set the visibily to false in the aspx file and in the above handler I set it to true.
It turns out that I get an error in the javascript console:
Sys.InvalidOperationException: Sys.InvalidOperationException: Could not find UpdatePanel with ID 'ctl00_mainContentPlaceHolder_updatePanel'. If it is being updated dynamically then it must be inside another UpdatePanel.
I have another update panel inside a multiview. But because the active view is not the one with the update panel on postback the update panel isn't rendered.
Check the parent/container elements for divAddMessage. Have they got their Visibility set to false. If so then the child element will always be Visible=false even if you have set it explicitly to true. That's driven me mad in the past.
Just a thought
I had a custom control and had set the Visible property to false on declaration in the aspx file and that was overriding the visibility of any child elements within the control itself.
I'm working on a ASP.NET site with C# code.
Now the trouble starts when I create a custom control programmatically. The control displays in a panel, but when I click one of the buttons of the control it does nothing. If I click them twice, the user control disappears.
Using the debugger, I found that it's doing a postback, which is strange because I tried using buttons and setting the usesubmitbehavior to false; it's still sending postbacks.
Here is where the control is inserted on the default.aspx file
<asp:UpdatePanel runat="server" ID="contentHolderUpdatePanel"
UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel runat="server" ID="contentPanel">
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Here is the ASPX from ListadoAuditoria of the control.
<asp:UpdatePanel runat="server" ID="auditorTableUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Table runat="server" ID="auditorTable" BorderWidth="0" Width="100%">
<asp:TableHeaderRow HorizontalAlign="Center">
<asp:TableHeaderCell>Button
</asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel runat="server" ID="formHolderUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label runat="server" ID="testLabel" Text="bbbbbbbbbbbbb" ></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
The method that the button invokes should change the text of the label testLabel from "bbbbbbbbbbbbb" to "aaaaaaaaaaa". Obviously I'm doing an auditorTableUpdatePanel.Update() after I modify the text.
The control CS
protected void Page_Load(object sender, EventArgs e)
{
loadAudits();
}
public void loadAudits()
{
for(int i=0;i<10;++i)
{
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
ImageButton deleteButton = new ImageButton();
deleteButton.ImageUrl = "~/image.gif";
deleteButton.Click += generateNewPart;
deleteButton.EnableViewState = true;
deleteButton.ID = i.ToString();
cell1.Controls.Add(deleteButton);
row.Cells.Add(cell1);
auditorTable.Rows.Add(row);
}
}
public void generateNewPart(object sender, EventArgs e)
{
tumadre.Text = "aaaaaaaaaaaa";
formHolderUpdatePanel.Update();
}
And here is the code when I generate the control and insert it into the panel:
Panel panel = (Panel)Page.FindControl("contentPanel");
UpdatePanel updatePanel = (UpdatePanel)Page.FindControl("contentHolderUpdatePanel");
ListadoAuditorias listadoAuditorias = (ListadoAuditorias)LoadControl("~/CargaDeAuditoria/ListadoAuditorias.ascx");
panel.Controls.Add(listadoAuditorias);
updatePanel.Update();
I looked over the Internet and didn't found anything.
I'm not sure where exactly the code to dynamically add the controls is, but it must be called on EVERY postback to re-add the controls. You can't just add it once and forget about it. When you postback, the page will re-render with the markup in your aspx page (which does not have your dynamic controls, obviously). The values from the dynamically added controls will still be in ViewState, but the controls will not be re-rendered.
I'm not entirely sure what I'm looking at; I don't know if the "code of the control" is the code for the ListadoAuditorias control that you're loading. If so, I didn't notice any buttons.
So I could be wrong here, but the first thing that pops out at me is that it looks like you're loading the ListadoAuditorias control and then adding it to a normal Panel control. If one of the controls inside of ListadoAuditorias triggers a postback, and it's not contained within an UpdatePanel, then yes, I'd expect the page to do a postback and reload, unless you have specified the ChildrenAsTriggers and UpdateMode properties to be something other than their default values (I think). So I would just suggest that you take a look at where you are adding your controls. Make sure that they're contained within an UpdatePanel, if that's what your intention is.
Also, note that the UseSubmitBehavior property of the Button control does not prevent the button from initiating a postback. That property only determines whether the button gets rendered as <input type="submit" /> or <input type="button" />. In the latter case (when you set UseSubmitBehavior to false) the control still renders javascript in the HTML element's onclick attribute to cause a postback.
EDIT: I've amended my explanation regarding UpdatePanel control to mention the ChildrenAsTriggers and UpdateMode properties.
I need to display a control consistently across a set of pages. So I'm using a MasterPage to do that in ASP.NET/C#. However I also need to programmatically access this control, mostly provide options to view/hide depending on whether the controls checkbox is clicked.
Here is the Source for the MasterPage
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server"
oncheckedchanged="chkInitialVerify_CheckedChanged" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server"
oncheckedchanged="chkContinuousVerify_CheckedChanged" />
I agree that my continuous data is correct
</div>
Now in the code behind I want to perform the following operations. Basically if a person clicks on the checkbox for the initial div box, then the initial box disappears and the continous box shows up. However it seems that the code behind for the MasterPage does not activate whenver I click on the checkbox. Is that just the way MasterPages are designed? I always thought you could do add some sort of control functionality beyond utilizing the Page Load on the Master Page.
protected void chkInitialVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = true;
verifyInitial.Visible = false;
}
protected void chkContinuousVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = false;
}
If you're expecting the two controls to trigger a change for that page immediately then you'll need to set the AutoPostBack property to true for both of them:
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server" oncheckedchanged="chkInitialVerify_CheckedChanged" AutoPostBack="true" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server" oncheckedchanged="chkContinuousVerify_CheckedChanged" AutoPostBack="true" />
I agree that my continuous data is correct
</div>
Otherwise, you need an <asp:button /> or some other control on the page to trigger a postback and cause your event handlers to run. The button, or other control, can either be on your masterpage or on your content page, the choice is entirely yours.