Dynamically add and remove inputText field using primefaces - jsf

I have using primefaces in my project. I need to create and delete field dynamically on my project. Here I am going to attached my code please find it
my xhtml page is
<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:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:panelGrid border="0" columns="3" cellpadding="4" columnClasses="control-label">
<h:panelGrid columns="3" cellpadding="4" >
<h:outputText value="Individual Email"/>
<div>
<h:dataTable value="#{utilBean.attachments}" var="attachmentBean" binding="#{utilBean.data}" id="attachments">
<h:column>
<h:inputText id="attachment" value="#{attachmentBean.emailAddress}" binding="#{utilBean.attachment}"/>
</h:column>
<h:column>
<h:commandButton id="delete" value="Delete" immediate="true" actionListener="#{utilBean.deleteAddress}"/>
</h:column>
</h:dataTable>
<h:commandButton id="add" value="Add Email Address" immediate="true" actionListener="#{utilBean.addAddress}" />
</div>
<br/>
</h:panelGrid>
</h:panelGrid>
</ui:composition>
My Bean Is:
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIData;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
#ManagedBean
#SessionScoped
public class UtilBean{
private UIData data=null;
private UIInput attachment = null;
private List<AttachmentBean> attachments = new ArrayList<AttachmentBean>();
public void addAddress(ActionEvent event){
attachments.add(new AttachmentBean());
this.updateAddresses();
FacesContext.getCurrentInstance().renderResponse();
System.out.println("adress size:" + attachments.size());
}
public void deleteAddress(ActionEvent event){
int index = data.getRowIndex();
this.updateAddresses();
this.getAttachments().remove(index);
FacesContext.getCurrentInstance().renderResponse();
}
public void updateAddresses(){
System.out.println("adress sizedfdfdfdf:" + attachments.size());
#SuppressWarnings("unchecked")
List<AttachmentBean> list = (ArrayList<AttachmentBean>)data.getValue();
for(int i =0;i<data.getRowCount();i++){
data.setRowIndex(i);
list.get(i).setEmailAddress((String)getAttachment().getSubmittedValue());
}
data.setRowIndex(0);
}
public UIData getData() {
return data;
}
public void setData(UIData data) {
this.data = data;
}
public UIInput getAttachment() {
return attachment;
}
public void setAttachment(UIInput attachment) {
this.attachment = attachment;
}
public List<AttachmentBean> getAttachments() {
return attachments;
}
public void setAttachments(List<AttachmentBean> attachments) {
this.attachments = attachments;
}
}
And the Attachment Class is
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
#ManagedBean
#SessionScoped
public class AttachmentBean implements Serializable {
private static final long serialVersionUID = 1L;
private String emailAddress;
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public AttachmentBean() {
super();
}
}
I am not able to add textBox by clicking the add button. Please help. Thanks in advance.

You need to put the whole in a <h:form>. See also commandButton/commandLink/ajax action/listener method not invoked or input value not updated.
Another major mistake is here:
<h:dataTable ... binding="#{utilBean.data}">
...
<h:inputText ... binding="#{utilBean.attachment}"/>
Remove those binding attributes. UI components are request scoped and yet you're binding them to a session scoped bean. This would fail hard if you open the same page in multiple browser windows in the same session. See also How does the 'binding' attribute work in JSF? When and how should it be used?.
That said, the #ManagedBean #SessionScoped on AttachmentBean is completely unnecessary. Get rid of those annotations. The #SessionScoped on UtilBean is also rather strange. The #ViewScoped is much better at its place here. See also How to choose the right bean scope?

Related

selectOneRadio lost checked value inside a dataList with pagination

