Validator is called but error message is not displayed - jsf

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

Related

Primefaces not showing data in tags [duplicate]

When I am using a PrimeFaces p:commandButton
<p:commandButton action=#{bean.action} />
I don't see the the validation messages for inputs (both the default h: ones or the PrimeFaces p: ones.) For example with
<f:validateRequired />
When I am using default command button like
<h:commandButton action=#{bean.action} />
I do see the validations. What can be the cause of this difference?
I am using Prime Faces 3.5 with Mojarra 2.1.18
<h:form id="reliefhourheadcopy-form">
<h:panelGrid columns="1">
<h:outputText value="Kopiere Entlastungsstunden von" />
<h:outputText value="Semester: #{reliefHourHeadManagedBean.reliefHourHead.semester}" />
<h:outputText value="Jahr: #{reliefHourHeadManagedBean.reliefHourHead.year}" />
<h:outputText value="nach" />
</h:panelGrid>
<h:panelGrid columns="3">
<h:outputText value="Semester:" />
<p:selectOneMenu id="semester" value="#{reliefHourHeadManagedBean.semester}">
<f:selectItems value="#{reliefHourHeadManagedBean.semesterTypes}" />
</p:selectOneMenu>
<h:message for="semester" />
<h:outputText for="yearSpinner" value="Jahr:" />
<p:spinner id="yearSpinner" value="#{reliefHourHeadManagedBean.year}" maxlength="4" min="2000" max="2030" size="4">
<f:validateRequired />
<f:validateLongRange minimum="2000" maximum="2030" />
</p:spinner>
<h:message for="yearSpinner" />
</h:panelGrid>
<h:panelGrid columns="1" style="margin-top:25px">
<p:commandButton action="#{reliefHourHeadManagedBean.copyReliefHourHead}" value="Kopieren" icon="ui-icon-copy" >
<f:param name="reliefhourhead_id" value="#{reliefHourHeadManagedBean.reliefHourHeadId}" />
</p:commandButton>
</h:panelGrid>
</h:form>
Like #Partlov wrote in the comments below the question,
Main difference is that p:commandButton is AJAX by default, and h:commandButton is non-AJAX by default.
So
<p:commandButton ... />
is more like
<h:commandButton ...>
<f:ajax/>
</h:commandButton>
but
<p:commandButton ...>
<p:ajax/>
</p:commandButton>
is wrong and leads to undefined behaviour
or the other way around
<h:commandButton ... />
is like
<p:commandButton ajax="false" ... />
The p:commandButton will submit the form by default. However by default it does not update anything in the form after the ajax call is finished so the messages are not displayed (which in development mode would have shown in the log files that messages were enqueued but not displayed) . The non-ajax h:commandButton does a full page refresh that does show the messages. In order to get the form (which contains the message component) updated when using the p:commandButton you need to add the update attribute:
<p:commandButton action="#{reliefHourHeadManagedBean.copyReliefHourHead}" value="Kopieren" icon="ui-icon-copy" update="#form">
<f:param name="reliefhourhead_id" value="#{reliefHourHeadManagedBean.reliefHourHeadId}" />
</p:commandButton>
Adding an (superfluous) f:ajax or p:ajax inside a p:commandXXX can result in strange undefined behaviour
See also
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

How to make required message dissapear when h:selectOneMenu value is changed?

I'm having a trouble with getting rid of required message.
I have a form in which I have a few fields and a button.
When I press a button there is validation that checks if required fields where filled with values if not then required message is displayed for invalid value/component.
Now I want to select a value from selectOneMenu or type something into inputText and when I do that I want the required message to dissapear without need to press the button again.
How would you do that?
I've tried to remove message with sth like this, but it doesn't seems to work:
Iterator<FacesMessage> msgIterator = FacesContext.getCurrentInstance().getMessages();
while (msgIterator.hasNext())
{
FacesMessage facesMessage = msgIterator.next();
msgIterator.remove();
}
Could you help me with that?
Here is example code:
<h:form id="mainForm">
<h:selectOneMenu required="true" id="dictionaryValueId" value="#{SomeBean.dictionarySelectedValue}">
<f:selectItem itemValue="#{null}" itemLabel="#{i18n['view.choose']}" />
<f:selectItems value="#{SomeBeanBean.dictionaryValuesMap}" var="element"
itemLabel="#{element.descripption}" itemValue="#{element.key}" />
<f:ajax event="change" execute="#this msgId" render="msgId dictionaryValueId"/>
</h:selectOneMenu>
<h:message id="msgId" style="display:none;" for="dictionaryValueId" />
...
<h:commandButton value="#{i18n['button.forward.name']}"
actionListener="#{SomeBean.forward}" >
<p:ajax process="#form" update="mainForm"/>
</h:commandButton>
I am not sure, but is not there a problem with
style="display:none;"
for
<h:message id="msgId"/>
You can wrap your message with <h:panelGroup/> and render by this panelGroup Id, this Id will be always present on your form.
<h:form id="mainForm">
<h:selectOneMenu required="true" id="dictionaryValueId" value="#{SomeBean.dictionarySelectedValue}">
<f:selectItem itemValue="#{null}" itemLabel="#{i18n['view.choose']}" />
<f:selectItems value="#{SomeBeanBean.dictionaryValuesMap}" var="element" itemLabel="#{element.descripption}" itemValue="#{element.key}" />
<f:ajax event="change" execute="#this" render="messageBundle1 dictionaryValueId"/>
</h:selectOneMenu>
<h:panelGroup id="messageBundle1">
<h:message id="msgId" style="display:none;" for="dictionaryValueId" />
</h:panelGroup>
<h:commandButton value="#{i18n['button.forward.name']}"
actionListener="#{SomeBean.forward}" >
<p:ajax process="#form" update="mainForm"/>
</h:commandButton>
</h:form>

