I'm using jsf 2.0, primefaces 3.0M3 and jboss 6.0.0 in a project. I'm trying to make a table cell editable as in primefaces showcase, but the events to save and cancel didn't get fired. So, I decided to try and make only one field editable inside the datable with an inplace element and use the save event. It didn't work also. The code is as follow:
<ui:define name="search_results">
<h:form id="search_results">
<p:dataTable id="tbl" var="amb" value="#{environment.searchResult}">
<p:column id="firstcolumn">
<f:facet id="nameFct" name="header">#{label['menu.admin.environment']}</f:facet>
<p:inplace editor="true" effectSpeed="fast" event="dblclick">
<p:inputText value="#{amb.dsAmbiente}" />
<p:ajax event="save" listener="#{environment.update(amb)}" />
</p:inplace>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
and the class that is called in the listener
#Named("environment")
#ViewScoped
public class Environment extends AbstractBean implements Serializable{
private static final long serialVersionUID = 1L;
private AmbienteRemote environmentRemote;
private List<Empresa> companies;
private Ambiente env;
#Inject
private transient FacesContext context;
#Inject
private transient Messages messages;
private String compSearch;
private String envSearch;
private EnumFlStatusAmbiente statusSearch;
private List<Ambiente> searchResult;
public Environment()
{
}
//....
public String update(final Ambiente amb)
{
System.out.println("update");
return null;
}
//....
}
Can anybody help?
Thanks
Kelly
CDI components (annotated with #Named) does not have #ViewScoped.
You can't mix JSF Managed Beans imports with CDI imports.
Try to use sessionScope (remember - class have to implements Serializable).
(ps: Probably you will use wrong import such as
import javax.faces.bean.SessionScoped;
instead
import javax.enterprise.context.SessionScoped;)
Related
i am little bit stuck in my problem. i have sent the parameter from one xhtml page to another xhtml page successfully and i printed that parameter on my next page xhtml like this, #{param['id']}, but the problem is my #postConstructor is not executing, because i want that whenever my next page loads the parameter id sends over to database and get the required details in my datatable.
here is my code snippet of xhtml page from where i am sending parameters
<h:column>
<f:facet name="header">
Title
</f:facet>
<h:link value="#{item.title}" outcome="showObj.xhtml">
<f:param name="pid" value="#{item.id}" />
</h:link>
</h:column>
and here is my managedBean
package mb;
import java.io.Serializable;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
#ManagedBean(name="next")
#RequestScoped
public class showObj implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{param.pid}")
private String name;
public String getName() {
System.out.println("in getter"+name);
return name;
}
public void setName(String name) {
this.name = name;
}
#PostConstruct // this will execute init() after id is injected
public void init() {
System.out.println("in init");
}
}
and here is my next xhtml page content, where i am receiving parameters.
<h:outputText value="#{param['pid']}"></h:outputText>
now i want that whenever my this parameter is received here, on page loading this parameter should send to database (the other ejb project). i know that if my #postConstructor runs than i can achieve this thing. but my #postConstructor is not executing.
i have also searched my problem over internet, they all says something about mojarra version, so i let you know that i have 2.1.6 version
After my post (Hibernate Primefaces AutoComplete text) I switched the implementation a little. But now I am facing a problem.
Even if I use an AJAX event I do not keep the selected value saved to populate a second drop down.
my CREATE.XHTML
<h:head></h:head>
<ui:debug rendered="true"/>
<body>
<h:form id="createAddressForm" prependId="true">
<!-- <p:messages autoUpdate="true" /> -->
<p:growl id="msgs" showDetail="true" />
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<p:outputLabel for="countryDropDown" value="Country" />
<p:selectOneMenu id="countryDropDown" value="#{addressController.selectedIsoCountry}" >
<p:ajax listener="#{addressController.onCountryChange}" update="stateDropDown" />
<f:selectItem itemValue="" itemLabel="Select a country"/>
<f:selectItems value="#{addressController.countryMap}" />
</p:selectOneMenu>
<p:outputLabel for="stateDropDown" value="State" />
<p:selectOneMenu id="stateDropDown" value="#{addressController.state}" >
<f:selectItem itemValue="" itemLabel="Selecione a State" />
<f:selectItems value="#{addressController.stateMap}" />
</p:selectOneMenu>
</h:panelGrid>
</h:form>
</body>
</html>
And this is AddressController.java
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
import br.com.azulseguros.ejb.CountryEJB;
import br.com.azulseguros.entity.Country;
import br.com.azulseguros.entity.State;
#SessionScoped
#Named
public class AddressController {
#EJB
private CountryEJB countryEJB;
private String selectedIsoCountry = null;
private State state = null;
private Map<String, String> countryMap = null;
private Map<String, String> stateMap = null;
#PostConstruct
private void init() {
Map<String, String> retorno = new TreeMap<String, String>();
for (Country _tmp : countryEJB.findAll()) {
retorno.put(_tmp.getName(), _tmp.getIso());
}
countryMap = retorno;
}
public Map<String, String> getCountryMap() {
return countryMap;
}
public Map<String, String> getStateMap() {
return stateMap;
}
public String getSelectedIsoCountry() {
return selectedIsoCountry;
}
public State getState() {
return state;
}
public void setSelectedIsoCountry(String selectedIsoCountry) {
this.selectedIsoCountry = selectedIsoCountry;
}
public void setState(State state) {
this.state = state;
}
public void setCountryMap(Map<String, String> countryMap) {
this.countryMap = countryMap;
}
public void setStateMap(Map<String, String> stateMap) {
this.stateMap = stateMap;
}
public void onCountryChange() {
setStateMap(getStatesFromSelectedCountry());
}
private Map<String, String> getStatesFromSelectedCountry() {
Map<String, String> retorno = new TreeMap<String, String>();
if (selectedIsoCountry != null && !selectedIsoCountry.equals("")) {
for (State _tmp : countryEJB.findByIso(selectedIsoCountry).getStates()) {
retorno.put(_tmp.getName(), _tmp.getFu());
}
}
return retorno;
}
}
The EJB responsibile for finding all countries and states is working fine. There is a lot of issues with that and I do not know what to do to fix it.
1 - After I invoke the page for the first time it calls the init method 10 times;
2 - After that it evoked the method getStatesFromSelectedCountry even not choosing any country from the 1st drop down and after that evokes the init method again;
3 - When i choose a country it evokes 7 times the init method and then the getStatesFromSelectedCountry() but the selectedIsoCountry is null.
The bean's init method is invoked many times because you have defined the bean both as a CDI bean using javax.inject.Named, without scope, and as a JSF Managed Bean using javax.faces.bean.SessionScoped; if you intended to use CDI beans, simply replace the latter annotation with javax.enterprise.context.SessionScoped. See Why are there different bean management annotations
From a CDI point of view, the bean is by default RequestScoped, this should explain also the second issue you are experiencing.
Concerning the third issue, see this Q/A:
Why is the getter called so many times by the rendered attribute?
Why JSF calls getters multiple times
I still have the problem that i need the old and the new value of an inputtext component on a blur event. But i don't see a way to get the blur event without the use of "p:ajax".
Are there any other ways to get the old and new value?
xhtml:
<h:form>
<p:inputtext value="#{myController.value}"
valueChangeListener="#{myController.handleEvent}">
<p:ajax event="blur" listener="#{myController.handleEvent}" />
</p:inputtext>
</h:form>
Controller:
#ViewAccessScoped
#Named("myController")
public class MyController implements Serializable {
private static final long serialVersionUID = 8736461860325705841L;
public void intervalChanged(AjaxBehaviorEvent event) {
// I need the old value here!
}
public void intervalChanged(ValueChangeEvent event) {
// Here i got the old value but this listener method is not invoked on blur
}
}
This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 7 years ago.
I am currently working on a small Voting-Tool with JSF, Primefaces, CDI etc... The main purpose of that is to improve my programming skills and learning a bit about Java EE.
In the tool, one can collect PC-games and create Game-Votings, where people (Lan-Party) can (or should be able to) vote for a game.
For the Voting-Form I want to use Primefaces "SelectOneListBox". It gets the List of Games from a #ApplicationScoped Bean that handels the Voting ("votingListProducer") and looks as follows:
<h:form id="votingFormID">
<p:selectOneListbox value="#{votingListController.selectedGame}" converter="#{gameConverter}"
var="g" showCheckbox="true" style="width:500px;" >
<f:selectItems value="#{votingListProducer.voting.gameList}" var="game" itemLabel="#{game.name}" itemValue="#{game}" />
<p:column>
<p:graphicImage value="resources/images/#{g.imgSrc}" width="40"/>
</p:column>
<p:column>
#{g.name}
</p:column>
<p:column>
#{g.version}
</p:column>
</p:selectOneListbox>
<p:commandButton value="Submit" action="#{votingListController.doAddVoteAktion}" />
<p:commandButton value="Zeige selektierte List" action="#{votingListController.doPrintSelectedGame}"/>
</h:form>
When I call this view, the correct List of Games is displayed. But when I select one and click on "Submit" the converter converts it right, because it returns the correct Game, but in the Controller the attribute "selectedGame" will not be set to this Game. And also the Methods are not called.
Here is the Controller:
#SessionScoped
#Named
public class VotingListController implements Serializable{
private static final long serialVersionUID = -7222543653854660316L;
private Game selectedGame;
#Inject #AddedChoice
private Event<Game> addChoiceEventSrc;
public void doAddVoteAktion (){
if (selectedGame!=null){
addChoiceEventSrc.fire(selectedGame);
}
}
public void doPrintSelectedGame(){
if (selectedGame!=null){
System.out.println(selectedGame.getName());
}
}
public Game getSelectedGame() {
return selectedGame;
}
public void setSelectedGame(Game selectedGame) {
this.selectedGame = selectedGame;
}
}
Do you have any Idea why this does not work?
Thank You!
Edit: Converter-Code
#RequestScoped
#Named
public class GameConverter implements Converter{
#Inject
private GameListManager gameListManager;
#Override
public Object getAsObject(FacesContext fc, UIComponent ui, String value) {
for (Game g : gameListManager.getGameList()){
if (g.getGameId().toString().equalsIgnoreCase(value)){
System.out.println ("I receive: "+g.getName());
return g;
}
}
return null;
}
#Override
public String getAsString(FacesContext fc, UIComponent ui, Object value) {
if (value!=null){
Game game = (Game) value;
String res = game.getGameId().toString();
System.out.println(res);
return res;
}
return null;
}
}
Try:
<p:commandButton value="Submit" actionListener="#{votingListController.doAddVoteAktion}"
process=":votingFormID"/>
Maybe it can be a error when your converter calls getAsObject, can you post the converter code?
Change your action Listener definition to
public void doAddVoteAktion (ActionEvent event){
if (selectedGame!=null){
addChoiceEventSrc.fire(selectedGame);
}
}
And
<p:commandButton value="Submit" actionListener="#votingListController.doAddVoteAktion}" ajax="true" process="#this"/>
I am trying to learn PF so I started with displaying datatable first and navigating to next page on rowClick passing parameters, but got stuck with the following error. I found similar problem for that question but no luck yet. I hope somebody will help me out.
I am getting following error:
DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.
Caused by:
javax.faces.FacesException - DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.
my Page:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Primefaces 3.1</title>
</h:head>
<h:body>
<h:form id="form">
<p:dataTable value="#{tableBean.cars}" var="var" rowkey="#{var.model}"
selection="#{tableBean.car}" selectionMode="single">
<p:column> <f:facet name="header">
<h:outputText styleClass="outputText" value="Model"></h:outputText>
</f:facet>
<h:outputText styleClass="outputText"
value="#{var.model}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText styleClass="outputText" value="Color"></h:outputText>
</f:facet>
<h:outputText styleClass="outputText"
value="#{var.randomColor}"></h:outputText>
</p:column></p:dataTable>
</h:form>
</h:body>
</html>
my bean Classes:
#ManagedBean
#ViewScoped
public class TableBean extends ListDataModel<Car> implements SelectableDataModel<Car>{
private List<Car> cars;
private Car car;
public List<Car> getCars() {
cars = new ArrayList<Car>();
Car car1 = new Car();
car1.setModel("BMW");
car1.setRandomColor("Black");
cars.add(car1);
Car car2 = new Car();
car2.setModel("Audi");
car2.setRandomColor("White");
cars.add(car2);
return cars;
}
public String onRowSelect(){
System.out.println("Row Click!!!");
return "otherpage";//Does this nav works???if not how???
}
public Car getCar() {
return car;
}
#Override
public Car getRowData(String pArg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Object getRowKey(Car pArg0) {
// TODO Auto-generated method stub
return null;
}
}
OtherBean:
public class Car{
private String model;
private String randomColor;
public String getRandomColor() {
return randomColor;
}
public void setRandomColor(String pRandomColor) {
randomColor = pRandomColor;
}
public String getModel() {
return model;
}
public void setModel(String pModel) {
model = pModel;
}
}
The #{tableBean.cars} must implement SelectableDataModel if you don't specify the rowKey attribute on the <p:dataTable>.
You have however implemented it on the #{tableBean} instead. This is not right. You can find correct examples in the PrimeFaces showcase. Basically, your TableBean class must look like this according to the showcase code example:
#ManagedBean
#ViewScoped
public class TableBean implements Serializable {
private List<Car> cars;
private Car car;
private CarDataModel carsModel;
public TableBean() {
cars = new ArrayList<Car>();
// Populate cars here and thus NOT in the getter method!
carsModel = new CarDataModel(cars);
}
// ...
}
Where the CarDataModel look like this (again, just copied from PrimeFaces showcase code example):
public class CarDataModel extends ListDataModel<Car> implements SelectableDataModel<Car> {
public CarDataModel() {
}
public CarDataModel(List<Car> data) {
super(data);
}
#Override
public Car getRowData(String rowKey) {
List<Car> cars = (List<Car>) getWrappedData();
for(Car car : cars) {
if(car.getModel().equals(rowKey))
return car;
}
return null;
}
#Override
public Object getRowKey(Car car) {
return car.getModel();
}
}
Finally use #{tableBean.carsModel} instead of #{tableBean.cars} as value of <p:dataTable>. Exactly as in the showcase example.
<p:dataTable value="#{tableBean.carsModel}" var="car" ... />
Another, easier, way is to just specify the rowKey attribute on the <p:dataTable>.
<p:dataTable value="#{tableBean.cars}" var="car" rowKey="#{car.model}" ... />
This way you don't need the whole SelectableDataModel. You only need to ensure that it's never null and always unique across the rows. See also DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled, but I have already defined rowKey.
Ensure to set the rowKey parameter in the bean method that populates the "value=.." of the datatable. Mine returned this error because the rowKey was null.
It worked for my project using a composite key for rowkey e.g.: rowKey="#{course.getCompositeKey()
Since I didn't have a compositeKey variable I simply created one in my Course Class (in your case the Car Class). The 2 primary keys are strings so I just said this.compositeKey=this.courseNumber+this.product--you just use whatever 2 primary keys are in your Car class instead of courseNumber and product.
Youd on't have to implement the datamodal in your managedbean, just specify in the proprety of the datatable the "rowkey" like this: rowkey="{mbean.atribute1}"
-- atribute1 must be diplayed in the data table column.
Must