I have this example code,
My xhtml page.
<html 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">
<h:head>
</h:head>
<h:body>
<p:dataList value="#{dataListView.lista}" var="l" type="unordered"
itemType="none" paginator="true" rows="1" styleClass="paginated">
<f:facet name="header">
Paginator
</f:facet>
<p:selectOneRadio id="resposta" value="#{dataListView.resposta}">
<f:selectItem itemLabel="Certo" itemValue="Certo" />
<f:selectItem itemLabel="Errado" itemValue="Errado" />
</p:selectOneRadio>
</p:dataList>
</h:body>
</html>
My Bean
package br.com.so.teste;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import br.com.so.modelo.Questao;
#Named
#ViewScoped
public class DataListView implements Serializable {
private List<String> lista;
private String resposta;
#PostConstruct
public void init() {
lista = new ArrayList<>();
lista.add("1");
lista.add("2");
lista.add("3");
lista.add("4");
lista.add("5");
}
public List<String> getLista() {
return lista;
}
public void setLista(List<String> lista) {
this.lista = lista;
}
public String getResposta() {
return resposta;
}
public void setResposta(String resposta) {
this.resposta = resposta;
}
}
The error appear when i change the page view, in pagination have (1,2,3...) if i check the radio button in page '1' and i go to page '2' and i come back to page '1' the radio button is not checked.
Why does it happen?
How do i fix it?
I need to keep the value checked in the radioButtons.
I resolved using this.
I create 2 SelectoneRadio, one geting the checked value, if exists..
And another only puting the value.
I use Ajax to pass the ID.
If the map contains the id, i use ajax only to update, because the radio set the value directly in the map.
<html 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">
<h:head>
</h:head>
<h:body>
<h:form id="formulario">
<p:dataList value="#{dataListView.lista}" var="l" type="unordered"
itemType="none" paginator="true" rows="1" styleClass="paginated">
<f:facet name="header">
Paginator
</f:facet>
<p:selectOneRadio value="#{dataListView.teste}"
rendered="#{dataListView.resposta[l] == null}">
<p:ajax listener="#{dataListView.processaResposta(l)}" event="click"
update="formulario"></p:ajax>
<f:selectItem itemLabel="Certo" itemValue="Certo" />
<f:selectItem itemLabel="Errado" itemValue="Errado" />
</p:selectOneRadio>
<p:selectOneRadio value="#{dataListView.resposta[l]}"
rendered="#{dataListView.resposta[l] != null}">
<p:ajax event="click" update="formulario"></p:ajax>
<f:selectItem itemLabel="Certo" itemValue="Certo" />
<f:selectItem itemLabel="Errado" itemValue="Errado" />
</p:selectOneRadio>
</p:dataList>
</h:form>
</h:body>
</html>
And in bean...
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class DataListView implements Serializable {
private List<String> lista;
private Map<String, String> resposta;
private String teste;
#PostConstruct
public void init() {
lista = new ArrayList<>();
lista.add("1");
lista.add("2");
lista.add("3");
lista.add("4");
lista.add("5");
resposta = new HashMap<>();
}
public List<String> getLista() {
return lista;
}
public void setLista(List<String> lista) {
this.lista = lista;
}
public Map<String, String> getResposta() {
return resposta;
}
public void setResposta(Map<String, String> resposta) {
this.resposta = resposta;
}
public void processaResposta(String action) {
resposta.put(action, teste);
teste = null;
}
public String getTeste() {
return teste;
}
public void setTeste(String teste) {
this.teste = teste;
}
}
After put a answer and ID, you need to make the value 'teste' null.

value not saving to session bean