How can I get my commandButton by Id?

I want to change my ActionListener of commandButton depending on the icon selected in advance:
<p:dialog id="dialog" header="Add Memo" widgetVar="dialogMemo" resizable="false" >
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="commentInput" value="Comment:" />
<p:inputTextarea id="commentInput" value="#{dashboardBean.getCurrentComment()}" rows="6" cols="25" label="commentInput"/>
<p:watermark for="commentInput" value="Enter your memo..."/>
<h:outputLabel for="selectShare" value="Share Memo: " />
<p:selectBooleanCheckbox id="selectShare" />
<h:outputLabel for="choosePriority" value="Priority:" />
<p:selectOneMenu id="choosePriority" value="#{dashboardBean.currentPriority}" label="choosePriority">
<f:selectItem itemLabel="Low Priority" itemValue="1" />
<f:selectItem itemLabel="Medium Priority" itemValue="2" />
<f:selectItem itemLabel="High Priority" itemValue="3" />
</p:selectOneMenu>
<p:commandButton id="submitDialog" icon="ui-icon-check" value="Confirm" ajax='false' type="submit" action="#{dashboardBean.getLastMemo()}"/>
<p:commandButton icon="ui-icon-close" onclick="dialogMemo.hide();" value="Cancel"/>
</h:panelGrid>
</h:form>
</p:dialog>
<p:layout fullPage="true">
<p:layoutUnit id="leftPanel" position="west" size="250" header="My Memos" resizable="false" closable="false" collapsible="false">
<h:form id="form">
<p:commandButton id="addMemo" icon="ui-icon-plus" onclick="dialogMemo.show();" type="submit" action="#{dashboardBean.getEditControl}"/>
<p:dashboard id="dashboardId" model="#{dashboardBean.model}" binding="#{dashboardBean.dashboard}">
</p:dashboard>
</h:form>
</p:layoutUnit>
</h:body>
When i click to command button (id="addMemo"), i want to change actionListener to commandButton(id="submitDialog").
I try that with:
public void getEditControl()
{
UIViewRoot view = _context.getViewRoot();
CommandButton button = (CommandButton) view.findComponent("submitDialog");
System.out.println("I am ID ==== [ " + button.getId() +" ]");
}
But 'button.getId()' does't work.
But 'button.getId()' does't work.
I gather that this is because the button is actually null and therefore the attempt to invoke the getId() method threw a NullPointerException? It's surprising that you stated the problem like that, "button.getId() doesn't work" instead of like "view.findComponent() returned null" (which has in turn the pretty obvious consequence that any attempt to access it would throw NullPointerException). If you had indeed no clue why it threw NullPointerException, then I strongly recommend to take a JSF pause and learn basic Java first.
Coming back to the concrete problem, the findComponent will return null when the client ID submitDialog doesn't exist in the component tree. Indeed, you have it inside a <h:form> which is a NamingContainer component. The button's client ID is more likely formId:submitDialog where formId is the ID of the button's parent form which you have to assign yet. An easy way to find out it is checking the ID of the generated HTML representation of the button.
See also this related question: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar" Just substitute "ajax" in the answer with findComponent.
I am not sure that the way you do this is the right way.
If you want to get component instance better way to do this will be not get it by id but add
<p:commandButton id="submitDialog" icon="ui-icon-check"
value="Confirm" ajax='false' type="submit"
action="#{dashboardBean.getLastMemo()}" binding="#{dashboardBean.component}" />
and that way the property in the bean will always have the component instance that you need.
Note that the scope of bean where you put component binding should be view to avoid side affects.

