ADF Faces dialog - dialogListener not triggering - javascript

My dialog of type "okCancel" does not trigger any event on the server when the ok button is clicked.
The cancel button is working fine, just hiding the popup.
I'm using Oracle ADF Faces 12.1.3 and JBoss seam 2.3 for injecting beans.
Here is the popup and dialog code :
<af:form id="mainForm">
<af:panelStretchLayout id="psl1">
<!-- page layout -->
</af:panelStretchLayout>
<af:popup id="myPopup"
binding="#{bkBean.myPopup}"
contentDelivery="lazyUncached">
<af:dialog id="myDialog" closeIconVisible="true"
modal="true" okVisible="true" cancelVisible="true"
title="Import from server to #{bkBean.file.name}"
type="okCancel"
dialogListener="#{bkBean.doSomething}">
<af:panelFormLayout id="pfl1">
<!-- Several input text here -->
</af:panelFormLayout>
</af:dialog>
</af:popup>
</af:form>
Here is the code for the dialogListener. I set a debug point at the if statement:
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
#Name("exportImportServer")
#Scope(ScopeType.SESSION)
public class ExportImportServerBean implements Cleanable {
public void importFromServer(DialogEvent event) {
if (event.getOutcome() == DialogEvent.Outcome.ok) {
}
}
}
The exportImportServer backing bean is in session scope.
If I toggle a break point in the first code line inside the exportImportServer backing bean importFromServer method it does not stop inside. This method does not get called. It seems that nothing happens (even I have no errors) except that the main form is submitted.
In debug mode after a click on the ok button I'm able to stop inside a PhaseListener beforePhase(PhaseEvent phaseEvent) method. But I don't really know if the backing bean method should be called after the PhaseListener beforePhase(PhaseEvent phaseEvent) method.
I'm searching for any hint on how could I debug it ?
Is there any javascript called when Ok button is clicked on dialog ?
UPDATE: it seems that the problem comes from the fact that the popup is called from a region of the page and defined in another page (the main page containing the region) as seen in the code below :
Inside main.xthml:
<af:document>
<af:form id="mainForm">
<af:panelStretchLayout id="psl1" topHeight="auto" bottomHeight="0">
<f:facet name="center">
<af:region id="myRegion" showHeader="never"
value="#{main.regionModel}" />
</f:facet>
</af:panelStretchLayout>
</af:form>
<af:popup id="myPopup"
binding="#{bkBean.myPopup}"
contentDelivery="lazyUncached">
<af:dialog id="myDialog" closeIconVisible="true"
modal="true" okVisible="true" cancelVisible="true"
title="Import from server to #{bkBean.file.name}"
type="okCancel"
dialogListener="#{bkBean.doSomething}">
<af:panelFormLayout id="pfl1">
<!-- Several input text here -->
</af:panelFormLayout>
</af:dialog>
</af:popup>
</af:document>
Inside myRegion.xhtml:
<?xml version='1.0' encoding='UTF-8'?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:trh="http://myfaces.apache.org/trinidad/html"
xmlns:tr="http://myfaces.apache.org/trinidad"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:tree ...>
</af:tree>
<!-- Contextual Menu -->
<af:popup id="pp1" contentDelivery="lazyUncached">
<af:menu>
<af:commandMenuItem text="Do something" immediate="true"
rendered="#{bkBean2.isRendered}" icon="icon.png" actionListener="#{bkBean2.showMyPopup}" />
</af:menu>
</af:popup>
</ui:composition>
It works if I define the popup inside myRegion.xhtml but not if I define the popup inside main.xhtml.
Thank you for any hints on how to make it work with the popup defined inside main.xhtml ?

You have two options:
Try mapping your bean in your adfc-config.xml instead of using annotations.
Leave annotations in place and make sure you use enable CDI in your ADF application as below:
http://www.jobinesh.com/2014/08/enabling-cdi-in-adf-applications.html
Worth mentioning that CDI (annotation-based beans) is not being used very often with ADF - at least there is little info about people following CDI approach - so you might be walking on uncharted territory .

