Programmatically Created Dialog Refuses To Display

UI Components for JSF
Post Reply
dartmanx
Posts: 18
Joined: 05 Apr 2012, 13:17

03 May 2012, 16:56

I have programatically created a Dialog component which I am attempting to add to a form on my index.xhtml page in my ManagedBean (which is set at Session scope). As mentioned in previous posts, I am trying to defer the creation of these dialogs until they are actually needed.

The dialog is supposed to be launched from a MenuItem action method in the index.xhtml file:

Code: Select all

					<p:menuitem id="menuItemManager" value="Manager"
						action="#{managerBean.launch}" oncomplete="dlgManager.show()"/>
This is supposed to update a section in the same file:

Code: Select all

		<p:layoutUnit id="mainPageCenter" position="center">
			<h:form id="mainPageCenterForm" binding="#{baseBean.form}">

			</h:form>
		</p:layoutUnit>
The launch method on the manager bean is called successfully. Here is the actual code:

Code: Select all

	public void launch() throws IOException {

	
		FacesContext fctx = FacesContext.getCurrentInstance();
		
		FaceletFactory factory = ApplicationAssociate.getInstance(fctx.getExternalContext()).getFaceletFactory();
		Facelet managerFacelet = factory.getFacelet("/WEB-INF/facelets/dialog/Manager.xhtml");
		
		//Dialog dialog = new Dialog();
		Dialog dialog = (Dialog) fctx.getApplication().createComponent(fctx, Dialog.COMPONENT_TYPE, "org.primeface.component.dialog.DialogRenderer");
		
		managerFacelet.apply(fctx, dialog);
		
		dialog.setId("ManagerDialog");
		dialog.setWidgetVar("dlgManager");
		dialog.setHeader("Application Manager");
		dialog.setWidth("660");
		dialog.setHeight("320");
		dialog.setVisible(true);
	
		form.getChildren().clear();
		form.getChildren().add(dialog);
	
		RequestContext.getCurrentInstance().update("mainPageCenterForm");
	}
Obviously I wouldn't be posting if it worked...

Following it in firebug, an Ajax call is mae (as a POST) to index.xhtml. The response is this:

Code: Select all

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><update id="mainPageCenterForm"><![CDATA[
<form id="mainPageCenterForm" name="mainPageCenterForm" method="post" action="/index.xhtml">
<input type="hidden" name="mainPageCenterForm" value="mainPageCenterForm" />

</form>]]></update><update id="javax.faces.ViewState"><![CDATA[1085527968780930835:794424633460843413]]></update></changes></partial-response>
Next, Firebug shows an error:

Code: Select all

dlgManager is not defined
Well, no kidding on the last, the dialog was apparently not attached to the form so of course the manager was not defined.

Can anyone point out if I'm just making a dumb mistake?
Primefaces 3.2
Mojarra 2.0.9
Weblogic 10.3.6

Hamsterbau
Posts: 409
Joined: 28 Dec 2011, 17:44

03 May 2012, 18:59

Code: Select all

#{managerBean.launch}

Code: Select all

#{baseBean.form}
Looks crazy, because you have used form instance in managerBean, but your binding of that form leads to baseBean :?
Primefaces 8.0.7 (PF Extensions 8.0)
JSF: Mojarra 2.3.2 (Spec 2.3) - running on WildFly 22

dartmanx
Posts: 18
Joined: 05 Apr 2012, 13:17

03 May 2012, 19:42

Sorry, left something out.

The ManagerBean extends the BaseBean. This allows it to have a reference to any components bound to BaseBean, such as the form. Here's some more code:

Code: Select all

@Named("baseBean")
@Scope("session")
public class BaseBean implements Serializable {

    protected UIForm form;

}
and

Code: Select all

@Name("managerBean")
@Scope("session")
public class ManagerBean extends BaseBean implements Serializable {

  // launch method that references form as defined in BaseBean

} 
Primefaces 3.2
Mojarra 2.0.9
Weblogic 10.3.6

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

03 May 2012, 20:28

Code: Select all

binding="#{baseBean.form}"
Looks really creasy. Why do you need binding? If you need binding, make sure your bean is requestScoped! Only requestScoped beans work fine with binding.

The second strange thing you have - you try to add dialog to the form. Try to have dialog with form inside (in XHTML) and only add content to this (e.g. UIPanel) programmatically.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

Hamsterbau
Posts: 409
Joined: 28 Dec 2011, 17:44

03 May 2012, 20:49

Oleg wrote:

Code: Select all