JSF - unhandled faces messages prevent rerendering of view

I work with JSF, RichCalendar and a4j. My problem: I want to rerender components of my website but if someone edits the date of one rich-calendar input field to '12.aa.2012' a FacesMessage is thrown, which is correct and good. Anyway my a4j-rerender-event did not get triggered due to unhandeld facesMessages. On my Tomcat-Console I get this errorMessage:
WARNUNG: There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are:
- Bitte ein gültiges Datum eingeben!
How can I handle this problem, I tried several ways to show the errorMessage and I can figure out how to show it, but there is still the warning and still the not triggered-rerender-event?
Thanks in advance.
UPDATE: here is the code to my question. As you can see after you select one of the radio buttons, one dateContainer will show up, for example 'admissionDateContainer'. If you change the value to 'asd', and select another choice, no rerendering of the related box happens, the choice will change but the wrong dateContainer will stay there ?!
<h:panelGroup layout="block" id="caseTypeContainer" rendered="#{CaseController.isFallContainer}" styleClass="fieldContainer">
<t:outputLabel for="caseType" styleClass="generalInputLabel" style="width:200px; float:left;" value="#{resources.labels['caseType']}:" title="#{resources.labels['caseType']}" />
<h:selectOneRadio id="caseType" style="font-size:13px;" value="#{CaseController.caseType}" styleClass="radioButtonTableMasterdata inlineBlock">
<f:selectItem itemValue="#{resources.labels['caseTypeDocAttrStationaer']}" itemLabel="#{resources.labels['caseTypeDocAttrStationaerLabel']}" />
<f:selectItem itemValue="#{resources.labels['caseTypeDocAttrAmbulant']}" itemLabel="#{resources.labels['caseTypeDocAttrAmbulant']}"/>
<f:selectItem itemValue="#{resources.labels['caseTypeDocAttrUnbekannt']}" itemLabel="#{resources.labels['caseTypeDocAttrUnbekannt']}"/>
<a4j:support oncomplete="initializeFocusBlurEvents(); " event="onchange" reRender="captureDateContainerDiv, admissionDateContainerDiv, dischargeDateContainerDiv, messagesContainer, warnings"/>
</h:selectOneRadio>
</h:panelGroup>
<t:div id="admissionDateContainerDiv">
<h:panelGroup layout="block" id="admissionDateContainer" rendered="#{CaseController.isCaseTypeStationaerOrAmbulant}" styleClass="fieldContainer showDateInputWithTime">
<t:outputLabel for="admissionDate" rendered="#{CaseController.isCaseTypeStationaer}" styleClass="generalInputLabel" style="width:200px;" value="#{resources.labels['caseAdmissionDateStationaer']}:" title="#{resources.labels['caseAdmissionDateStationaer']}" />
<t:outputLabel for="admissionDate" rendered="#{CaseController.isCaseTypeAmbulant}" styleClass="generalInputLabel" style="width:200px;" value="#{resources.labels['caseAdmissionDateAmbulant']}:" title="#{resources.labels['caseAdmissionDateAmbulant']}" />
<rich:calendar id="admissionDate" value="#{CaseController.caseContainerAdmissionDate}" datePattern="dd.MM.yyyy HH:mm" enableManualInput="true" direction="auto">
<f:facet name="footer">
<h:panelGrid columns="3" width="100%" columnClasses="fake, width100 talign">
<h:outputText value="{selectedDateControl}" style="font-weight:bold;" />
<h:outputText value="{timeControl}" style="font-weight:bold;" />
<h:outputText value="{todayControl}" style="font-weight:bold;" />
</h:panelGrid>
</f:facet>
</rich:calendar>
<rich:message for="admissionDate" />
</h:panelGroup>
</t:div>
<t:div id="messagesContainer" rendered="true">
<p>Messages global</p>
<rich:messages global="true" />
</t:div>
Add <rich:messages or <rich:message to your page
Take a look at rich:messages and rich:message
Also make sure that they are being rendered after your button is being clicked... add their ids or their wrapper (#form for example) ids to the reRender of your calendar

How to submit values in a pop-up panel?

I have bean struggling to understand how to use the rich:popupPanel component in the right way. There are (at least not that I could find) few post about how to use the rich:popupPanel and how to submit values from it.
To make matter worse the panel seams to add (when checking the html) a hard coded "_content" to its component id name (to the div generated). I have tried to use aj4:region tag to partial render the complete form. But that didn't seamed to work, cause nothing where posted to managed bean. So now I have one option left, where the panel has its own form, outside the main one on the page.
I can see that the evaluation of the form (popup) values is happening, but not the execution of the bean function that persist the values (I see the POST request of the command button). The only reason I can think of at the moment, is that the pop-up panel use another bean to persist the values that the main form on the page (both of them are session scoped).
I am thinking of omit the pop-up panel all together, since it seams so hard to make this work. Maybe its a well know secret, since it so few post about it. It behaves the same if if use componentController or only a a4j:commanLink.
How is it possible to submit values from a rich:popupPanel and invoke a backing bean function to persist the pop-up form values ?
Appreciate if someone can shed some light on this, greetings Chris.
I use Richfaces 4.0-final on Glassfish 3.1
<h:form id="main_form">
<!-- Command for popup -->
<a4j:commandLink actionListener="#{userController.prepareCreateSysRequest}" oncomplete="#{rich:component('popup_sys_user_req_form:popup_sys_user_req')}.show(); return false;"
execute="#this" value="Request New Sector/Category" />
...
<a4j:commandButton action="#{projectController.Create}" ...>
</h:form>
<h:form id="popup_sys_user_req_form">
<rich:popupPanel id="popup_sys_user_req" modal="true" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="New Project Request" />
</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.selectedSysRequestType}" required="true" requiredMessage="Request Type is required" title="Request Type">
<f:selectItems value="#{userController.getSysRequestTypeItems()}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel value="Description:" />
<h:inputTextarea id="user_req_desc" value="#{userController.selectedSysUserRequest.description}" required="true" requiredMessage="Decription is missing" />
</h:panelGrid>
<a4j:commandButton action="#{userController.CreateSysUserRequest}" onclick="#{rich:component('popup_sys_user_req')}.hide(); return false;" execute="#form" render="popup_sys_user_req_form" value="Send Request" />
</rich:popupPanel>
</h:form>
For what I have done I used to have the issue to got to submit twice only the first time.
To fix it the form got to be outside the popupPane. And also that the popupPanel should have the attibute domElementAttachment="form".
Example.
<h:form>
<rich:popupPanel id="shipmentItemUpdateDialog"
autosized="true"
domElementAttachment="form">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{shipmentBundle.shipmentItemDetailsHeader}" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:commandLink>
<h:graphicImage value="/core/images/modal/close.png"/>
<rich:componentControl target="shipmentItemUpdateDialog" operation="hide" />
</h:commandLink>
</f:facet>
<h:outputText for="shipmentItemName"
value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemName}"
/>
<h:inputText id="shipmentItemName"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.name}"
label="#{shipmentBundle.shipmentItemName}"
size="40" >
</h:inputText>
<h:outputText for="shipmentItemCode"
value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemCode}"
/>
<h:inputText id="shipmentItemCode"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.code}"
label="#{shipmentBundle.shipmentItemCode}"
size="40" >
</h:inputText>
<h:outputText value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemAmount}"
/>
<h:inputText id="shipmentItemAmount"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.amount}"
label="#{shipmentBundle.shipmentItemAmount}"
size="4" >
<f:validateLongRange minimum="1"/>
</h:inputText>
<h:outputText value="#{coreBundle.requiredChar} #{shipmentBundle.shipmentItemNeedsCooling}"
/>
<h:selectBooleanCheckbox id="shipmentItemNeedsCooling"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.needsCooling}"
label="#{shipmentBundle.shipmentItemNeedsCooling}"
/>
<h:outputText for="shipmentItemDetails"
value="#{shipmentBundle.shipmentItemDetails}"
/>
<h:inputTextarea id="shipmentItemDetails"
disabled ="false"
required ="true"
value="#{shipmentItemController.shipmentItemUI.value.details}"
label="#{shipmentBundle.shipmentItemDetails}"
cols="38"
rows="5"
/>
</h:panelGrid>
<h:panelGrid columns="1" dir="LTR">
<h:panelGrid columns="2" dir="LTR">
<a4j:commandButton value="#{coreBundle.acceptButton}"
action="#{shipmentItemController.onUpdate()}"
render="shipmentItemsTable">
</a4j:commandButton>
<h:commandLink value="#{coreBundle.closeLink}"
immediate="true">
<rich:componentControl target="shipmentItemUpdateDialog" operation="hide" />
</h:commandLink>
</h:panelGrid>
<h:outputText value="#{coreBundle.requiredText}"/>
</h:panelGrid>
</rich:popupPanel>
</h:form>
I hope this helps.
I think you got it right.. think of the pop-up as a regular page. To submit and close the pop-up, do something like this:
<a4j:commandButton value="Save" onclick="#{rich:component('panelId}.hide();" render="..."/>
Hope this helps..

Resources