I have created a session bean but it seems my <h:selectOneMenu> is not storing the value in the bean. Can someone tell me what I am doing wrong?
In the xhtml navigates to another xhtml that displays the results. I do not have any values in faces-config.xml other than the navigation rules since I think managed bean / session bean annotations can replace that
xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<!-- Using a custom header -->
<ui:include src="/resources/ADTHeader.xhtml" />
<h:body>
<h1>Test</h1>
<h:form>
<h:selectOneMenu id="mypick"
value="#{gridMaster_backing.pickedGrid}"
converter="#{categoryConverter}"
title="ADTF" >
<f:selectItems value="#{gridMaster_backing.gridList}" var="prog" itemValue="#{prog.gridid}" itemLabel="#{prog.gridid} - #{prog.program} - #{prog.project} - #{prog.ci}" />
</h:selectOneMenu>
<br /><br />
<h:button value="View Grid" outcome="result" />
</h:form>
</h:body>
</html>
Session bean:
package edu.adtf.web;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.ejb.EJB;
import com.ray.adtf.ejb.*;
import com.ray.adtf.jpa.Gridmaster;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
#ManagedBean
#SessionScoped
public class gridMaster_backing {
#EJB
private GridMasterBean ejb;
private Collection<Gridmaster> mgrid;
private List gridList = new ArrayList();
// pickedGrid holds value picked from the gridid drop down list
private Long pickedGrid;
public Long getPickedGrid() {
//System.out.println("getPicked Grid");
return pickedGrid;
//return (long) 100;
}
public void setPickedGrid(Long pickedGrid) {
this.pickedGrid = pickedGrid;
}
// returns data to show grid form
public Collection<Gridmaster> getGridmaster(Long vgridid){
mgrid = ejb.getAllGrids(vgridid);
return mgrid;
}
public void setGridList(List gridList) {
this.gridList = gridList;
}
// list for grid list drop down
public List getGridList() {
List gridList2 = ejb.getDisplayGridList();
return gridList2;
}
}
converter:
package edu.adtf.web;
import javax.faces.bean.ManagedBean;
import edu.adtf.jpa.Gridmaster;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#ManagedBean(name = "categoryConverterBean")
#FacesConverter(value = "categoryConverter")
public class CategoryConverter implements Converter{
#PersistenceContext
private transient EntityManager em;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
//System.out.println(em.find(Gridmaster.class, new Long(value)));
return em.find(Gridmaster.class, new Long(value));
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
Gridmaster gridmaster;
gridmaster = (Gridmaster) value;
//System.out.println(String.valueOf(gridmaster.getGridid()));
return String.valueOf(gridmaster.getGridid());
}
}
The problem is in the converter you're using. The field of your managed bean from where you're getting/setting the data is of type Long and the default value for <h:selectOneMenu> is of type String, so you only need to use a Long converter. There's a built-in converter for this case: javax.faces.Long. Make sure you're defining that the itemValue for the <h:selectItems> is type Long as well.
The code should look like this:
<h:selectOneMenu id="mypick"
value="#{gridMaster_backing.pickedGrid}"
converter="javax.faces.Long"
title="ADTF">
<!-- #{prog.gridid} must return Long -->
<f:selectItems
value="#{gridMaster_backing.gridList}"
var="prog"
itemValue="#{prog.gridid}"
itemLabel="#{prog.gridid} - #{prog.program} - #{prog.project} - #{prog.ci}" />
</h:selectOneMenu>

CommandLink doesn't work. Tried everything

it's my first question on the site :) But first, sorry for my bad english, i'm learning :)
Plz, i need your help. I'm blocked with an application in JSF.
I have this
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<body>
<ui:composition template="./defaultTemplate.xhtml">
<ui:define name="content">
<h1 style="margin-bottom: 0px">#{msg.default_2}</h1>
<br/>
<ul style="padding-left: 0px">
<ui:repeat value="#{categoryMB.categories}" var="categorie">
<h:outputLabel value=" -==- " style="color: #FF8620; font-size: 10px; padding-left: 0px"></h:outputLabel>
<h:form>
<h:commandLink value="#{categorie.categoryname}" action="#{categoryMB.getItemsByCat(categorie.categoryid.id)}"/>
</h:form>
</ui:repeat>
</ul>
<ui:repeat value="#{categoryMB.listItems}" var="item">
<div class="itemCategory">
<h:graphicImage class="item-image" url="#{item.urlimage}"/>
<h:outputLabel value="#{item.price} €" class="prix"></h:outputLabel>
<br/>
<h2><h:outputLabel value="#{item.name}"></h:outputLabel></h2>
<br/>
<h:form>
<h:commandLink value="#{msg.default_14}" action="#{itemMB.linkItem(item.id)}"
></h:commandLink>
</h:form>
</div>
</ui:repeat>
</ui:define>
</ui:composition>
</body> </html>
Everything is good, except the second commandLink !
I can't execute the action. I always return on the same page...
I tried everything i could and i read all subjects about that on the site but i can't find a solution. Please, i'm asking you, help me. I'm going to be crazy.
My bean for categoryMB :
package managedBean;
import entityBean.Item;
import entityBean.Translatecategory;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.view.ViewScoped;
import sessionBean.ItemFacadeLocal;
import sessionBean.TranslatecategoryFacadeLocal;
/**
*
* #author Aurélien
*/
#ManagedBean
#ViewScoped
public class CategoryMB {
#EJB
private ItemFacadeLocal itemFacade;
#EJB
private TranslatecategoryFacadeLocal translatecategoryFacade;
#ManagedProperty("#{internationalizationMB}")
private InternationalizationMB language;
private List<Item> listItems;
/**
* Creates a new instance of CategoryMB
*/
public CategoryMB() {
}
public List<Translatecategory> getCategories () {
return translatecategoryFacade.findByLanguage(language.getLocale().getLanguage());
}
public void getItemsByCat (int idCat) {
setListItems(itemFacade.findByCat(idCat));
}
public InternationalizationMB getLanguage() {
return language;
}
public void setLanguage(InternationalizationMB language) {
this.language = language;
}
public List<Item> getListItems() {
return listItems;
}
public void setListItems(List<Item> listItems) {
this.listItems = listItems;
}
}
And my bean for itemMB :
package managedBean;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
#ManagedBean
#SessionScoped
public class ItemMB implements Serializable {
private int idItem;
/**
* Creates a new instance of ItemMB
*/
public ItemMB() {
}
public int getIdItem() {
return idItem;
}
public void setIdItem(int idItem) {
this.idItem = idItem;
}
public String linkItem(int id)
{
setIdItem(id);
return "item";
}
}
You're mixing CDI #SessionScoped with JSF 2.x #SessionScoped. This is noted in your imports:
import javax.enterprise.context.SessionScoped;
#ManagedBean
#SessionScoped
public class ItemMB implements Serializable {
//...
}
This makes your managed bean to have the default scope, which in JSF 2 is #RequestScoped, so your managed bean will be re created on every request.
Fix your import to:
import javax.faces.bean.SessionScoped;
If you happen to use JSF 2.2.x, start working everything with CDI 1.1. Use #Named for your managed beans and use javax.faces.view.ViewScoped for #ViewScoped.
More info:
What's new in JSF 2.2. CDI compatible #ViewScoped

