I have this commandButton :
<p:commandButton value="Enregistrer" action="#{reglementClientMB.ajouter}"
process="#this #form" update="#form" >
<f:setPropertyActionListener target="#{reglementClientMB.est_ajouter}" value="false" />
</p:commandButton>
the action method return to another page , I want to display one p:growl when the next page is loaded
I tested to put that is the constructor of its managed bean but the growl is displayed below data in the page
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_INFO, ""
+ "Confirmation", "Réglement crée avec sucée"));
RequestContext.getCurrentInstance().update("messages");
how can I achieve this
thank you in advance
The bean's constructor may be too late for the job if the <p:growl> is rendered before the bean is been constructed for the first time. E.g.
<p:growl />
...
<h:outputText value="#{bean.something}" />
It would only work if the bean is constructed before the <p:growl> is rendered.
<h:outputText value="#{bean.something}" />
...
<p:growl />
In order to solve your concrete problem, you'd need to do the job in a pre render view listener instead.
<f:event type="preRenderView" listener="#{bean.init}" />
With:
public void init() {
// Add the desired message here.
}
Related
I'm working on an application in JSF to manage trips made by the people in the various offices in my company.
(i'll try to keep the code at the minimum necessary)
I have an object Trip, an object Office, and a helper object OfficeWithTrips:
public class Trip {
private BigDecimal id;
private BigDecimal officeId;
// getters and setters
}
public class OfficeWithTrips {
private Office office;
private DataModel<Trip> trips;
// getters and setters
}
The application has two pages: one where each manager sees the offices he has to manage and the trips of each office, and another with the detail of a single trip.
I have a session bean that contains the list of offices with their trips:
public class TripsListBean implements Serializable {
private DataModel<OfficeWithTrips> officesWithTrips;
private Trip currentTrip = new Trip();
// getters and setters
}
On the main page I go through the "offices" in the bean, which has a nested list of Trips. Each office table with its list of trips has a footer with an "add new trip" button.
<h:dataTable value="#{tripsListBean.officesWithTrips}" var="officeWithTrips">
<h:column>
<h:form id="tripForm">
<h:dataTable value="#{officeWithTrips.trips}" var="trip">
<f:facet name="header">
<h:panelGrid columns="2">
<h:outputText value="Trips for the office: " />
<h:outputText value="#{officeWithTrips.office.name}" />
</h:panelGrid>
</f:facet>
<f:facet name="footer">
<h:commandButton value="Add new trip"
action="#{tripsHandler.addTrip}" />
</f:facet>
<h:column>
<f:facet name="header">Trip date</f:facet>
<h:outputText value="#{trip.date}">
<f:convertDateTime type="date" pattern="dd.MM.yyyy" />
</h:outputText>
</h:column>
// other columns
<h:column>
<h:commandButton value="edit"
action="#{tripsHandler.editTrip}">
<f:setPropertyActionListener target="#{tripsHandler.currentTrip}"
value="#{trip}" />
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</h:column>
</h:dataTable>
When I click "add new trip" I want to be able to set the office id in the trip. What I do in "addTrip()" method is this:
public String addTrip() {
OfficeWithTrips officeWithTrips = tripsListBean.getOfficesWithTrips().getRowData();
Trip trip = new Trip();
trip.setOfficeId(officeWithTrips.getOffice.getId());
tripsListBean.setCurrentTrip(trip);
return TRIP_DETAIL_URL;
}
My problem is that in addTrip the index in officesWithTrips is always 0, when I want to add a trip to the second office in the list it doesn't work (it always returns the first office).
Can anyone spot the error? I guess that when I click the "add new trip" button, this sets the index in the officeWithTrips.trips dataModel, but not in tripsListBean.officesWithTrips...
I solved this with another setPropertyActionListener: I added an Office currentOffice to TripsListBean and set that with a setPropertyActionListener directly on the jsf page. Basically, the same I do for currentTrip
I'm much newbie to the JSF. I am creating a simple crud app. I have done adding, and deleting but there is some problem with updating data..... when edit is clicked, bean is populated with values of whom i want to update. but it is not shown in the next page, in which it is to be edited......
this is the link which leads to editPage
<h:column>
<f:facet name="header">Edit</f:facet>
<h:form>
<h:commandLink value="Edit" action="#{personManipulate.editPerson(person)}"/>
</h:form>
</h:column>
this is the code which assign person data to person entity
public String editPerson(PersonEntity person){
this.person=person;
return "success2";
}
This is the code which updates per save person
public String savePerson(){
if(person.getPersonId() > 0){
personDao.updatePerson(person);
return "success";
}else{
personDao.addPerson(person);
return "success";
}
}
}
This is the page where values should be shown and Updated
<h:form>
<h:panelGrid columns="2">
<f:facet name="header">Person</f:facet>
<h:outputLabel for="firstName" value="First name" />
<h:inputText id="firstName" value="#{personManipulate.person.firstName}"
label="First name" />
<h:outputLabel for="lastName" value="Last name" />
<h:inputText id="lastName" value="#{personManipulate.person.lastName}"
label="Last name" />
<h:outputLabel for="address" value="Address" />
<h:inputText id="address" value="#{personManipulate.person.address}"
label="Address" />
<h:outputLabel for="phone" value="Contact Number" />
<h:inputText id="phone" value="#{personManipulate.person.phone}" />
<h:commandButton action="#{personManipulate.savePerson}" value="Submit" />
<h:button outcome="ShowPersons.xhtml" value="Cancel" />
</h:panelGrid>
</h:form>
This is the navigation rule
<navigation-rule>
<from-view-id>JSF/personManipulate.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>JSF/ShowPersons.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>JSF/ShowPersons.xhtml</from-view-id>
<navigation-case>
<from-outcome>success2</from-outcome>
<to-view-id>JSF/personManipulate.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
On Debugging everything is fine i.e. data is assigned to person object but not shown on update page
Well, you're trying to access the #{personManipulate} bean, which still has not been created when you're in the people list. Supposing it is a #ViewScoped bean as it should, that should be created when you address to JSF/personManipulate.xhtml specifically. So I would encourage you to do the People List -> Edit Person transition using a GET request, instead:
showPersons.xhtml
<h:column>
<f:facet name="header">Edit</f:facet>
<h:form>
<h:link value="Edit" outcome="personManipulate.xhtml">
<f:param name="idPerson" value="#{person.id}" />
</h:link>
</h:form>
</h:column>
That will direct you to an url similar as: personManipulate.xhtml?idPerson=1. Then, load the person before the #{personManipulate} bean makes the rendering task:
personManipulate.xhtml
<f:metadata>
<f:viewParam name="idPerson" value="#{personManipulate.idPerson}" />
<f:event listener="#{personManipulate.loadData}" type="preRenderView" />
</f:metadata>
PersonManipulate.java
public void loadData(ComponentSystemEvent event){
person = service.getPersonById(idPerson);
}
That way you keep both view beans unbound and you use urls for navigation. If you aren't interested in showing the person id in the url, then you can use the Flash scope to pass it from bean to bean. Have a look at the linked posts.
See also:
View parameter when navigating to another page
Understand Flash Scope in JSF2
I have the next url: http://host:port/page.xhtml?response=something
I want render a p:message if response==something
I have the next code:
<h:panelGroup rendered="#{param.response == 'something'}">
<h:outputText value="message" />
</h:panelGroup>
this render a <div>message</div>
I want render a <p:messages /> or <p:growl /> and its value "message" if response==something
please help me to code this, and something else:
Do I need a bean managed to send value to p:messages or p:growl?
Do I need to call p:messages or p:growl from a <p:commandButton />?
I can't use <h:body onload="callFunction()"> 'cause h:body is on
template xhtml <ui:insert name="content"></ui:insert> and my view
is on <ui:composition ... <ui:define name="content" > in other
xhtml, and h:body is common to several views
You'd really need to use FacesContext#addMessage() to add a message to the context. On an initial request, your best bet is a
<f:metadata>
<f:viewParam name="response" value="#{bean.response}"/>
<f:event type="preRenderView" listener="#{bean.init}" />
</f:metadata>
with
private String response;
public void init() {
if (response != null) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_INFO, response, null));
}
}
You can by the way also use a separate <p:messages globalOnly="true"> or <p:growl globalOnly="true"> to display only faces messages with a null client ID.
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
I have programmed a little application in which you can register and edit your data. For the authenticity I used a bean class called Authenticity. This class contains an object of Customer (which is a database entity) and methods to login and to logout.
Now I´ve created a page for editing the user: A form with many inputTexts which have the value of authenticity.curUser./(properties). It look like this:
<h:form>
<h:panelGrid columns="2" cellpadding="4px" width="600">
<h:outputText value="firstname:" />
<h:inputText value="#{authenticity.curUser.firstname}"/>
<h:outputText value="lastname:"/>
<h:inputText value="#{authenticity.curUser.lastname}" />
<h:outputText value="street:"/>
<h:inputText value="#{authenticity.curUser.street}" />
<h:outputText value="housebumber"/>
<h:inputText value="#{authenticity.curUser.housenumber}" />
<h:outputText value="Zip:"/>
<h:inputText value="#{authenticity.curUser.zip}" />
<h:outputText value="City:"/>
<h:inputText value="#{authenticity.curUser.city}" />
<h:outputText value="Land"/>
<h:inputText value="#{authenticity.curUser.country}" />
<h:outputText value="email:"/>
<h:inputText value="#{authenticity.curUser.email}" />
<h:outputText value="password:"/>
<h:inputSecret value="#{authenticity.curUser.password}" />
<h:commandButton action="#{authenticity.editUser}" value="Edit" />
</h:panelGrid>
</h:form>
My question now is whether there are better solutions for this problem. Should a AuthenticityBean be actually able to edit the user? Or should I create a extra bean?
I would use a completely separate view scoped bean which holds a brand new copy of the entity representing the logged-in user. Only when the form is successfully edited and saved, then the currently logged-in user can be replaced (the form bean can just access it as a #ManagedProperty).
If you were reusing the same entity in the form; imagine that you're ajax-updating some fields and then cancels/closes the form. The currently logged-in user would then still have the "Wrong" field values in the remnant of the session. This is not correct.
I tried some ways to achieve this simple thing :
Show a collection of POJOs in form of checkboxes
When i click on one of the checkboxes, a method should be executed
The method will be able to access the pojo/checkbox that was clicked
I tried to implement it this way :
<h:selectManyCheckbox id="groupUsers" layout="pageDirection" value="#{timetableBean.selectedUsers}">
<f:ajax listener="#{timetableBean.processUserEvents}" render="#this" />
<f:selectItems value="#{timetableBean.group.users}"
var="user" itemLabel="#{user.userId} - #{user.name}" itemValue="#{user}">
<f:attribute name="user" value="#{user}" />
</f:selectItems>
</h:selectManyCheckbox>
And my method is :
public void processUserEvents(AjaxBehaviorEvent e) {
User user = (User) e.getComponent().getAttributes().get("user");
...
}
The user fetched from e.getComponent().getAttributes().get("user"); is sadly null
In what way can i accomplish this ?
Thank you !