richfaces and displaying errormessages - jsf

<h:form id="userSettingsForm">
<rich:messages>
<f:facet name="errorMarker">
<h:graphicImage value="/img/msgerror.png" />
</f:facet>
</rich:messages>
<h:outputText value="Description:" />
<h:inputText label="Description:" id="description"
value="#{userSettingsForm.instance.description}" required="true"
size="5">
<f:validateLength minimum="3" />
</h:inputText>
<a:commandButton value="Validate" />
</h:form>
When an error occurs I see e.g. this: screenshot
How can I display the text "Description" in front of "Required field" ?
Like it is used on the richfaces demo page at richfaces demo page

Take a look at <rich:message> - it shows a single message.

I found out that I was missing something in my messages_en.properties file.
When I create one using seam setup the generated file contains e.g. this:
javax.faces.converter.IntegerConverter.INTEGER=Value is not a number
javax.faces.component.UIInput.REQUIRED=Required field
When I add:
javax.faces.converter.IntegerConverter.INTEGER={2}: Value is not a number
or
javax.faces.component.UIInput.REQUIRED={0}: Required field
The field label is added in front of the message.

Related

Pass parameter in JSF h:link

In the search box, the user type a word, like "iPhone", and click "Search", the system performs backend search and return all information for "iPhone". In the end, it also output a related word "iPod" through wordController.related variable. If the user clicks "iPod" link, the system needs to pass iPod as another word to perform search, and return results again. My question, how can I pass "iPod" (the "related" variable) as another search variable and perform backend search? This time, it is not through h:inputText and h:commandButton, since it's not user entered value.
Thank you for your help!
<h:form id="wordForm">
<h:panelGrid columns="3">
<h:outputLabel for="word">Enter a word:</h:outputLabel>
<h:inputText id="word"
value="#{wordController.word}" />
<h:message for="word" />
</h:panelGrid>
<h:commandButton id="search" value="Search!"
action="#{wordController.info}" />
</h:form>
<br />
<h:outputText value="#{wordController.wordInfo}"
rendered="#{not empty wordController.wordInfo}" />
<h:link value="#{wordController.related}" />
<h:link value="This is a link" outcome="login" >
<f:param name="firstname" value="Matt" />
</h:link>
HTML output
This is a link

Dynamic navigation with parameter passing in JSF

I want to pass the "title" parameter in the following listing dynamicaly to another jsf Facelet, depending on the selection of the selectOneMenu. My first approach looks like this:
<h:form id="form">
<p:selectOneMenu value="#{exerciseEditorBean.selectedExerciseType}" >
<f:selectItem itemLabel="Multiple Choice Exercise" itemValue="MultipleChoiceExercise" />
<f:selectItem itemLabel="Vocabulary Test" itemValue="VocabularyTest" />
</p:selectOneMenu>
<h:outputText value="Enter Title of your Exercise: " />
<h:inputText id="title" value="#{exerciseEditorBean.exerciseTitle}" />
<h:commandButton value="Next" action="#{exerciseEditorBean.openEditor()}" />
</h:form>
The ExerciseEditorBean is ViewScoped.
The openEditor() function then decides by the selectedExerciseType attribute which Facelet to show next and returns something like "multipleChoiceEditor.xhtml".
How can I now pass the titel attribute to this Facelet?
I now use the f:ViewParam in the target servelet, which works well except, that "multipleChoiceEditor.xhtml?includeViewParams=true" does not work, but this is another issue. Thanks for the discussion!

Error "<f:ajax> contains an unknown id" when used to render <rich:message>

This is my form:
<h:body>
<h:form>
<h:panelGrid columns="3" >
<h:outputLabel for="name" value="Primeiro nome:" />
<h:inputText id="name" value="#{register.person.name}" >
<f:ajax event="blur" render="m_name" listener="#{register.validateName}" />
</h:inputText>
<rich:message id="m_name" for="name" />
//.. others fields
</h:panelGrid>
</h:form>
</body>
When i try to execute on Glassfish gives the follow error :
javax.servlet.ServletException: <f:ajax> contains an unknown id 'm_name' - cannot locate it in the context of the component name
But if i change <rich:message ..> by <h:message..> it works (I want it works with rich:message because it returns an image and a message )
Why this is happening ? Never happened with me before, until now.
The RichFaces component reference tells this about the <rich:messages>:
13.1.1. Basic usage
...
The <rich:message> component is automatically rendered after an Ajax request. This occurs without the use of an component or a specific reference through the render attribute of the Ajax request source.
So, I'd just remove the render attribute on m_name and replace <f:ajax> by <a4j:ajax>.
<h:inputText id="name" value="#{register.person.name}" >
<a4j:ajax event="blur" listener="#{register.validateName}" />
</h:inputText>
<rich:message id="m_name" for="name" />
If you want to explicitly specify it anyway, you can set ajaxRendered="false" on the <rich:message> component.
<h:inputText id="name" value="#{register.person.name}" >
<f:ajax event="blur" listener="#{register.validateName}" render="m_name" />
</h:inputText>
<rich:message id="m_name" for="name" ajaxRendered="false" />
Looks like a richfaces behavior to me. I suspect you will have to file a bug report.
A work-around is to enclose the rich:message tag inside a rich:message tag inside a div tag, then give the div tag an id="m_name".

