Richfaces inputText onBlur and commandButton onClick - jsf

I have a page with two text fields and a commandButton, in one of the text field onBlur i'm calling onBlur() method in the bean and in the commandButton i'm calling onClick() method in the bean, every thing works fine except when i click the commandButton if the focus is on the text box with onBlur then only the onBlur method been called not both. I've attached the xhtml file and bean.
XHTML Code
<h:inputText id="service" value="#{onBlurTestBean.service}">
<a4j:support status="test" event="onblur"
action="#{onBlurTestBean.onBlur}" reRender="category" />
</h:inputText>
<a4j:htmlCommandLink id="submit" action="#{onBlurTestBean.onClick}"
ajaxSingle="true" value="Click!" />
Bean
public class OnBlurTestBean {
private String service;
private String category;
public void initialize(){
}
public void onBlur(){
log("onBlur");
try{
Thread.sleep(1000);
}catch(Exception e){
}
}
public void onClick(){
log("OnClick");
}
public void log(String msg){
System.out.println(msg);
}
}

The specified example in question works OK (both methods are invoked onBlur and onClick).
In you case it seems you have a4j:status component which blocks user clicks (for example covers the layout with invisible div).
To verify my assumption, try the following (status attribute removed, a4j:region added):
<a4j:region>
<h:inputText id="service" value="#{onBlurTestBean.service}">
<a4j:support event="onblur"
action="#{onBlurTestBean.onBlur}" reRender="category" />
</h:inputText>
</a4j:region>
<a4j:htmlCommandLink id="submit" action="#{onBlurTestBean.onClick}"
ajaxSingle="true" value="Click!" />

Related

Not able to update "growl" in template from Backing bean [duplicate]

In a backing bean's #PostConstruct method, I make a call to an EJB which might return some messages that I want to display on the page via p:messages. However, even if I add the FacesMessages e.g. FacesContext.getCurrentInstance().addMessage(...), p:messages is not being updated with the FacesMessages.
If I instead invoke the call to the EJB on an action from the page (say a user clicks a button on the page which invokes a method that calls the EJB and then adds the FacesMessage(s)), then the messags show up using p:messages as expected.
How do I add Faces Messages during #PostConstruct and have them show up when the page is initially rendered?
Code:
Page1Controller.java:
#ManagedBean
public class Page1Controller
{
#PostConstruct
public void init()
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from #PostConstruct"));
}
public String getValue()
{
return "Some Value";
}
public void triggerMessage(ActionEvent event)
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from Trigger Button"));
}
}
page1.xhtml
<h:form>
<p:messages showDetail="true" showSummary="true" autoUpdate="true"/>
<h:outputText value="#{page1Controller.value}"/>
<br/>
<p:commandButton value="Trigger Message"
actionListener="#{page1Controller.triggerMessage}"/>
</h:form>
That can happen when the message component is rendered before the message is added.
In your specific example, the bean is referenced for the first time by the <h:outputText> component and thus constructed for the first time at that moment. But the <h:outputText> component appears in your specific example after the <p:messages> component, so the <p:messages> component is already rendered and thus it's too late to show the message.
You need to make sure somehow that the message is added before the message component is rendered. One way is using <f:viewAction>. It runs during INVOKE_APPLICATION phase which is before RENDER_RESPONSE phase. Thus it runs before any component is rendered. A perfect opportunity thus.
<f:metadata>
<f:viewAction action="#{bean.onload}" />
</f:metadata>
public void onload() {
// Add message here instead of in #PostConstruct.
}
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
You can collect the error and then display it at the end of loading the page using a remoteCommand of primefaces with autorun = true mode.
In my case I have a viewScope and in xhtml I show the list of values that are loaded in the #PostConstruct. If an Exception is generated I will save it to the sample at the end of the page load if it exists using the remoteCommand.
private ArrayList<Exception> postConstucError = new ArrayList<>();
#PostConstruct
public void validarAcceso() {
/**
* verificar permisos a la vista de coeficientes
*/
try {
this.init() //load data;
} catch (Exception e) {
System.out.print(e.getMessage());
this.postConstucError.add(e);
}
}
public void showPostConstructError() {
try {
for (int i = 0; i < this.postConstucError.size(); i++) {
JsfUtil.addErrorMessage("Error al cargar datos iniciales: " + postConstucError.get(i).getMessage());
}
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: showPostConstructError() " + e.getMessage());
}
}
xhtml code
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
<h:form>
<p:remoteCommand id="rcomerror" name="showError" process="#this" autoRun="true"
actionListener="#{mBPresentNinos.showPostConstructError()}" />
</h:form>
For me using preRenderView event to display message on form init was a messages-hell. So I created very simple "component" to keep static messages. For this example only one error message is supported.
staticMessage.xhtml:
<ui:fragment xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
rendered="#{rendered}">
<div id="staticMessage" class="ui-messages ui-widget" aria-live="polite">
<div class="ui-messages-error ui-corner-all"><span class="ui-messages-error-icon"/>
<ul>
<li>
<span class="ui-messages-error-summary">#{value}</span>
</li>
</ul>
</div>
</div>
</ui:fragment>
Including messages:
<ui:include src="/template/components/staticMessage.xhtml">
<ui:param name="rendered"value="#{beanMB.staticMessagesRendered}"/>
<ui:param name="value" value="Place your message here."/>
</ui:include>