Related

Ajax update causes elements created by javascript to be lost in Primefaces

I have in my .xhtml form an element into which I am appending html elements through javascript.
When I trigger an ajax commandButton, these appended elements are lost.
I have tried to exclude this element from my ajax update and make my submit partial (following this practice How to exclude child component in ajax update of a parent component?) , but in vain, the newly added elements are lost after the update takes place.
Is there any way to avoid this? Thanks in advance :)
Code sample:
<h:form id="formID">
<p:commandButton
value="ajax_button" partialSubmit="true"
update="#(#divOfElement :not(.notupdate))"
ajax="true">
<f:actionListener binding="#{myBean.myAction()}"/>
</p:commandButton>
</h:form>
<p:outputPanel id="divOfElement">
<!-- other things i want to be updated-->
<p:outputPanel id="panel_not_to_update"styleClass="notupdate">
<!-- this div is filled with other elements from javascript code which will be destroyed when the ajax update takes place -->
</p:outputPanel>
</p:outputPanel>
Here, I want divOfElement to be updated through the command button in the ajax call, but exclude the div with id panel_not_to_update so it's child elements added through javascript code will not be lost.
I am using JSF 2.2 and Primefaces 7.0.

How to keep objects on JSF Flash Scope after Ajax call or Reload?

I have a 'big' project, big table and a lot of relations... So in my form, I have several tabs, some dialogs, and a lot of PrimeFaces commandButtons to manage all the CRUD with Ajax requests.
The xhtml structure is something like that:
<ui:define name="content">
<h:body>
<p:growl id="growl"/>
<h:form id="formCars" enctype="multipart/form-data">
<p:tabView id="formTabView" scrollable="true" >
<p:tab title="Tab1">
<ui:include src="tabOne/tabOne.xhtml" />
</p:tab>
<p:tab title="Tab2">...</p:tab>
...
<p:tab title="Tab8">...</p:tab>
</p:tabView>
<br />
<div align="center">
<p:commandButton id="cmdSave" value="Save"
action="#{controllerMB.save}" icon="ui-icon-disk"
update="#form :growl" process="#form #this" validateClient="true" />
</div>
</h:form>
<p:dialog header="Car Color" id="modalCarColor" widgetVar="modalCarColor" appendToBody="true" modal="true" height="500" width="700" dynamic="true" closeOnEscape="true" >
<p:ajax event="close" listener="#{controllerMB.closeModalCarColor}" update="#this,:formCarColor"/>
<h:form id="formCarColor">
<ui:include src="tabTwo/carColor/carColor.xhtml" />
</h:form>
</p:dialog>
<p:dialog header="Car Size" ...>
<p:ajax event="close" .../>
<h:form id="formCarColor">...</h:form>
</p:dialog>
</h:body>
</ui:define>
And it works flawlessly...
The problem is when I try to reload the page...
I manage to keep the main object on the flash by using
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep(key)
on the #PostConstruct of the #ViewScoped controller.
If I access the page and dont touch the ajax buttons, I can reload the page without a problem... But, if I do touch anything that causes and ajax request, the JSF Flash Scopre loses the main object, therefore I can't reload the page.
My controller is built this way:
#ManagedBean(name="controllerMB")
#ViewScoped
public class ControllerMB implements Serializable{
// attributes
// ----------
#PostConstruct
public void init(){
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
if(car==null) {
redirect_back();
return;
}
// attributes initialization and form preparation
// -----
}
// methods
// ----------
}
The "car" as main object is just an example.
Is there any solution or workaround for this?
I want to keep the state after an 'accidental reload' but, it is not working with Flash.
Also, is it possible to capture/handle the reload event from browser (maybe with js)? I mean, then I could process the form in my main object before reload.
I'm using PrimeFaces 5.3, JSF 2, Maven, Tomcat 7 and Java 7 in my project.
Thank you all in advance.
Edit 1: After trying the solution mentioned by the user NightEagle, it almost worked... I modified the code:
<ui:composition ....>
<f:metadata>
<f:event type="preRenderView" listener="#{controllerMB.preRender}"/>
</f:metadata>
<ui:define name="title">...</ui:define>
<ui:define name="header">...</ui:define>
<ui:define name="content">...</ui:define>
</ui:composition>
and
public void preRender()
{
System.out.print("PRE-RENDER ");
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
System.out.println("KEEP");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
} else {
System.out.println("PUT");
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car",car);
}
}
The weird thing is, the first ajax call is good, after the second... it starts popping the JSF1095 error.
The output after some dialogs openings:
PRE-RENDER PUT
PRE-RENDER KEEP
PRE-RENDER KEEP
Jul 14, 2017 11:43:59 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:00 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:04 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
Thank you all in advance, still finding a solution.
I think that i know how to resolve it (it helped me in my project)
<f:metadata>
<f:event type="preRenderView" listener="#{myBean.preRender}"/>
</f:metadata>
backed bean:
public class MyBean
{
#PostConstruct
public void init(){
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
}
public void preRender()
{
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
}
}
"The preRenderView event is invoked on every HTTP request (yes, this also includes ajax requests!)." (c) https://stackoverflow.com/a/9844616/3163475