How to refer element id dynamically

I am trying to spread the radio buttons using tomahawk selectOneRadio. My id looks like this
<rich:dataTable id="carTable" value="#{cars}" var="car">
<rich:column>
<s:decorate id="types" template="/layout/display-text.xhtml">
<t:selectOneRadio id="models" value="#{car.model}" layout="spread">
<f:selectItems value="#{models}" />
</t:selectOneRadio>
<h:panelGrid columns="2">
<a:repeat value="#{models}" rowKeyVar="index">
<t:radio for="car:carTable:0:types:models" index="#{index}"></t:radio>
</a:repeat>
</h:panelGrid> -->
</s:decorate>
</rich:column>
</rich:dataTable>
I referred id after inspecting an element. But this is not working. Because for each iteration radio button id varies. How to refer an id in t:radio
The documentation for t:radio says:
The id of the referenced extended selectOneRadio component. This value is resolved to the particular component using the standard UIComponent.findComponent() searching algorithm.
I'm guessing a:repeat is a NamingContainer, so using "models" won't work. You can use the client identifier of the t:selectOneRadio component.
Something like this:
<t:selectOneRadio id="models" value="#{car.model}" layout="spread"
binding="#{requestScope.modelComponent}">
<f:selectItems value="#{models}" />
</t:selectOneRadio>
<h:panelGrid columns="2">
<a:repeat value="#{models}" rowKeyVar="index">
<t:radio for="#{requestScope.modelComponent.clientId}" index="#{index}" />
</a:repeat>
</h:panelGrid>
Caveats:
This binds the component to the request scope map using the key "modelComponent"; you need to ensure this doesn't collide with something else
Resolving modelComponent.clientId requires JSF 2.0 (JEE6) or above
See here for more details; working with older versions; etc.

Enable JSF commandbutton only if all the other components are error free

I am using icefaces in my application.
There is a form in the page, which has a couple of input fields.
I would like to enable the commandbutton only if the fields are valid(no errors for the other components)
Is it possible to do it ?
example code
<ice:form>
<ice:panelGrid columns="2">
<ice:outputLabel>Enter Date</ice:outputLabel>
<ice:panelGroup>
<ice:selectInputDate renderAsPopup="true" id="InputDate" value="#{Bean.FormDate}" partialSubmit="true" ></ice:selectInputDate>
<ice:message for="InputDate" />
</ice:panelGroup>
<ice:outputLabel>Days</ice:outputLabel>
<ice:panelGroup>
<ice:inputText value="#{Bean.days}"partialSubmit="true" id="inputDays">
<f:validateLongRange minimum="1" maximum="10"/>
</ice:inputText>
<ice:message for="inputDays"/>
</ice:panelGroup>
<ice:commandButton value="Submit" action="#{Bean.SomeAction}"></ice:commandButton>
</ice:panelGrid>
In the above code, I want to enable the submit commandbutton only if the days and date are valid(Don't have any error enqueued.
If you are using jsf 2.0 you can do something like this:
<ice:form>
<ice:panelGrid columns="2">
<ice:outputLabel>Enter Date</ice:outputLabel>
<ice:panelGroup>
<ice:selectInputDate renderAsPopup="true" id="InputDate"
value="#{Bean.FormDate}" partialSubmit="true"
binding="#{inputDateComponent}">
<f:ajax execute="#this" render="submit inputDateMessage" />
</ice:selectInputDate>
<ice:message id="inputDateMessage" for="InputDate" />
</ice:panelGroup>
<ice:outputLabel>Days</ice:outputLabel>
<ice:panelGroup>
<ice:inputText value="#{Bean.days}" partialSubmit="true"
id="inputDays" binding="#{inputDaysComponent}">
<f:validateLongRange minimum="1" maximum="10" />
<f:ajax execute="#this" render="submit inputDaysMessage" />
</ice:inputText>
<ice:message id="inputDaysMessage" for="inputDays" />
</ice:panelGroup>
<ice:commandButton id="submit" value="Submit"
action="#{Bean.SomeAction}"
disabled="#{!inputDateComponent.valid}" />
</ice:panelGrid>
</ice:form>
I haven't tested this specific example but you can see where I'm going. The input fields get evaluated on change and either show validation errors or create a condition where the commandButton is not disabled.
You could also use rendered= and make positive assertions if you want the button to only appear when the input fields are valid.
You could use a phase-listener as described here:
http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html
The phase-listener in this example builds a string with client-ids that have messages attached. Check this string in a bean and create a bean property depending on whether there are ids with messages or not.
Then you can enable the command button depending on the bean property.
Switch each of your input fields to 'immediate="true"' and add a validator to the fields.
Have the validator set/unset a boolean to determine whether the fields contain valid data and do as sparrowhawk suggests and test this boolean value(s) in the rendered expression for the submit button.

Resources