Logic for values in JSF - java

I have simple problem in JSF 2.0 and I need advice what is better solution. So, on my .xhtml page there is component which has 2 values : Yes and No.
<h:outputLabel id=v1 value="#{someValue}"/>
<f:selectItem itemValue="0" itemLabel="#{msg['label.no']}" />
<f:selectItem itemValue="1" itemLabel="#{msg['label.yes']}" />
What I am trying to accomplish is get default value of f:select based on outputLabel.
For example: if outputLabel gets value: Amateur than default f:selectItem is 'Yes' otherwise is 'No' default. Is it better with some logic in backing bean or via rendering on xhtml page?

You need to set it in the property behind the input component's value attribute. You didn't show the complete code, but if it's for example a <h:selectOneRadio> like so
<h:outputLabel for="foo" value="#{bean.label}" />
<h:selectOneRadio id="foo" value="#{bean.value}">
<f:selectItem itemValue="0" itemLabel="#{msg['label.no']}" />
<f:selectItem itemValue="1" itemLabel="#{msg['label.yes']}" />
</h:selectOneRadio>
then you should be setting the #{bean.value} in bean's (post)constructor. The complete picture is unclear, so here's a basic kickoff example instead of a well-suited solution:
private String label;
private Integer value;
#PostConstruct
public void init() {
label = "Amateur";
value = "Amateur".equals(label) ? 1 : 0;
}

Related

How to render more JSF components by using a ui:repeat component?

I have a question concerning the jsf component . Here is a small code example:
<ui:repeat var="bean" value="myBean.myListToIterate">
<h:selectOneCheckbox value="#{myBean.specificField}" />
#{bean.car.name}
</ui:repeat>
Question 1: Why the expression #{bean.car.name} alone inside the ui:repeat element and why not for example in a
<h:outputLabel value="#{bean.car.name}" />"?
If i use this, nothing will be displayed.
Question 2: Why does this example doesn´t look very well, if i use a
<h:selectOneRadio value="#{myBean.specificField}"/> component
instead of a
<h:selectOneCheckbox value="#{myBean.specificField}"/> component?
Greetz
Marwief
Answer 1 :
EL JSF expressions are allowed in the last JSF versions. So it can be put without any wrapping tag (like <h:outputText />).
Using this <h:outputLabel value="#{bean.car.name}" /> did not give result, because you did not specify for attribute to point to, in order to be rendered as label of its client id, which means, it cannot be used alone.
Answer 2 :
First, this JSF tag <h:selectOneCheckbox /> doesn't exist, maybe you wanted to mean <h:selectBooleanCheckbox />. Replacing this by <h:selectOneRadio ... /> does not look very well, because this last one needs <f:selectItem /> or <f:selectItems /> to hold choices from where the end user will be able to choose between (i.e at least 2 choices), in the contrary of <h:selectBooleanCheckbox /> which can have no child select item(s) tag(s) in the case of one alone choice to (un)check.

f:ajax listener isn't called

