In my JSF application, here's a simplified version of part of my form:
<h:form id="loginFormId">
<h:panelGrid columns="3">
<h:outputText value="Login :" />
<h:inputText label="Login" id="loginId" />
<rich:message for="loginId" ajaxRendered="true"/>
<f:facet name="footer">
<a4j:commandButton value="OK" action="#{authentifierUtilisateurBean.authentifierUtilisateur}">
<f:ajax execute="#form" render="#form" />
</a4j:commandButton>
</f:facet>
</h:panelGrid>
</h:form>
and here's a simplified version of my Managed Bean method authentifierUtilisateur() :
public String authentifierUtilisateur() {
try {
utilisateurEnBase = utilisateurDao.chercherParLogin( utilisateur.getLogin() );
}
...
if ( utilisateurEnBase == .... ) {
message = new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle.getString("authentifier.utilisateur.login.inconnu"),"" );
FacesContext.getCurrentInstance().addMessage("loginFormId:loginId", message );
}
I'd like to assign an error to the rich:message tag associated with the h:inputText based on something happening in the authentifierUtilisateur() method.
A validator is not possible, because the method that will deliver results from the DB is run in the authentifierUtilisateur() method.
When I try the above code, the page doesn't display message in front of the h:inputText.
If I insert in the form, the code
<rich:messages />
(messages with an s) above the button as follows:
<f:facet name="footer">
<rich:messages />
<a4j:commandButton value="OK" action="#{authentifierUtilisateurBean.authentifierUtilisateur}">
<f:ajax execute="#form" render="#form" />
</a4j:commandButton>
</f:facet>
then I can see the message so I am sure that the server sends correctly message to the client.
So why the client doesn't display h:message in front of the h:inputText?
Is there something wrong in the Managed Bean?
addMessage("loginFormId:loginId", message)
A FacesMessage consists of a summary and a detail, rich:message will display the detail by default. That's the one you're leaving empty so there's nothing to display. Either fill in the detail or set #showSummary="true"
Insert an id to the h:panelGrid i.e
<h:panelGrid columns="3" id="grid">
Then in java code try this
FacesContext.getCurrentInstance().addMessage("loginFormId:grid:loginId", message );
Let me know if this helps
Related
I have a strange behavior where I am getting NPE while doing page refresh using faces context.
I have a managed bean which is in Request Scope. So want to refresh the page after click on commandbutton. I have tried with 'update' but it is behaving strange in my page.
Error: PartialViewContextImpl$PhaseAwareVisitCallback.visit : java.lang.NullPointerException
This is my JSF page:
<h:form id="form">
<p:messages autoUpdate="true"/>
<h:panelGrid columns="4" cellpadding="5" id="panelGrid" rendered="true">
<p:outputLabel for="s00" value="#{tk.expense_keyword}"/>
<p:inputText id="s00" value="#{expense.form.keyword}"/>
<p:outputLabel for="s02" value="#{tk.expense_creatorId}"/>
<p:inputText id="s02" value="#{expense.form.creatorId}" disabled="#{!expense.form.canEditCreatorId}"/>
<h:outputText id="s10" value="Amount Between #{expense.form.amountFrom} and #{expense.form.amountTo}" />
<h:panelGrid>
<p:slider for="s11,s12" display="s10" minValue="0" maxValue="1000" style="width: 200px" range="true" displayTemplate="Amount Between {min} and {max}" />
<h:inputHidden id="s11" value="#{expense.form.amountFrom}" />
<h:inputHidden id="s12" value="#{expense.form.amountTo}" />
</h:panelGrid>
</h:panelGrid>
<p:commandButton value="#{tk.expense_search}" id="a01" action="#{expense.search}" ajax="false" immediate="true"/>
<p:dataTable var="line" varStatus="loop" value="#{expense.form.expenseEntryList}" emptyMessage="#{tk.expense_table_empty}" id="dataTable">
<p:column headerText="#{tk.expense_table_creatorId}">
<h:inputHidden value="#{line.oid}"/>
<h:inputText value="#{line.creatorId}"/>
</p:column>
<f:facet name="footer">
<p:commandButton value="#{tk.expense_saveAsDraft}" id="a06" action="#{expense.saveAsDraft}"/>
<p:commandButton value="#{tk.expense_submit}" id="a07" action="#{expense.submitAll}"/>
<p:commandButton value="#{tk.expense_validate}" id="a08" action="#{expense.validate}"/>
</f:facet>
</p:dataTable>
</h:form>
Here when I click on Save As Draft I want to refresh the page. So I am using FacesContext's method to refresh the page.
Here is my method saveAsDraft:
public Outcome saveAsDraft() throws Exception{
try {
saveAsDraftBody(false,false);
getFacesContext().getPartialViewContext().getRenderIds().add("form:panelGrid");**//**getting error****
getFacesContext().getPartialViewContext().getRenderIds().add("form:dataTable");**//**works fine****
Log.info(this,"getFacesContext().getPartialViewContext().getRenderIds(): "+getFacesContext().getPartialViewContext().getRenderIds());
return Outcome.SUCCESS;
}
catch (Throwable e){
throw manageError(e);
}
}
I don't know why it works for data table refresh but not for panelGrid :(
First of all you have the bean in request scope and you are making full page submit and here the partial render does not make any sense. The error you are getting because you have component which is basically, another input into a form which will be sent to the managed bean of the current view when the form is submitted.
I have one .xhtml file with primefaces and have one form with one commandButton when try to fire the actionListener doesn't works this is the form:
<h:form id="formCreate">
<p:dialog header="Crear" widgetVar="usuarioDlgCreate" resizable="false" id="usuDlgCreate"
showEffect="fade" hideEffect="explode" modal="true">
<h:panelGrid id="display" columns="2" cellpadding="4" style="margin:0 auto;">
<h:outputText value="Rol:" />
<p:inputText value="#{usuarioBean.usuarioSeleccionado.rolId}"/>
<h:outputText value="Nombre:" />
<p:inputText value="#{usuarioBean.usuarioSeleccionado.nomUsuario}"/>
<h:outputText value="Email:" />
<p:inputText value="#{usuarioBean.usuarioSeleccionado.email}" size="30"/>
<f:facet name="footer">
<p:separator/>
<p:commandButton id="btnNewAccept" actionListener="#{usuarioBean.create(actionEvent)}" title="Guardar" value="Guardar"/>
<p:commandButton id="btnNewCancel" oncomplete="usuarioDlgCreate.hide()" icon="ui-icon-new" title="Cancelar" value="Cancelar"/>
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
and this is my bean method:
public void create(ActionEvent actionEvent) {
UsuarioDao usuarioDao = new UsuarioDaoImplements();
String msg = null;
if(usuarioDao.create(this.usuarioSeleccionado)) {
msg = "Información guardada correctamente";
} else {
msg = "No ha sido posible almacenar la información";
}
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, null);
FacesContext.getCurrentInstance().addMessage(null, message);
}
already tried with the button like:
and the method without the parameter ActionEvent:
and like this too(without parenthesis):
but doesn't fire the method, pleas help me.... thanks a lot
I have similar issue, actionListener didn't fired when I used in component as value expression object. Submit wasn't successful and no error message showed (also no logged). So I change value expression to simple variable: integer, string etc. and after that work for me.
before:
<p:selectOneMenu value="#{formCalendarDay.airplane}">
<f:selectItems value="#{classifiers.airplanes}" var="airplane" itemLabel="#{airplane.name}" itemValue="#{airplane}"/>
</p:selectOneMenu>
after fix:
<p:selectOneMenu value="#{formCalendarDay.airplaneId}">
<f:selectItems value="#{classifiers.airplanes}" var="airplane" itemLabel="#{airplane.name}" itemValue="#{airplane.id}"/>
</p:selectOneMenu>
The first thing, you should change your attribute like this : actionListener="#{usuarioBean.create}".
Second, make sure you are using javax.faces.event.ActionEvent.
If it still doesn't work, you should verify for validation errors, you can try by adding h:messages to see if something goes wrong.
Try putting your form inside of the dialog - not the other way around
Well, I solved this it seems Primefaces 3.5 and Glassfish 4.0 doesn't work very well, so I changed by Primefaces 4.0 and it works.
I have one xhtm in jsf and one modal within.
In this modal I have one field that I´m trying to validate and return an error.
my code:
Modal:
<rich:popupPanel id="cancelssi" modal="true" width="500" height="280" zindex="2" domElementAttachment="form" show="#{demandasMB.showCancelar}" showWhenRendered="#{demandasMB.showCancelar}" >
...
<h:panelGroup layout="block" class="area-input-100" id="idmotivocancelamentopanel">
<h:panelGroup class="label-campo">Justificativa de cancelamento:</h:panelGroup>
<h:inputTextarea styleClass="textarea-form-2-linhas" id="idmotivocancelamento" value="#{demandasMB.demandas.cnmmotivocancelamento}" maxlength="255"/>
<h:message for="idmotivocancelamento" />
</h:panelGroup>
<h:panelGroup layout="block" class="clear"/>
<h:panelGroup layout="block" styleClass="alinhaBotao">
<h:commandButton value="Cancelar">
<f:ajax render="idmotivocancelamento idmotivocancelamentopanel"
event="click"
listener="#{demandasMB.preCancelar()}"
execute="#form"
/>
</h:commandButton>
<h:commandButton value="Fechar"/>
</h:panelGroup>
</rich:popupPanel>
in my MB I have:
public void preCancelar(){
if(StringUtils.isBlank(demandas.getCnmmotivocancelamento())){
FacesMessage fm = new FacesMessage("Favor preencher");
FacesContext.getCurrentInstance().addMessage("idmotivocancelamento",fm);
}else{
showConfirmacaoCancelar = true;
showCancelar = false;
}
}
I´m building FacesMessage but doesn´t appear in my modal.
What I´m doing wrong ?
thanks
You need to ajax-update idmotivocancelamentopanel to reflect the FacesMessages you're adding.
An alternative is to use the <rich:message/>. Using the ajaxRendered="true" attribute will allow the message component be automatically updated on ajax-requests. So you'll instead have:
<rich:message for="idmotivocancelamento" ajaxRendered="true"/>
when i click on the command button. validate method is getting called but the error message is not getting displayed..
here is my code..
<h:form id="form">
<h:body>
<p:panel style="width:500px">
<h:outputLabel for="year" value="Select Year: *" style="font-weight:bold" />
<p:selectOneMenu id="year" value="#{leaveBean.year}">
<f:selectItem itemLabel="Select One" itemValue="null" />
<f:selectItems value="#{leaveBean.yearDTO}" var="currentUser" itemValue="#{currentUser.name}" itemLabel="#{currentUser.name}" />
<f:validator validatorId="LeaveCardValidator" />
</p:selectOneMenu>
</p:panel>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails" id="button"/>
<h:message for="year" style="color:red"/>
You seem to expect that JSF auto-updates the <h:message> on every ajax request. This is untrue. Perhaps you're confusing with PrimeFaces <p:messages> or <p:growl> which have each an autoUpdate attribute which enables you to tell them to auto-update themselves on every ajax request.
You really need to make sure that the <h:message> is covered by the ajax update. Just give it an ID
<h:message id="yearMessage" ... />
and include it in the client ID collection of the ajax update
<p:commandButton ... update="updateList updateDetails yearMessage" />
An alternative would be to replace <h:message> by <p:messages autoUpdate="true">.
Not sure where are the updateList and updateDetails are located but in the example give above you should use update="#form" instead or in addtion like this:
update="updateList updateDetails #form"
so that the form will be rendered again...
just use one of these :
update the whole form in order to update the content of
<h:message />
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="#form" id="button"/>
or give the <h:message /> an id and id this id to the <p:commandButton/>
<h:message id="msg" for="year" style="color:red"/>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails,msg" id="button"/>
I am trying to submit values in a pop-up panel inside another panel that has a submit/action event. But before opening pop-up panel I need to invoke a function on my managed bean that create a new entity object. The outer panel has the only h:form, since you can't nest them. I have wrapped the pop-up panel in a a4j:region to submit only this part when the use submits the values inside the pop-up panel. This works, but not the execution of the preparing function that need to be invoked when the pop-up panel executes. I have tried a4j:commandLink but that component don't work together with the rich:popupPanel (strange since both of them are Richfaces components?!). So I have to relay on the h:commandLink and use ajax.
How can I invoke a function on my managed bean when the link to open/render the pop-up panel fires?
(What is the correct pattern for this?)
PS. The initial question has changed, but not the problem concerning submitting values in a pop-up panel.
Part of the xhtml file:
<h.form>
...
<a4j:region>
<rich:popupPanel id="popup_sys_user_req" modal="false" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="Request New Sector/Category" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('popup_sys_user_req')}.hide(); return false;">
X
</h:outputLink>
</f:facet>
<h:panelGrid columns="2">
<h:outputLabel value="Request New:" />
<h:selectOneMenu id="sys_req_type" value="#{userController.selectedSysUserRequest.sysrequesttype}" required="true" >
<f:selectItems value="#{userController.getSysRequestTypeItems('SECTOR_CATEGORY')}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel value="Description:" />
<h:inputTextarea id="user_req_desc" value="#{userController.selectedSysUserRequest.description(desc)}" required="true" requiredMessage="Decription is missing" />
</h:panelGrid>
<a4j:commandButton action="#{userController.CreateSysUserRequest()}" value="Send Request" execute="sys_user_req_form" oncomplete="#{rich:component('popup_sys_user_req')}.hide(); return false;"/>
</rich:popupPanel>
</a4j:region>
</h:form>
The commandLink (re-edit)
<h:commandLink actionListener="#{userController.prepareCreateSysRequest}" value="Request New Sector/Category">
<f:ajax execute="popup_sys_user_req #this" render="popup_sys_user_req">
<rich:componentControl id="popup_ctr" event="click" target="popup_sys_user_req" operation="show"/>
</f:ajax>
</h:commandLink>
----------------------------
//Managed Bean:
public void prepareCreateSysRequest(ActionEvent event ) {
selectedSysUserRequest = new Sysuserrequest();
JsfUtil.log("Prepare Create System User Request");
}
This post continues the dicussion about the pop-up panel.
Greetings Chris.
If I understand correctly you want to submit all form elements inside popupPanel but not outside the panel when you invoke someAction1? I can think of two ways to do this:
1. a4jcommandButton has a limitToList attribute, you can list which components you want to be updated on the server
2. create your popupPanel outside of the first form and then use its own form:
<h:form>
...
<a4j:commandButton action="someAction2"...
</h:form>
<rich:popupPanel>
<h:form>
...
<a4j:commandButton action="someAction1"...
</h:form>
</rich:popupPanel>
Update
If you are using RichFaces 4 you can replace the limitToList attribute with limitRender
The problem is that the popup isn't a child of the form in jsf, you only need to use the domElementAttachment attribute to change that. So your code would look like this:
<h.form>
...
<a4j:region>
<rich:popupPanel id="popup_sys_user_req" modal="false" autosized="true" resizeable="false" domElementAttachment="form">
<f:facet name="header">
...