f:setPropertyActionListener always setting null

I'm trying to put the currently iterated <p:dataTable var> as a property of a managed bean using <f:setPropertyActionListener>. However, it is always set as null.
The view, dentistas.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/template.xhtml">
<ui:define name="content">
<h:form id="formDentistas">
<p:growl autoUpdate="true" />
<p:commandButton icon="ui-icon-plus" value="Cadastrar"
id="cadastrar" oncomplete="dialogCadastrar.show()" />
<p:dataTable var="dentista" value="#{dentistaMB.dentistas}"
paginator="true" emptyMessage="Não foi encontrado nenhum registro"
rows="10" id="dataTableDentistas">
<f:facet name="header">Lista de Dentistas</f:facet>
<p:column headerText="Nome" sortBy="nome" filterBy="nome" id="nome"
width="200px">
#{dentista.pessoaFisica.nome}
</p:column>
<p:column headerText="Data Nascimento" sortBy="dataNascimento"
filterBy="dataNascimento" id="dataNascimento" width="60px">
#{dentista.pessoaFisica.dataNascimento}
</p:column>
<p:column headerText="CRO" sortBy="cro" filterBy="cro" id="cro"
width="60px">
#{dentista.cro}
</p:column>
<p:column headerText="Ações" style="width:50px;">
<p:commandButton value="Alterar" icon="ui-icon-pencil">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
<p:commandButton value="Remover" icon="ui-icon-trash"
actionListener="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<ui:include src="/tabelas/dialog_insert_dentista.xhtml" />
</ui:define>
</ui:composition>
</h:body>
</html>
The managed bean, DentistaMBImpl:
package br.com.odontonew.mb;
import java.util.List;
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.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.FacesConverter;
import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import br.com.odontonew.bean.Dentista;
import br.com.odontonew.bean.EstadoCivil;
import br.com.odontonew.bean.PessoaFisica;
import br.com.odontonew.bean.Sexo;
import br.com.odontonew.bean.SituacaoPessoa;
import br.com.odontonew.bean.Uf;
import br.com.odontonew.bo.BasicBO;
import br.com.odontonew.exception.BOException;
#ManagedBean(name = "dentistaMB")
#ViewScoped
public class DentistaMBImpl extends BasicMBImpl {
private Logger logger = Logger.getLogger(DentistaMBImpl.class);
#ManagedProperty("#{dentistaBO}")
private BasicBO dentistaBO;
private Dentista dentista;
private Dentista selectedDentista;
private List<Dentista> dentistas;
// Lists
private List<EstadoCivil> estadosCivis;
private List<SituacaoPessoa> situacoesPessoa;
private List<Sexo> sexos;
private List<Uf> ufs;
#PostConstruct
public void init() {
dentista = new Dentista();
dentista.setPessoaFisica(new PessoaFisica());
dentista.getPessoaFisica().setSexo(new Sexo());
dentista.getPessoaFisica().setEstadoCivil(new EstadoCivil());
dentista.getPessoaFisica().setSituacao(new SituacaoPessoa());
dentista.getPessoaFisica().setUf(new Uf());
estadosCivis = (List<EstadoCivil>) dentistaBO
.findByNamedQuery(EstadoCivil.FIND_ALL);
situacoesPessoa = (List<SituacaoPessoa>) dentistaBO
.findByNamedQuery(SituacaoPessoa.FIND_ALL);
sexos = (List<Sexo>) dentistaBO.findByNamedQuery(Sexo.FIND_ALL);
ufs = (List<Uf>) dentistaBO.findByNamedQuery(Uf.FIND_ALL);
}
public void salvar(ActionEvent event) {
try {
dentista = (Dentista) dentistaBO.save(dentista);
addInfoMessage("Dentista salvo com sucesso");
RequestContext.getCurrentInstance().execute(
"dialogCadastrar.hide()");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public void atualizar(ActionEvent event) {
try {
dentistaBO.update(selectedDentista);
addInfoMessage("Dentista atualizado com sucesso");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public void deletar(ActionEvent event) {
try {
dentistaBO.delete(selectedDentista);
addInfoMessage("Dentista deletado com sucesso");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public List<Dentista> getDentistas() {
try {
if (dentistas == null)
dentistas = (List<Dentista>) dentistaBO
.findByNamedQuery(Dentista.FIND_ALL_COMPLETO);
return dentistas;
} catch (BOException e) {
addErrorMessage(e.getMessage());
return null;
}
}
/* gets and sets */
public Dentista getSelectedDentista() {
return selectedDentista;
}
public void setSelectedDentista(Dentista selectedDentista) {
this.selectedDentista = selectedDentista;
}
public Dentista getDentista() {
return dentista;
}
public void setDentista(Dentista dentista) {
this.dentista = dentista;
}
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public List<EstadoCivil> getEstadosCivis() {
return estadosCivis;
}
public void setEstadosCivis(List<EstadoCivil> estadosCivis) {
this.estadosCivis = estadosCivis;
}
public List<SituacaoPessoa> getSituacoesPessoa() {
return situacoesPessoa;
}
public void setSituacoesPessoa(List<SituacaoPessoa> situacoesPessoa) {
this.situacoesPessoa = situacoesPessoa;
}
public List<Sexo> getSexos() {
return sexos;
}
public void setSexos(List<Sexo> sexos) {
this.sexos = sexos;
}
public void setDentistas(List<Dentista> dentistas) {
this.dentistas = dentistas;
}
public List<Uf> getUfs() {
return ufs;
}
public void setUfs(List<Uf> ufs) {
this.ufs = ufs;
}
public BasicBO getDentistaBO() {
return dentistaBO;
}
public void setDentistaBO(BasicBO dentistaBO) {
this.dentistaBO = dentistaBO;
}
}
Here,
<p:commandButton value="Remover" icon="ui-icon-trash"
actionListener="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
you're performing the delete in an actionListener method instead of an action method. This is not right. Business actions should be performed in the action method. All action listeners, including the <f:setPropertyActionListener>, are invoked before action method in the very same order as they are declared and assigned on the command component. So, in effects, the delete is first invoked and then the property is set. That explains why the property is null during the delete.
The fix is simple: make it a real action method:
<p:commandButton value="Remover" icon="ui-icon-trash"
action="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
Don't forget to remove the ActionEvent argument:
public void deletar() {
// ...
}
See also:
Differences between action and actionListener
Unrelated to the concrete problem, if you happen to target a Servlet 3.0 / EL 2.2 compatible container, then you can even get rid of that <f:setPropertyActionListener> altogether:
<p:commandButton value="Remover" icon="ui-icon-trash"
action="#{dentistaMB.deletar(dentista)}" />
With:
public void deletar(Dentista selectedDentista) {
// ...
}
See also point 3 of How can I pass selected row to commandLink inside dataTable?

JSF 2.1: h:dataTable does not refresh data

I've set-up a system which allows you to view categories of IT-equipment and their subcategories.
Now I want to be able to add a subcategory to a parentcategory via JPA.
The problem is that my entity is persisted correctly, but it does not show up in the dataTable. I need to start a new session to make it visible.
This is my xhtml-page:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>Kategorie Tester</title>
<h:outputStylesheet library="css" name="tables.css"/>
<f:metadata>
<f:event type="preRenderView" listener="#{kategorieController.beforeRenderLoadKat}"/>
</f:metadata>
</h:head>
<h:body>
<h:form>
<h:dataTable value="#{kategorieController.reload()}"
var="kat"
styleClass="katview">
<h:column>
<f:facet name="header">
Kategorie
</f:facet>
<h:outputText value="#{kat.titel}"/>
</h:column>
<h:column>
<f:facet name="header">
Unterkategorie
</f:facet>
<h:selectManyCheckbox layout="pageDirection">
<f:selectItems value="#{kat.unterkategorieList}"
var="sub"
itemLabel="#{sub.titel}"
itemValue="#{sub.idunterkategorie}"/>
</h:selectManyCheckbox>
</h:column>
</h:dataTable>
<h:panelGroup>
<h:inputText value="#{kategorieController.titel}"/>
<h:selectOneMenu value="#{kategorieController.kategorie.idkategorie}">
<f:selectItems id="kategorie" value="#{kategorieController.allKats}"
var="kati"
itemLabel="#{kati.titel}"
itemValue="#{kati.idkategorie}"/>
</h:selectOneMenu>
<h:commandButton value="Add" action="#{kategorieController.addSub()}"/>
</h:panelGroup>
</h:form>
</h:body>
</html>
And these are my controllers in order to persist and relaod the data:
KategorieController:
package controller;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import model.Kategorie;
import model.Unterkategorie;
#ManagedBean
#SessionScoped
public class KategorieController implements Serializable {
#Inject
private KategorieService katService;
private List<Kategorie> allKats;
// Hinzufügen
private Unterkategorie subkategorie;
private Kategorie kategorie;
private String titel;
public void beforeRenderLoadKat(final ComponentSystemEvent event) {
if (allKats != null) {
allKats.clear();
}
allKats = katService.getAll();
subkategorie = new Unterkategorie();
kategorie = new Kategorie();
}
public void addSub() {
subkategorie.setKategorieId(kategorie);
subkategorie.setTitel(titel);
katService.addSub(this.subkategorie);
}
// GETTERS AND SETTERS
}
KategorieService:
package controller;
import java.io.Serializable;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import model.Kategorie;
import model.Unterkategorie;
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class KategorieService implements Serializable {
#Inject
private KategorieFacade katFacade;
public List<Kategorie> getAll() {
return katFacade.getAll();
}
public List<Kategorie> addSub(final Unterkategorie sub) {
return katFacade.addSub(sub);
}
}
KategorieFacade:
package controller;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import model.Kategorie;
import model.Unterkategorie;
public class KategorieFacade {
#PersistenceContext
private EntityManager em;
public List<Kategorie> getAll() {
TypedQuery<Kategorie> query = em.createNamedQuery("Kategorie.findAll", Kategorie.class);
return query.getResultList();
}
public List<Kategorie> addSub(final Unterkategorie sub) {
em.persist(sub);
em.flush();
return getAll();
}
}
Any help is appreciated!
Thank you in advance!
Why don't you try to refresh the collection in the addSub() method:
public void addSub() {
subkategorie.setKategorieId(kategorie);
subkategorie.setTitel(titel);
allKats.clear();
allKats.addAll(katService.addSub(this.subkategorie));
}
And completely unrelated to the original question: you're interchanging the concepts Service and Facade with each other.
But I would suggest that instead of putting the getAll() into addSub(), make it void and do another call from the client to the service after doing the insertion.

Resources