I've got a problem considering JSF and AJAX.
I am trying to update some customer details after a visitor inserts the customer id.
Firstly, a excerpt from the xhmtl code:
<h:form>
<h:panelGrid columns="2">
<h:panelGrid columns ="2" border="1" id="customer_grid">
<h:outputLabel value="#{mbean_msg.reservation_lblCustomerNo}" for = "customer_id"/>
<h:inputText id = "customer_id" value="#{reservationHandler.customer.customer_id}">
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails}"
render="customer_grid" />
</h:inputText>
<h:outputLabel value="#{mbean_msg.reservation_lblLastname}" for="lastname"/>
<h:inputText id="lastname" value="#{reservationHandler.customer.lastname}" required ="true"
requiredMessage="#{error_msg.errmsgLastname}" validator="#{reservationHandler.validateCustomer}"/>
<h:outputLabel value="#{mbean_msg.reservation_lblFirstname}" for="firstname"/>
<h:inputText id="firstname" value="#{reservationHandler.customer.firstname}" required ="true"
requiredMessage="#{error_msg.errmsgFirstname}" validator="#{reservationHandler.validateCustomer}"/>
The listener method is implemented within my java file (ReservationHandler.java) like that:
public void autocompleteCustomerDetails(){
System.out.println("Auto Complete"); // for testing
}
Basically I am trying to call the method autocompleteCustomerDetails with the Listener. Unfortunately this method is never called. Anyways, the render seems to work just fine, since the other inputTexts update themselves (visibly).
Does anybody have an idea, why the listener isn't called?
There are two problems in the code shown so far:
First,
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails}" />
this isn't a valid EL expression. EL expessions have the form of #{}, not {}. Fix it accordingly:
<f:ajax listener="#{reservationHandler.autocompleteCustomerDetails}" />
Second,
public void autocompleteCustomerDetails() {
this isn't a valid default signature of a method expression for <f:ajax listener>. The tag documentation clearly tells the following:
signature must match public void processAjaxBehavior(javax.faces.event.AjaxBehaviorEvent event) throws javax.faces.event.AbortProcessingException.
So, you forgot the argument. Add it accordingly. The throws declaration isn't mandatory for unchecked exceptions, so we can just leave it out.
public void autocompleteCustomerDetails(AjaxBehaviorEvent event) {
Or, if you actually intend to get rid of the argument, then you should put parentheses in the EL method expression:
<f:ajax listener="#{reservationHandler.autocompleteCustomerDetails()}" />
Note that this works only if your container supports EL 2.2.
Try this:
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails()}"
render="customer_grid" />
or change the method to:
getAutoCompleteCustomerDetails
just for testing...
Anyhow, you´re not allowed to use any jsf's components library? Like primefaces ?
It gets the job done in such a easy way...
Anyhow, with primefaces I would do that like this:
<p:ajax event="blur" listener="#{prospectoRadarController.atualizarRadar(data)}" update=":mainForm:painelRadar" />
Another guess would be, add the execute="#this" to the ajax flag...
Sorry, those are all wild guesses, but I really want to help.
PLease feedback!

How to check a textbox value when the user press tab

The scenario was something like this:
I have 2 textboxes, say txtbox1 and txtbox2. When the user type something on txtbox1 and then press tab, txtbox1 loses focus and txtbox2 got focus. I want to check the value of txtbox1 when it loses focus. If txtbox1 value is invalid, I need to render a <h:outputText value="Invalid field" rendered=#{bean.errorFlag}/>
I used <p:ajax event="blur" /> on txtbox1.
My problem is it doesn't render the outputText even though the value of errorFlag is set to true. I also use update on ajax to update outputText, but it doesn't render it.
You need to specify the client ID of the to-be-updated element in update attribute.
<h:inputText id="input1" value="#{bean.input1}">
<p:ajax event="blur" update="input1Message" />
</h:inputText>
<h:panelGroup id="input1Message">
<h:outputText value="Invalid field!" rendered="#{bean.input1Error}" />
</h:panelGroup>
But... You're basically reinventing JSF validation and not taking benefit of JSF built-in validation API. I strongly recommend to just implement a Validator instead.
#FacesValidator("input1Validator")
public class Input1Validator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (isInvalid(value)) {
throw new ValidatorException(new FacesMessage("Invalid field!"));
}
}
}
and use it as follows
<h:inputText id="input1" value="#{bean.input1}">
<p:ajax event="blur" update="input1Message" />
</h:inputText>
<h:message id="input1Message" for="input1" />
This keeps your managed bean free from validation and boolean property clutter.
I guess you use p:tabview. if it is correct, you can use tab change listener
you can look this site
http://www.primefaces.org/showcase-labs/ui/tabviewChangeListener.jsf

How to preserve a object through multiple pages

