Error Message in modal JSF doesn´t work - jsf

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"/>

Related

reset primefaces calendar date to system date

I am designing a page technology using jsf 2.0 and primefaces. In my page I insert a prime faces calendar. When the user click on calendar to change the default date, a warning message shown which is a dialog box containing two command button. Now what I am trying to do is when the user click on cancel command button, the date should be changed back to the default date which was populated from the first time page when the page loaded. I wrote a java script but its not working.
<label>Date<label>
<p:calendar readonlyInput="true" widgetVar="calDate" yearRange="c-20:c+20" navigator="true" id="b1incomeeffectfrom#{incmStatus.index}" value="#{userDate.effectiveFrom}" pattern="dd/mm/yyyy">
<p:ajax event="dateSelect" oncomplete="checkForDefault(this);" global="false"/>
</p:calendar>
<p:dialog rendered="#{user.Lock}" widgetVar="dlg1" header="Warning" modal="true">
<h:panelGroup layout="block" styleClass="modal-dialog">
<h:panelGroup layout="block" styleClass="modal-content">
<h:panelGroup layout="block" styleClass="modal-body">
<div class="form-horizontal">
<h:panelGroup layout="block" styleClass="form-group">
<h:outputLabel styleClass="col-xs-8 control-label">Are you sure want to change?</h:outputLabel>
</h:panelGroup>
</div>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="modal-footer">
<p:commandButton value="Ok" type="button" styleClass="btn btn-primary" onclick="PF('dlg1').hide();PF('dlg2').show();" />
<p:commandButton value="Cancel" type="button" styleClass="btn btn-primary" onclick="resetDate();" />
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
</p:dialog>
javascript
function resetDate(){
PF('dlg1').hide();
calDate.setDate(null);
}
Your calendar value is coming from your backing bean (userDate.effectiveFrom). You will have to change the value there to take effect
<p:commandButton value="Cancel" type="button" styleClass="btn btn-primary"
onsuccess="PF('dlg1').hide()" action="#{userDate.resetDate()}" update="calDate" />
class UserDate{
[..]
public void resetDate(){
this.effectiveFrom = initialDate;
}
[..]
}

Button in dialog inside p:dialog is not calling controller method

I've got a problem as described in the title.
Small description of the problem is as following:
I have button which is used to open dialog. Then, inside that dialog, there is button which opens another dialog on top of the first one. After clicking second button I want method from controller to be called but nothing happens. Value in h:outputText is read properly, so I guess it is not a problem with connection controller->view.
I'm using:
Spring web 3.1.2.RELEASE
JSF 2.2.10
Primefaces 5.1
Code:
beans.xml
<bean id="testController" class="test.TestController" />
TestController.java
public class TestController implements Serializable
{
private static final long serialVersionUID = 7028608421091861830L;
private String test;
public TestController()
{
test = "abc";
}
public void testMethod()
{
test = "cba";
}
public String getTest()
{
return test;
}
}
test.xhtml
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg1">
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg2">
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" type="button" actionListener="#{testController.testMethod}" />
</p:dialog>
</p:dialog>
What I tried:
adding appendToBody="true" to each p:dialog
changing from p:commandButton to p:button
changing from actionListener to action
but nothing helps.
I would be grateful for any help or advice of what can be the reason of not calling given method.
There are 3 problems.
You're nesting <p:dialog> components. This doesn't make sense. Separate them.
A <p:dialog> must have its own <h:form>, particularly when you explicitly use appendToBody="true" or appendTo="#(body)", otherwise nothing can be submitted because JavaScript would relocate the dialog out of its position in the HTML DOM tree to the end of body, causing it to not be sitting in a form anymore.
A <p:commandButton type="button"> acts as a "click" button, not as a submit button. Remove that attribute from submit buttons.
All in all, this is how it should look like:
<h:form>
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
</h:form>
<p:dialog widgetVar="dlg1">
<h:form>
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog widgetVar="dlg2">
<h:form>
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" actionListener="#{testController.testMethod}" />
</h:form>
</p:dialog>
OK. I guess I found a way to fix this problem.
It seems that the problem was:
type="button"
I deleted it from the list of attributes of each button and now it works even without h:form. Thanks for help.

Getting a NullPointerException while Partial rendering via FacesContext

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.

h:message doesn't display JSF message

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

Submit popup panel content, rich:popupPanel

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">
...

Resources