How to call popup based on a condition in richfaces?

I am trying to understand popup menu in richfaces. I am trying to do the following: I have a textbox and a button. I write some text into the textbox, and if the value of the text written is "popup", i want to call the popup menu. Here is the code:
<h:form>
<h:inputText value="#{popupCall.text}"></h:inputText>
<a4j:commandButton action="#{popupCall.showpopup()}" onclick="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();">
</a4j:commandButton>
</h:form>
<rich:popupPanel id="popup" modal="false" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="Popup panel" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('popup')}.hide();
return false;">
X
</h:outputLink>
</f:facet>
</rich:popupPanel>
and the bean:
#ManagedBean (name="popupCall")
#VievScoped
public class PopupCall {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public PopupCall() {
}
public void checkText(){
if(text.equals("popup")){
//CALL POPUP MENU
}
}
public boolean showpopup(){
if(text!=null && text.equals("popup"))
return true;
else
return false;
}
}
If i don't put "if(#{popupCall.showpopup()})" inside the onclick method it always calls when button is pressed but now even though the showpopup()method returns true no popup is shown. Also, inside the showpopup() method, if i just write return true, the if statement inside onclick works but now it does not.
Can anyone help me with this? Thanks
For your case you want to use oncomplete instead of onclick since you want to show <rich:popupPanel> after executing some business logic. When I changed
onclick="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();"
to
oncomplete="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();"
The pop up showed up. Also be careful with
action="#{popupCall.showpopup()}"
Remember that action needs String (or null) for navigation but
showpopup() is returning a boolean so you might want to fix that.
I found these links to be helpful check them out (for the first link, I liked the one with the highest vote).
Primefaces onclick and onsuccess differences
EL expression inside p:commandButton onclick does not update/re-render on ajax request?

Several select menus with a4j support, only the last one works

I have several forms like this on the same page:
<h:form>
<h:selectOneMenu value="#{collectionBean.selectedCollection}">
<f:selectItems value="#{collectionBean.collectionItems}" />
<a4j:support event="onchange" />
</h:selectOneMenu>
<a4j:commandButton value="Add" action="#{collectionBean.addToCollection(_resource)}" >
</a4j:commandButton>
</h:form>
Here is my Bean:
#Name("collectionBean")
#Scope(ScopeType.SESSION)
public class CollectionBean {
private String selectedCollection;
public String getSelectedCollection() {
return selectedCollection;
}
public void setSelectedCollection(String collectionName) {
selectedCollection = collectionName;
}
public List<SelectItem> getCollectionItems() {
...
}
public void addToCollection(Resource res) {
...
}
}
A form is associated to a resource _resource, its goal is to let the user add the resource to a collection he choses.
The problem is that only the last form on the page works: when changing the selection in the other forms, the setSelectedCollection method is never called.
Do you have an idea of what could be wrong?
As said here and in the comments, it does not make sense to bind several components to the same bean property. So I used a Map in the backing bean, with the resource id as a key.
<h:selectOneMenu value="#{collectionBean.selections[_resource.id]}">
<f:selectItems value="#{collectionBean.collectionItems}" />
<a4j:support event="onchange" />
</h:selectOneMenu>
Still, it did not fix the main problem: only the last form on the page worked. For all the other forms, the method getSelections was never called.
Then, instead of using several forms (one form for each select menu), I used a single englobing form. I don't know why, but it worked...