I have an ArrayList of objects and I use them as follow:
<ui:repeat value="#{BookReview.books}" var="book" >
<li>
<h:commandLink value="#{book.bookName}" action="detail" />
</li>
</ui:repeat>
in the detail page I show the book's comments, and I have a form to register a new comment:
<h:form>
Name:<h:inputText value="#{Comment.author}" />
Rate:<h:inputText value="#{Comment.rate}" />
Text:<h:inputText value="#{Comment.comment}" />
<h:commandButton action="#{book.addComment(Comment)}" value="Add Comment" />
</h:form>
My problem is that book isn't preserved until the next Request and #{book.addComment(Comment)} results in Target Unreachable, identifier 'book' resolved to null.
I have tried annotate the book as RequestScoped, didn't work, then I've modified to ViewScoped, didn't work either, then I tried to use a <inputHidden > to keep the object around, but it just uses a .toString() and I can't reuse the object.
I don't want to use session to store the object because I need it only once, and I don't think I want to use a converter because Book has a ArrayList of comments (also I think it is to cumbersome and complicated)
Put your BookReview bean to the session scope (or, if you're on JSF-2.0 - then let it have the view scope).
You've got to keep a handle of the current book somewhere and relate the new comment with it.
Create a new bean, BookDetail.
#ManagedBean
#ViewScoped
public class BookDetail {
private Book book;
private Comment comment = new Comment();
public String addComment() {
book.getComments().add(comment);
// You need to persist book here if necessary.
return "list";
}
// Add/generate getters/setters the usual way.
}
Set the selected book as follows (could be done nicer if you were using an UIData component like h:dataTable or t:dataList instead of ui:repeat):
<h:commandLink value="#{book.name}" action="detail">
<f:setPropertyActionListener target="#{bookDetail.book}" value="#{book}" />
</h:commandLink>
Rewrite the detail form as follows:
<h:form>
Name:<h:inputText value="#{bookDetail.comment.author}" />
Rate:<h:inputText value="#{bookDetail.comment.rate}" />
Text:<h:inputText value="#{bookDetail.comment.comment}" />
<h:commandButton action="#{bookDetail.addComment}" value="Add Comment" />
</h:form>

selectOneMenu with selectItems

I am trying to make a filter using selectOneMenu.
I have two categories, when one is selectect, must filter the results shown, and also the second category.
JSF code:
<div id="box-categories" class="box-left">
<b>Filter by topic</b>
<h:selectOneMenu id="cat1" binding="#{interfaceContainer.documentFormContainer.selectOnes['cat1'].selectOne}" rendered="true" onchange="javascript:refreshResults(); return false;">
<f:selectItems value="#{interfaceContainer.documentFormContainer.selectOnes['cat1'].items}" />
</h:selectOneMenu>
<b>and subtopic</b>
<h:selectOneMenu id="cat2" binding="#{interfaceContainer.documentFormContainer.selectOnes['cat2'].selectOne}" rendered="true" onchange="javascript:refreshResults(); return false;" value="#{interfaceContainer.documentFormContainer.selectOnes['cat2'].value}">
<f:selectItems value="#{interfaceContainer.documentFormContainer.selectOnes['cat2'].items}" />
</h:selectOneMenu>
</div>
But I have problems when I try to get the values using this java code:
public String getStringValue(){
if ( this.selectOne ==null || this.getSelectOne().getValue()==null)
return "";
return this.getSelectOne().getValue().toString();
}
I realised that the problem is just with getValue(), because debugging, this.getSelectOne() is in the rigth value, but this.getSelectOne().getValue() is null.
Any idea??
Thanks in advance
UIInput#getValue() will return null when you attempt to access it during any phase before the Update Model Values phase. You're apparently accessing it at the "wrong" moment in the JSF lifecycle. Anyway, creating dependent dropdown menus in JSF without help of a shot of Ajax is terrible.
Long story short, here's how to do it: Populate child menu's (with complete and working code examples).

Categories