custom usercontrol content in UpdatePanel disappears on button click postback - visual-studio

I have the following function that updates the UpdatePanel content by adding/loading an ascx custom usercontrol in the placeholder that is in default.aspx:
protected void NavigationTab_Click(string ascxpath)
{
Control ctrl = LoadControl(ascxpath);
//cphmaincontent is my asp ContenPlaceHoderId in masterpage
PlaceHolder phmaincontent = (PlaceHolder)cphmaincontent.FindControl("phmaincontent");
phmaincontent.Controls.Clear();
phmaincontent.Controls.Add(ctrl);
upmaincontent.Update();
}
Masterpage UpdatePanel:
<asp:UpdatePanel ID="upmaincontent" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lbmsg" runat="server" Text=""></asp:Label>
<asp:ContentPlaceHolder ID="cphmaincontent" runat="server">
</asp:ContentPlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
I am calling NavigationTab_Click from my navigation control that is another custom ascx control, my ctrl Control object that is loading dynamically on each has button and label when I click the button it simply reassigns some text to the label.
and I have this following code on my masterpage just to get the ascx control path:
protected override void OnInit(EventArgs e)
{
//raising an event to set ascx path
mainmenu.NavigatePath += new usercontrols.mainmenu.NavigationHandler(NavigationTab_Click);
base.OnInit(e);
}
so far everything works good, after loading my ctrl object by calling NavigationTab_Click function I see my ctrl in the placeholder and has the button and the label but the issue is this if I click this button it should reassign the label to some text but instead the whole ctrl control content disappears, please help.

When you're adding controls dynamically you must ensure that it gets recreated on every postback. You also have to ensure that you assign the same ID as before, otherwise events will not be triggered correctly and values cannot be reloaded from ViewState. This must be done it Page_Load at the latest(better in Page_Init).
That's the reason why you should avoid dynamical controls whenever possible.
So you can add controls in event-handlers like you've done. But they must be recreated on the next Postback. So you need to store somewhere what(f.e. IDs) or how many controls are already created. That can be done for example in ViewState or Session. Then you can assign appropriate IDs to the controls(for example with the index or ID suffixed).
Here are some additional informations on this subject:
View State and Dynamically Added Controls *
ASP.NET Page Life Cycle Overview

Related

Popupextender disappears after postback in Usercontrol

Dear Fellows i have a usercontrol which takes destination details from users with multiple dropdownlist controls...
e.g. Country Dropdownlist produces postback and populate states dropdownlist based on select values. State's Dropdownlist produces postback to get cities based on states.Furthermore everything happens in an Ajax UpdatePanel.
--Select--
I'm using this control in popupextender to be displayed. Each time dropdownlist postback popupcontrol disappears. Please help me with that
<asp:Panel ID="pnlhotelsearch" runat="server">
<div>
</div>
<uc1:SlimMainsearchpanel ID="SlimMainsearchpanel1" runat="server" />
</asp:Panel>
<ajaxToolkit:PopupControlExtender ID="PopupControlExtender1" TargetControlID="lnkbtnCriteriea" PopupControlID="pnlhotelsearch" runat="server">
</ajaxToolkit:PopupControlExtender>
There are several suggestions at ASP.net Modal Pop up extender and DropDownlist autopostback.
The way I solved it was to raise a new event, say DropDownChangedEvent, in the AutoPostBack event handler. The handler for the new DropDownChangedEvent calls PopupExtender.Show.

apex:actionFunction and Database.Update() unintended page refresh

So, I've been working on an "edit item" modal for a visualforce page that will allow the user to edit a child component of an object, and refresh the page. As it stands, there is a single URL parameter that contains the parent objects ID. The code is structured very similar to this:
<apex:form id="edit-modal">
<!-- Modal Content-->
<apex:actionFunction action="{!updateModalObject}" name="updateModalObject">
</apex:actionFunction>
</apex:form>
When the user preses a "save" button in the modal, the aforementioned actionfunction is called. The class in the controller looks like this:
public PageReference updateModalObject(){
database.update(modalObject);
return null;
}
When this action completes, the page is refreshing, also dropping the URL parameters and causing the whole thing to sort of.. gum up. I'm not sure which portion of the code is causing the refresh, if it's the actionfunction or if it's the update in the controller.
You said:
When the user preses a "save" button...
I think this is causing the page refresh. Do you use the command button without reRender tag? The solution might look like this:
Just try this trick out - add return false after executing your JavaScript function:
<apex:commandButton value="Save" onclick="updateModalObject(); return false;"/>
Other way to avoid page reload is to add a dummy reRender tag:
<apex:commandButton value="Save" onclick="updateModalObject()" reRender="none" />
or
<apex:actionFunction action="{!updateModalObject}" name="updateModalObject" reRender="none">
You must to re-render "something" to avoid the page reload. Otherwise the command button will reload the whole page. In our case we will re-renden "nothing".

