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
Related
i have a problem with this primefaces component in my view xhtml. I builded a searchbar that filters elements in a list based on the value of this inputText component with an ajax call on event. Everything works like it should, till i press enter in inputText, then my filter method does unexpected things. Thats why i tried to avoid pressing enter. But like in the snipped below, the listener isn't called even if key != 13.
Does anybody have a idea?
Thanks for your help!
<p:inputText value="#{ListView.filter}" style="width:150px" placeholder="Stichwort">
<p:ajax event="keyup" onevent="if (event.keyCode == 13) { return false; }" listener="#{ListView.filterAvailable}" update="#form"/>
</p:inputText>
You can just try this directly on the inputText tag. I usually do this with Internet Explorer.
<p:inputText id="testInput" onkeydown="if(event.keyCode==13) return false;" [....]
You can simply add a condition in front of it like :
<p:inputText id="testInput" onkeydown="#{mySessionInfoBck.ieBrowser ? 'if(event.keyCode==13) return false;' : ''}" [....]
I have a problem I can not solve, I have a selectOneListbox with a Value Chang Listener and submit onclick. It works perfectly but the problem I have noticed is that the Set and Get methods I have for other elements in my form runs after the method that captures the ValueChangeListener. And I can not use the right data from the elements in my form, how do I resolve this?
So i got in my selectOneListbox:
<h:selectOneListbox onclick="Submit();"
valueChangeListener="#{normalbesoksgrenController.setActiveFromAllList}"
size="20" value="#{normalbesoksgrenController.currentVardTillfalleID}">
<f:selectItems itemValue="#{item.vardTillfalle.id}" itemLabel="#
{normalbesoksgrenController.getDateAndTime(item.getVardTillfalle().getStartTid())}"
var="item" value="#{normalbesoksgrenController.besokList}" ></f:selectItems>
</h:selectOneListbox>
And i got my backbean:
public void setActiveFromAllList(ValueChangeEvent event)
{
int id = Integer.parseInt(event.getNewValue().toString());
Doing some stuff..
}
I think you might want to use the ajax event like this:
<h:selectOneListBox .....>
<f:ajax execute="#form" listener="#{normalbesoksgrenController.setActiveFromAllList}" event="change" reder=":whatEverYouWant" />
</h:selectOneListBox>
The execute attribute defines what should be submitted before the ajax request is handled.
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;
}
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!
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>