I've a problem that I can't find any solutions for. I'm using JSF 2.1 and primefaces, and I have a bean that contains a boolean variable with a getter and setter. I use p:ajax to call a method that updates the boolean value when p:graphicImage is updated.
During debugging this work correctly; p:graphicImage has the attribute rendered set to the boolean variable of the bean. When the image is updated by ajax however, the getter is called and returns the correct value, true, but image is not rendered!
This is my code:
<p:panel>
<p:panelGrid columns="3" cellpadding="5">
<p:row>
<p:column>
<p:outputLabel value="#{msg.username}"></p:outputLabel>
</p:column>
<p:column>
<h:inputText id="username" value="#{user.userName}">
<p:ajax listener="#{registationController.checkUserName}" event="blur" update="imgControl"/>
</h:inputText>
</p:column>
<p:column id="imgControl">
<p:graphicImage
value="/resources/images/#{registationController.userNameAvailable}"
height="24px" rendered="#{registationController.imgShow}"/>
</p:column>
<p:message for="username" id="msgUsername" severity="info"></p:message>
</p:row>
</p:panelGrid>
</p:panel>
And this is the bean:
#ManagedBean(name="registationController")
public class RegistrationController implements Serializable{
private static final long serialVersionUID = 1086976296682850824L;
#ManagedProperty(value="#{user}")
private User usr;
private MyLogger log;
private String userNameAvailable=null;
private boolean imgShow=false;
public void checkUserName(AjaxBehaviorEvent event){
User tempUser=null;
UserDAOImpl userDAOImpl=new UserDAOImpl();
if(usr.getUserName()!="" && usr.getUserName()!=null){
tempUser=userDAOImpl.selectUserByUsername(usr.getUserName());
imgShow=true;
} else {
imgShow=false;
}
if(tempUser!=null){
userNameAvailable="no.png";
} else{
userNameAvailable= "yes.png";
}
}
public boolean isImgShow() {
return imgShow;
}
others methods...
}
Any ideas why this doesn't works?
Thanks,
John
Related
I have an application that uses Spring Boot and jsf. In case I named #Component class the same as the name of the DataModel class in jsf, in the .xhtml file when calling the DataModel's property, it is interpreted as the #Component class.
In the example below although cardDataModel always has data, it seems that card.employeeName is accessing #Component("card") instead of cardDataModel. Just to be sure I remove #Component("card") and the error goes away.
Can anyone help me explain why? Is there a way to limit #Component class? only let it use in Bean only. Or if it can't be limited, is there any warning mechanism when naming the same #Component or DataModel.
Thank you very much
CAP10Bean.java
#Controller("CAP10Bean")
public class CAP10Bean implements Serializable {
private DataModel cardDataModel = new ListDataModel();
public void initCAP10Bean(){
// assume that there is always data, Card.employeeName is not null
createCardList();
}
private void createCardList(){
List<Card> cardList = this.Service.findCard(ID);
this.cardDataModel.setWrappedData(cardList);
}
}
}
CAP1001l.xhtml
<rich:dataTable value="#{CAP40Bean.cardDataModel}" var="card" rowKeyVar="rowIndex">
<f:facet name="header">
<rich:columnGroup>
<rich:column>
<h:outputText value="employee"/>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<!-- ERROR -> card.employeeName is null -->
<h:outputText value="#{card.employeeName}" rendered="#{card.employeeName != null}" />
</rich:column>
</rich:dataTable>
Card.java
#Component("card")
public class Card implements java.io.Serializable {
private String employeeName;
}
WHAT I HAVE:
A basic data-table which, for the sake of simplicity, only shows the amount of items of a certain customer-order.
PROBLEM:
When I click the cell, the <p:inputText> appears, I am able to enter a number(e.g.: 3). When I press enter, the old number (e.g: 42) appears within the <h:outputText>. If I click the cell again the edited number (3) appears again. And most importantly the public void onCellEdit(CellEditEvent event) method is NOT fired.
WHAT HAVE I TRIED:
I have created another basic web-application in which there is only one editable <p:dataTable> (as I want it) and in this project the listener fires and I simply don't get what is different. For the sake of simplicity of this question I will not add the code of the other project.
Additionally I have tried to apply the (not) accepted answer to this question but it did not work either.
QUESTION:
Why does the listener not fire ? What might be the reason (or reasons)? Yes, I am a beginner, so any hint would be very welcome.
Thank You !
xhtml with the table
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
template="/templates/template.xhtml">
<ui:define name="metadata"/>
<ui:define name="content">
<h:form id="lastOrders">
<p:dataTable id="orders"
var="item"
value="#{editController.items}"
emptyMessage="Der Kunde hat noch keine Aufträge!"
style="size: 30px"
editable="true"
editMode="cell">
<p:ajax event="cellEdit" listener="#{editController.onCellEdit}" update=":mainForm:lastOrders:orders"/>
<f:facet name="header">
<p:outputPanel>
<h:outputText value="#{userController.customer.name}" />
</p:outputPanel>
<p:outputPanel>
<h:outputText value="#{oldOrdersController.order.date}">
<f:convertDateTime pattern="dd.MM.yy" />
</h:outputText>
</p:outputPanel>
</f:facet>
<p:column headerText="Amount">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.amount}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{item.amount}"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
This is the EditController
package com.forall.laundry.controller.edit;
import com.forall.laundry.controller.OldOrdersController;
import com.forall.laundry.model.Item;
import com.forall.laundry.service.ItemService;
import com.forall.laundry.service.ProductService;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.event.CellEditEvent;
#Named
#ViewScoped
public class EditController implements Serializable{
#EJB
private ItemService itemService;
#EJB
private ProductService productService;
#Inject
private OldOrdersController oc;
private List<Item> items;
#PostConstruct
public void init(){
items = itemService.getItemsFrom(oc.getOrder());
}
public void onCellEdit(CellEditEvent event) {
System.out.println("TEST"); // NOT FIRED (i know sysout is not good but no matter what I do here, nothing happens.
}
public ItemService getItemService() {
return itemService;
}
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
public OldOrdersController getOc() {
return oc;
}
public void setOc(OldOrdersController oc) {
this.oc = oc;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public ProductService getProductService() {
return productService;
}
public void setProductService(ProductService productService) {
this.productService = productService;
}
}
Comment to the solution or workaround:
In the PrimeFaces showcase it is suggested to use <p:ajax event="cellEdit" listener="#{dtEditView.onCellEdit}" update=":form:msgs" /> but for reasons which are unknown to me the event is not fired and the onCellEdit-method is not called. Therefore I have researched other approaches to fire events and I ended up with the solution below in which I pass the object itself which was changed, rather than the event.
I still don't know why the original code does not work.
Snippet:
<p:column headerText="Produkt">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.name}"/>
</f:facet>
<f:facet name="input">
<h:inputText id="modelInput" value="#{item.name}">
<f:ajax execute="modelInput" event="change" listener="#{editController.onCellEdit(item)}" render=":mainForm:lastOrders:orders"/>
</h:inputText>
</f:facet>
</p:cellEditor>
</p:column>
Bean-Method:
public void onCellEdit(Item item) {
//stuff
}
My goal is to get the selected value of type Sistema, so I can update a datatable and another SelectOneMenu.
Whenever a value is selected the ajax tag behaves correctly, and calls configura(), however my sistemaSelecionado (wich is an Object in Bean)always return as null to my Backing Bean.
The converter is working fine in another page with the same class Sistema. But it doesn't fire on this specific page.
This is the xhtml page
<div>
<p:outputLabel title="Sistema"></p:outputLabel>
</div>
<div>
<p:selectOneMenu id="selectOneMenu"
value="#{permissaoListBean.sistemaSelecionado}"
converter="entityConverter">
<p:ajax event="change" listener="#{permissaoListBean.configura}"
update="selectOneMenuGrupo,secoes"></p:ajax>
<f:selectItem itemLabel="Selecione" itemValue="" />
<f:selectItems value="#{permissaoListBean.listaSistema}"
var="sistema" itemLabel="#{sistema.nome}" itemValue="#{sistema}">
</f:selectItems>
</p:selectOneMenu>
</div>
Here is my Backing Bean
#Component("permissaoListBean")
#Scope("session")
public class PermissaoListBean {
private List<Sistema> listaSistema = new ArrayList<Sistema>();
//Service das entidades
#Autowired
private SistemaService sistema;
#Autowired
private GrupoService grupo;
#Autowired
private SecaoService secao;
//Objetos da view
private Sistema sistemaSelecionado;
private Grupo grupoSelecionado;
private List<Secao> secaoSelecionada = new ArrayList<Secao>();
private LazyDataModel<Secao> modelo ;
public void populaSistema(){
listaSistema = sistema.findAll();
}
public void configura(){
populaGrupo();
populaSecao();
}
public void populaGrupo(){
setListaGrupo(grupo.findBySistema(sistemaSelecionado));
}
//dataTable lazyLoad code
//end of lazyload
public List<Sistema> getListaSistema() {
setListaSistema(sistema.findAll());
return listaSistema;
}
public void setListaSistema(List<Sistema> listaSistema) {
this.listaSistema = listaSistema;
}
//getters and setters
I have bean "RichFacesTreeNodeBean" with property "newItemInfo", and I call modal panel with inputTextArea, which must contain actual value of that property, but it contains the first value of property all the time. Here is the part of index.xhtml:
<rich:popupPanel id="editPanel">
<h:form>
<h:inputTextarea value="#{richFacesTreeNodeBean.newItemInfo}" />
<!-- some buttons -->
</h:form>
</rich:popupPanel>
And RichFacesTreeNodeBean.java:
#ManagedBean
#ViewScoped
public class RichFacesTreeNodeBean {
private String newItemInfo;
public String getNewItemInfo() {
return newItemInfo;
}
How to fix this?
<h:form>
<a4j:outputPanel layout="block" ajaxRendered="true">
<h:inputTextarea value="#{richFacesTreeNodeBean.newItemInfo}" />
</a4j:outputPanel>
</h:form>
It works.
Im trying out an example with EJB Session Beans. I wanna see the differences them. My basic projects diagram is below ;
http://img109.imageshack.us/img109/8262/85220418.png
Project is like a shopping cart. When i invoke to the managed bean to get result of added Urun objects via injected EJB, result list must be last Urun object. Cause my EJB is #Stateless bean. But, when i run the application, it keeps the all new added Urun object. But it is Stateless, it must keep the last Urun object in every action. And then, when i open the application page in other web browser, it list the before added Urun object's list. But managed bean and Ejb is Stateless in my model. But it acts a Singleton bean. Where is my problem?
#Stateless
public class AlisverisSepetiEJB {
List<Urun> urunler=new ArrayList<>();
public List<Urun> getUrunler() {
return urunler;
}
public void setUrunler(List<Urun> urunler) {
this.urunler = urunler;
}
public void urunEkle(Urun urun){
urunler.add(urun);
}
}
#ManagedBean(name="bean")
#RequestScoped
public class JSFYonetimliNesne {
public JSFYonetimliNesne(){
System.out.println("Yönetimli nesne çalıştı");
}
#EJB
AlisverisSepetiEJB alisverisSepeti;
Urun urun=new Urun();
List<Urun> urunler;
public List<Urun> getUrunler() {
return alisverisSepeti.getUrunler();
}
public void setUrunler(List<Urun> urunler) {
this.urunler = urunler;
}
public Urun getUrun() {
return urun;
}
public void setUrun(Urun urun) {
this.urun = urun;
}
public void sepeteKoy(){
alisverisSepeti.urunEkle(urun);
urun=new Urun();
}
}
public class Urun {
String urunAdi;
Long fiyat;
Long gramaj;
public Long getFiyat() {
return fiyat;
}
public void setFiyat(Long fiyat) {
this.fiyat = fiyat;
}
public Long getGramaj() {
return gramaj;
}
public void setGramaj(Long gramaj) {
this.gramaj = gramaj;
}
public String getUrunAdi() {
return urunAdi;
}
public void setUrunAdi(String urunAdi) {
this.urunAdi = urunAdi;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Alışveriş Sepeti</title>
</h:head>
<h:body>
Alışveriş Sepeti
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="Ürün adı : "/>
<h:inputText value="#{bean.urun.urunAdi}"/>
<h:outputLabel value="Ürün fiyatı : "/>
<h:inputText value="#{bean.urun.fiyat}"/>
<h:outputLabel value="ÜRün gramajı : "/>
<h:inputText value="#{bean.urun.gramaj}"/>
</h:panelGrid>
<h:commandButton action="#{bean.sepeteKoy}" value="Sepete Ekle"/>
<br><h:outputLabel value="Sepetteki Ürünler"/></br>
<h:dataTable value="#{bean.urunler}" var="item" border="1">
<h:column >
<f:facet name="header">
<h:outputLabel value="Ürün adı"/>
</f:facet>
<h:outputText value="#{item.urunAdi}"/>
</h:column>
<h:column >
<f:facet name="header">
<h:outputLabel value="Ürün fiyatı"/>
</f:facet>
<h:outputText value="#{item.fiyat}"/>
</h:column>
<h:column >
<f:facet name="header">
<h:outputLabel value="Ürün gramajı"/>
</f:facet>
<h:outputText value="#{item.gramaj}"/>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
It's quite possible that the same instance of AlisverisSepetiEJB is being shared between invocations (the container can do this, it's perfectly legal). Precisely because of the stateless nature of a #Stateless EJB, you should not declare instance attributes in it!
Remove the List<Urun> urunler = new ArrayList<>(); declaration and all associated methods, think of a stateless bean as a class where all its methods are static - meaning, that they can't use any instance attributes and must be completely independent of instance data; if any state needs to be maintained between calls, then it must be passed along as parameters from the point where the EJB is being invoked. The only instance variables allowed in a #Stateless EJB are attributes which are themselves stateless and/or immutable.
If you need to maintain the state of the shopping cart between invocations, you'll have to keep it elsewhere in a stateful context (say, the Session context of a web application) or mark the EJB as #Stateful.