binding="#{baseBean.form}"
Looks really creasy. Why do you need binding? If you need binding, make sure your bean is requestScoped! Only requestScoped beans work fine with binding.

The second strange thing you have - you try to add dialog to the form. Try to have dialog with form inside (in XHTML) and only add content to this (e.g. UIPanel) programmatically.
Dialog in a form should work as well. And bindings in a session scoped beans are fine. No need to change that, or did i miss something?

But what is new to me, that you can bind a bean twice (under different names). I would prefer to inject all needed beans (@ManagedProperty), to have a good coffee :)

To your problem: i have no clue what went wrong. Perhaps the "workaround" from Oleg works (form in a dialog).
Primefaces 8.0.7 (PF Extensions 8.0)
JSF: Mojarra 2.3.2 (Spec 2.3) - running on WildFly 22

dartmanx
Posts: 18
Joined: 05 Apr 2012, 13:17

03 May 2012, 22:10

Okay, it seemed to work when I removed the binding (which was an artifact of a team member's ideas on what components should be bound). I can now get a dialog to load dynamically and pop up via this code:

Code: Select all

	public void launch() throws IOException {
	
		FacesContext fctx = FacesContext.getCurrentInstance();
		
		FaceletFactory factory = ApplicationAssociate.getInstance(fctx.getExternalContext()).getFaceletFactory();
		Facelet retainManagerFacelet = factory.getFacelet("/WEB-INF/facelets/dialog/manager.xhtml");
		
		Dialog dialog = (Dialog) fctx.getApplication().createComponent(fctx, Dialog.COMPONENT_TYPE, "org.primeface.component.dialog.DialogRenderer");
		
		managerFacelet.apply(fctx, dialog);
		
		dialog.setId("ManagerDialog");
		dialog.setWidgetVar("dlgManager");
		dialog.setHeader("Manager");
		dialog.setWidth("660");
		dialog.setHeight("320");
		dialog.setVisible(true);
		
		UIViewRoot rootView = fctx.getViewRoot();
		UIForm form = (UIForm) rootView.findComponent("mainPageCenterForm");
		form.getChildren().clear();
		form.getChildren().add(dialog);
	
		RequestContext.getCurrentInstance().update("mainPageCenterForm");
	}
Unfortunately, it's not rendering the child components of the dialog as defined in manager.xhtml, but I'll keep working on it.
Primefaces 3.2
Mojarra 2.0.9
Weblogic 10.3.6

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

03 May 2012, 22:19

And bindings in a session scoped beans are fine. No need to change that, or did i miss something?
bindings in a session scoped beans is not good. Scope of component is narrower than session. They are view scoped as far as I know. It's similar if you would reference a view scoped bean in a session scoped bean. Dangerous.
Unfortunately, it's not rendering the child components of the dialog as defined in manager.xhtml
In the other post you said it works. I had shown there a little bit another code to get FaceletFactory, not Mojarra specific as you use.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

dartmanx
Posts: 18
Joined: 05 Apr 2012, 13:17

03 May 2012, 22:30

The reason the dialogs are inside the form is a brute-force attempt to prevent <h:form> elements from being nested. It would probably be find the other way as long as we were careful about the nesting.

As I said, this is a brute-force method that only works because when I open a new dialog, I programatically clear out the form. Putting the <h:form> inside the dialog is workable, but extra effort has to be made to ensure that forms don't nest by accident. It's probably better in fact, I just haven't gotten there yet.

The method shown was the only was I found to get a FaceletFactory that was not null.
Primefaces 3.2
Mojarra 2.0.9
Weblogic 10.3.6

Hamsterbau
Posts: 409
Joined: 28 Dec 2011, 17:44

04 May 2012, 10:34

Oleg wrote:bindings in a session scoped beans is not good. Scope of component is narrower than session. They are view scoped as far as I know. It's similar if you would reference a view scoped bean in a session scoped bean. Dangerous.
You are right, found the following part mentioned in a stackoverflow-thread:
See JSF 2.0 spec section 3.1.5 "... It is strongly recommend that application developers place managed beans that are pointed at by component binding expressions in "request" scope, and not any other scope. This is because placing it in session or application scope would require threadsafety, since UIComponent instances depends on running inside of a single thread. There are also potentially negative impacts on memory management when placing a component binding in "session" or "view" scopes ..."
Thanks a lot.
Primefaces 8.0.7 (PF Extensions 8.0)
JSF: Mojarra 2.3.2 (Spec 2.3) - running on WildFly 22

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 23 guests