Can use AjaxStatus while The next Page Is Loading?

Im developing a SW Application. I have been for several time trying to show a modal between the transition of my xhtml pages. I dont want the user can push many buttons or repeat pushing while the next screen is loading.
First i tried it putting an overlayPaneltrying to cover the full screen but i found this problem:
p:overlayPanel Full Screen
Then, I tried it using blockUI blocking the whole body of my page, but then I found this other problem:
p:blockui disable ajax
Finally, I really thought that i got it, using a JS function but then I had this problem (basically the problem is that it dont works with the dataTable):
onstart and oncomplete dont work in datatable with p:commandLink
Thank U In Advice!!!!
to make an ajaxStatus try to make it like that (do not forget that the ajaxStatus is invoked each time you use a p:ajax that mean in your dataTable you need to add an ajax event when you try to invok it )
mypage.xhtml
<p:ajaxStatus onstart="PF('statusDialog').show()" onsuccess="PF('statusDialog').hide()" />
<h:form id="form">
...
</h:form>
<p:dialog widgetVar="statusDialog" modal="true" draggable="false" closable="false" resizable="false" showHeader="false">
<p:graphicImage name="ajaxloadingbar.gif" library="images/myIcons" />
</p:dialog>
Hope that helped you

Set default value inputText jsf with javascript [duplicate]