How can I add FacesMessage during page load? Using #PostConstruct does not seem to work

In a backing bean's #PostConstruct method, I make a call to an EJB which might return some messages that I want to display on the page via p:messages. However, even if I add the FacesMessages e.g. FacesContext.getCurrentInstance().addMessage(...), p:messages is not being updated with the FacesMessages.
If I instead invoke the call to the EJB on an action from the page (say a user clicks a button on the page which invokes a method that calls the EJB and then adds the FacesMessage(s)), then the messags show up using p:messages as expected.
How do I add Faces Messages during #PostConstruct and have them show up when the page is initially rendered?
Code:
Page1Controller.java:
#ManagedBean
public class Page1Controller
{
#PostConstruct
public void init()
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from #PostConstruct"));
}
public String getValue()
{
return "Some Value";
}
public void triggerMessage(ActionEvent event)
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from Trigger Button"));
}
}
page1.xhtml
<h:form>
<p:messages showDetail="true" showSummary="true" autoUpdate="true"/>
<h:outputText value="#{page1Controller.value}"/>
<br/>
<p:commandButton value="Trigger Message"
actionListener="#{page1Controller.triggerMessage}"/>
</h:form>
That can happen when the message component is rendered before the message is added.
In your specific example, the bean is referenced for the first time by the <h:outputText> component and thus constructed for the first time at that moment. But the <h:outputText> component appears in your specific example after the <p:messages> component, so the <p:messages> component is already rendered and thus it's too late to show the message.
You need to make sure somehow that the message is added before the message component is rendered. One way is using <f:viewAction>. It runs during INVOKE_APPLICATION phase which is before RENDER_RESPONSE phase. Thus it runs before any component is rendered. A perfect opportunity thus.
<f:metadata>
<f:viewAction action="#{bean.onload}" />
</f:metadata>
public void onload() {
// Add message here instead of in #PostConstruct.
}
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
You can collect the error and then display it at the end of loading the page using a remoteCommand of primefaces with autorun = true mode.
In my case I have a viewScope and in xhtml I show the list of values that are loaded in the #PostConstruct. If an Exception is generated I will save it to the sample at the end of the page load if it exists using the remoteCommand.
private ArrayList<Exception> postConstucError = new ArrayList<>();
#PostConstruct
public void validarAcceso() {
/**
* verificar permisos a la vista de coeficientes
*/
try {
this.init() //load data;
} catch (Exception e) {
System.out.print(e.getMessage());
this.postConstucError.add(e);
}
}
public void showPostConstructError() {
try {
for (int i = 0; i < this.postConstucError.size(); i++) {
JsfUtil.addErrorMessage("Error al cargar datos iniciales: " + postConstucError.get(i).getMessage());
}
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: showPostConstructError() " + e.getMessage());
}
}
xhtml code
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
<h:form>
<p:remoteCommand id="rcomerror" name="showError" process="#this" autoRun="true"
actionListener="#{mBPresentNinos.showPostConstructError()}" />
</h:form>
For me using preRenderView event to display message on form init was a messages-hell. So I created very simple "component" to keep static messages. For this example only one error message is supported.
staticMessage.xhtml:
<ui:fragment xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
rendered="#{rendered}">
<div id="staticMessage" class="ui-messages ui-widget" aria-live="polite">
<div class="ui-messages-error ui-corner-all"><span class="ui-messages-error-icon"/>
<ul>
<li>
<span class="ui-messages-error-summary">#{value}</span>
</li>
</ul>
</div>
</div>
</ui:fragment>
Including messages:
<ui:include src="/template/components/staticMessage.xhtml">
<ui:param name="rendered"value="#{beanMB.staticMessagesRendered}"/>
<ui:param name="value" value="Place your message here."/>
</ui:include>