Create PrimeFaces dialogs dynamically

I'm using primefaces 3.3.1 and JSF 2 (Mojarra 2.1.9).
I have a page with a DataTable component and Dialog to show details of DataTable entries. That's very simple when I have one dialog. What I want is to try to allow users to open two or three dailogs with details of different entries in the same time. Does somebody have any idea how to get whole dialog with AJAX from server, not just a dialog content?
Yes I did. For this purpose I created necessary dialogs programmatically in backing bean. I know this is not really best practice, but in this moment I think this is only possible solution. First of all I added one group panel which is container for dialogs on my JSF page. Then on backing bean I have some code like this:
UIComponent panelGroup = facesContext.getViewRoot().findComponent("panel_id");
Dialog dialog = new Dialog();
dialog.setHeader("Sample");
dialog.setVisible(true);
dialog.setMinimizable(true);
...
panelGroup.getChildren().add(dialog);
...
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("panel_id");
Dialog id also can be dynamic so you can create some id or some other value and give it him.
<p:dialog header="Choose Delimiter Type" id="dialog"
widgetVar="exportDialog#{p.Id}" resizable="false" >
and calling via button ;
<p:commandButton id="id" value="xxx"
actionListener="#{p.export2CSV}" ajax="false"
onclick="exportDialog#{p.tabId}.show()">
</p:commandButton>
#newuserua Your code is not working widgetVar value is setted only once when page load
...
requestContext.update("panel_id");
the above line updated complete panel its refreshing all the existing dialog and its contents.

In JSF on an ajax call, how do we create a HTML fragment using a different JSF page for rendering?

I have a JSF page in which I have a div which acts as a popup window.
This popup is displayed when the user clicks on a certain button or link, until which it is hidden.
I would like to have another JSF page that provides the content for this div via an AJAX call.
I vaguely remember doing this using Struts Action and JSP fragment.
Is it possible to do this in JSF 2.0?
ADDITIONAL DETAILS:
My scenario is as follows:
I have a page that displays the details of employees as a summary table using the dataTable tag with a class EmployeeInfo as a backing bean that provides a Collection of EmployeeBeans. On this page I have a radio button as the first column in the dataTable. This page has a div that is hidden.
When the radio button is switch on and a certain button is clicked, over an AJAX call we need to hit the backing bean to get the details of the EmployeeBean that has been selected as above and populate the div based on this AJAX call.
The reason why I do not want to have a full submit on the first page and get the second page is, because I want to save the state of any changes that have been done on the first page.
Using a tag, you are able to show or hide content quite easily. This is all rough code typed out quickly but in your bean, imagine you had the following:
public class MyBean {
public boolean renderHidden = false;
public void toggleHidden(AjaxBehaviorEvent event) {
renderHidden = !renderHidden;
}
}
Then in your JSF page, you'd have a link to show hide your popup done as a ui:fragment:
<h:commandLink value="Click Me!">
<f:ajax event="click" listener="#{myBean.toggleHidden}" render="hiddenarea" />
</h:commandLink>
<ui:fragment id="hiddenarea" rendered="#{myBean.renderHidden}">
<div><!-- Content to show/hide here --></div>
</ui:fragment>
That ui:fragment could easily be in another JSF page that you include via ui:include if you need it to be. The important bit is that the f:ajax take is what makes the AJAX call (on a click event in this case) and updates the specified element (hiddenarea).

Primefaces Change menu entry via ajax an rerender content on full layout

I am trying to get a simple full layout to work with a navigation on the left side.
That works but I want to reload the center (content) via ajax on menu item selection.
The reason is, that I have a MP3 player on the right side and if the whole page reloads the mp3 player
start the playback again.
On Richfaces I did that with a session bean which holds the actual filename that needs to be rendered in the center
and on menu click the action method analyses the menu entry ID and sets the filename to its corresponding.
Actually that works a little bit for primefaces as well, but the content doesn't render correctly. After punshing F5
it is perfect.
Does anybody can give me a real simple example how I can do that?
Many greetings,
Hauke
I have never use menuitem but with commandButton I just use 'update' notation to refresh the form located in the center content via ajax.
On navigation layoutUnit
<p:commandButton
value="Enter"
image="ui-icon ui-icon-comment"
update="form_input_console form_output_console:tabbed_contents"
actionListener="#{dashboardUi.processCommand}" />
and on the center layout unit
<p:layoutUnit position="center">
<h:form id="form_output_console">
<p:tabView
id="tabbed_contents"
dynamic="true">

Resources