I have a JSF 2 application that has two pages, one to list students and one to show details of a given student. The listing page has a link to the details page in each row of the students table, that opens a new tab in browser to show those details, when clicked.
Now the requirements changed to no more show details in a new tab, but in a modal dialog in the listing page.
My idea is to simply embed the details page content in the modal dialog so the listing page will not get too big and hard to maintain. Here start my doubts. After some research I changed the link in each row of the listing to the following button:
<p:commandButton value="Details" type="button"
onclick="PF('dialog-details').show()">
</p:commandButton>
The dialog is declared as follows:
<p:dialog widgetVar="dialog-details" header="Details" modal="true" width="95%">
<ui:include src="student_details.xhtml">
<ui:param name="id" value="#{student.id}"/>
</ui:include>
</p:dialog>
Finally, the details page was changed to be something like this:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:viewParam name="id" value="#{studentBean.id}" />
</f:metadata>
<h1 class="title ui-widget-header ui-corner-all">Details of #{studentBean.bean.name} / #{studentBean.bean.number}</h1>
</ui:composition>
When I click the button, the dialog really shows and the content is the details page. I see the following content in the dialog:
Details of /
No errors at all, but the data that should be shown, isn't. A breakpoint was set in StudentBean.setId() (this method loads a property named bean with the Student instance corresponding to the passed id) but it is never hit.
After some time thinking about it, I came to understand why it does not work. The parameter passed to the details page is student.id, but student is the name used as the var in the <p:datatable/> that show all the students, so student is not valid in <p:dialog/> which is outside the <p:datatable/>.
So, what I need is a way to show the dialog using the id of the corresponding student in a given row. Ideally, I would like an ajax call here, so the details would loaded only when neded.
Any ideas?
The button should be an ajax button which sets the currently iterated entity in the bean, and then updates the dialog's content, and finally shows it. The dialog should just reference that entity in the bean and update the list and table on save. It's very important that dialog is placed outside the main form and that it has its own form.
Here's a kickoff example:
<h:form id="master">
<p:dataTable value="#{bean.entities}" var="entity">
<p:column>#{entity.property1}</p:column>
<p:column>#{entity.property2}</p:column>
<p:column>#{entity.property3}</p:column>
...
<p:column>
<p:commandButton value="View" action="#{bean.setEntity(entity)}"
update=":detail" oncomplete="PF('detail').show()" />
</p:column>
</p:dataTable>
</h:form>
<p:dialog id="detail" widgetVar="detail">
<h:form>
<p:inputText value="#{bean.entity.property1}" />
<p:inputText value="#{bean.entity.property2}" />
<p:inputText value="#{bean.entity.property3}" />
...
<p:button value="Close" onclick="PF('detail').hide(); return false" />
<p:commandButton value="Save" action="#{bean.save}"
update=":master" oncomplete="if(!args.validationFailed) PF('detail').hide()" />
</h:form>
</p:dialog>
With this inside a #ViewScoped bean:
private List<Entity> entities; // +getter
private Entity entity; // +getter+setter
#EJB
private EntityService entityService;
#PostConstruct
public void load() {
entities = entityService.list();
entity = null;
}
public void save() {
entityService.save(entity);
load();
}
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Creating master-detail table and dialog, how to reuse same dialog for create and edit
Keep p:dialog open when a validation error occurs after submit
Difference between rendered and visible attributes of <p:dialog>
How to display dialog only on complete of a successful form submit

jsFunction's data is undefined when event starter is inside the form

here is my situation:
I'd like to test if anyway to link the java bean and xhtml, so I use the richfaces, a4j:jsFunction to deal it.
I succeed -- in some limit, that the event starter have to fire OUTSIDE the form, so WEIRD !!
there are 3 parts in my code: xhtml、js、java
xhtml:
<button id="succeed" onclick="showMessage()"> succeed_test </button>
<!-- this is the succeeded button -->
<h:form id="form1" prependId="true" >
<button id="fail" onclick="showMessage()"> fail_test </button>
<!-- this is the failed button -->
<a4j:jsFunction
name="showMessage"
data="#{javaBeanTest.showThings()}"
oncomplete="presentData(data)"
immediate="true" />
</h:form>
js:
function presentData(data){
alert(data);
}
java:
#Name("javaBeanTest")
public class JavaBeanTest implements Serializable{
public boolean showThings(){
System.out.println("--JavaBeanTest.showThings()");
return true;
}
}
when clicking the 「succeed_test」 button, I got a 「true」 alert and 「--JavaBeanTest.showThings()」 on console, but only got 「undefined」 alert and 「--JavaBeanTest.showThings()」 on console while clicking 「fail_test」 button.
obviously the DIFFERENCE is of inside or outside the form .....
CONFUSED !!!! PLEASE !!!
ps.in my richfaces version, it works with 「data」 instead of 「event.data」, should be 3.x
JDK 1.6
JBDS 4.1.0GA
seam 2.2
JSF 1.2
In your case HTML button submits the form if it is inside of one (behavior may differ from browser to browser). You need to specify explicitly the button type or prevent default submit behavior, e.g.:
<button id="fail" type="button" onclick="showMessage()">does not fail anymore</button>
or
<button id="fail" onclick="showMessage(); return false;">does not fail anymore</button>
There is a recommendation by W3C to always specify the type attribute:
Tip: Always specify the type attribute for the element.
Different browsers may use different default types for the
element.
Refer to: http://www.w3schools.com/tags/att_button_type.asp

Categories

Resources