CommandButton action not worked in insideModalPanel

h:commandButton action not worked in modalPanel.
I am using t:inputFileUpload component for upload file. In my richModalPanel have one h:commandButton
My requirement : After browse the file, and click upload commandButton, then i want to show the selected file name in inside ModalPanel.
My problem is :
When i click commandbutton in modalPanel, not called commandButton action in bean, and automattically close the modalPanel.
In that action method starting...just i put System.out.println("Uploading process to be start..."); Even this output not print in my tomcat log.
<body>
<h:form id="UploadForm" binding="#{FileUpload.intiForm}">
<a4j:outputPanel id="uploadOutputPanel">
<a4j:commandButton value="ShowModalPanel"
action="#{FileUpload.showUploadPanelAction}"
oncomplete="#{rich:component('uploadImagePanel')}.show()"
reRender="uploadImagePanel,uploadOutputPanel"/>
</a4j:outputPanel>
</h:form>
<rich:modalPanel id="uploadImagePanel" moveable="true" top="150" width="400" autosized="true">
<h:form id="uploadForm" enctype="multipart/form-data" >
<h:panelGrid id="uploadPanelGridId" columns="2">
<t:inputFileUpload id="uploadFile"
value="#{FileUpload.logoImageFile}"
size="54"/>
<h:commandButton id="UploadButton"
value="Upload"
action="#{FileUpload.uploadFileAction}"/>
<h:outputText value="Uploaded File Name : #{FileUpload.fileName}"/>
</h:panelGrid>
</h:form> </rich:modalPanel> </body>
faces-config.xml
<managed-bean>
<managed-bean-name>FileUpload</managed-bean-name>
<managed-bean-class>com.jsf.fileupload.FileUpload</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
FileUpload .java
import javax.faces.component.html.HtmlForm;
import org.apache.myfaces.custom.fileupload.UploadedFile;
public class FileUpload
{
private HtmlForm intiForm;
private String fileName;
private UploadedFile logoImageFile;
public String showUploadPanelAction()
{
System.out.println("Show Upload Panel Action ....."); //This line showing in tomcat log, when i click "ShowModalPanel" button --> a4j:commandButton
return "";
}
public String uploadFileAction()
{
System.out.println("Uploading process to be start...."); //But this line NOT show in my tomcat log, when i click "UploadButton" --> h:commandButton
System.out.println("logoImageFile : " + logoImageFile);
if(logoImageFile != null)
{
fileName = logoImageFile.getName();
}
return "";
}
public HtmlForm getIntiForm(){
System.out.println("Page initializing......"); //This line showing in tomcat log, when the page loading time
return intiForm;
}
public void setIntiForm(HtmlForm intiForm) {
this.intiForm = intiForm;
}
public UploadedFile getLogoImageFile(){
return logoImageFile;
}
public void setLogoImageFile(UploadedFile logoImageFile){
this.logoImageFile = logoImageFile;
}
public String getFileName(){
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
Please help me..
Thanks in advance.
Use domElementAttachment="form" to the modal panel
<rich:modalPanel id="uploadImagePanel" moveable="true" top="150" width="400" autosized="true" domElementAttachment="form"> </rich:modalPanel>
Do the other prints show up in your log ?
Have you annotated your FileUpload.java with #Named or #ManagedBean ? And its #{fileUpload.xxx}, not #{FileUpload.xxx}.
And i would also change
<h:commandButton id="UploadButton"
value="Upload"
action="#{FileUpload.uploadFileAction}"/>
with an
<a4j:commandButton id="UploadButton"
value="Upload"
action="#{FileUpload.uploadFileAction}"
reRender="uploadImagePanel,uploadOutputPanel">
I'm not sure if they are related but i'm facing a similar issue when using and h:commandLink inside a form with enctype="multipart/form-data". If I remove this property from the form it works.

Resources