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.
Related
I have two dropdowns: One is implemented using a selectOneMenu component and the other is implemented with selectCheckboxMenu.
When selecting an option in the selectOneMenu, the option values of the selectCheckboxMenu are updated depending of what option was selected in the selectOneMenu.
The following scenario happens:
I select an option of the selectOneMenu, the selectCheckboxMenu gets populated
I select/check some options of the selectCheckboxMenu
I select another option of the selectOneMenu, the selectCheckboxMenu gets populated with other values
I select some of the new values
I select the option in step 1 of the selectOneMenu
The values I selected in step 2 are no longer selected
I believe this is because the list value bound to the selectCheckboxMenu is getting reset by the setter method.
What I would like is for the state of the selectCheckboxMenu to be globally saved. What would be the best strategy for doing this?
EDIT:
Here's the relevant code that duplicates the previous behavior:
Bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
#ManagedBean
#ViewScoped
public class BackingBean {
private List<Parent> parents = new ArrayList<>();
private List<Child> children = new ArrayList<>();
private List<Child> selectedChildren = new ArrayList<>();
private Parent selectedParent = new Parent();
#Inject
FamilyService service;
#PostConstruct
public void init(){
parents = service.findParents();
}
public void parentChanged(){
children = new ArrayList<>();
if(getSelectedParent() == null){
return;
}
children = service.findChildrenByParent(getSelectedParent());
}
public void selectedSonChanged(){
System.out.println(selectedChildren.size());
}
public List<Parent> getParents() {
return parents;
}
public void setParents(List<Parent> parents) {
this.parents = parents;
}
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
public List<Child> getSelectedChildren() {
return selectedChildren;
}
public void setSelectedChildren(List<Child> selectedChildren) {
this.selectedChildren = selectedChildren;
}
public Parent getSelectedParent() {
return selectedParent;
}
public void setSelectedParent(Parent selectedParent) {
this.selectedParent = selectedParent;
}
}
XHTML:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form id="selectOne">
<p:messages autoUpdate="true" />
<h:outputLabel for="parents" value="Parents:" />
<p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
<p:ajax update="children" listener="#{backingBean.parentChanged}" />
<f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
<f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
</p:selectOneMenu>
<h:outputLabel for="children" value="Children:" />
<p:selectCheckboxMenu converter="#{childConverter}" id="children"
value="#{backingBean.selectedChildren}"
label="Children" filter="true" filterMatchMode="startsWith">
<p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
<f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
</p:selectCheckboxMenu>
<p:outputPanel id="display">
<p:dataList value="#{backingBean.selectedChildren}" var="sn" emptyMessage="No children selected">
#{sn.name}
</p:dataList>
</p:outputPanel>
<p:commandButton value="Submit" update="display, selectOne" />
</h:form>
</h:body>
</html>
The complete project is here: https://github.com/cenobyte321/jsfsamples/tree/master/selectcheckboxmenu
You can find a video of the interaction mentioned previously here:
https://github.com/cenobyte321/jsfsamples/blob/master/selectcheckboxmenu/example1.mp4?raw=true
As you can see when choosing another "Parent" and then selecting their children the previous children list gets substituted. How can I properly modify this behavior so the previously selected elements get persisted and shown as checked in the selectCheckboxMenu?
EDIT 2:
One solution I found was introducing another variable which will hold the global values and will be modified in the listener method "selectedSonChanged". Here's the relevant code:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
#ManagedBean
#ViewScoped
public class BackingBean {
private List<Parent> parents = new ArrayList<>();
private List<Child> children = new ArrayList<>();
private List<Child> selectedChildren = new ArrayList<>();
private List<Child> globalSelectedChildren = new ArrayList<>();
private Parent selectedParent = new Parent();
#Inject
FamilyService service;
#PostConstruct
public void init(){
parents = service.findParents();
}
public void parentChanged(){
children = new ArrayList<>();
if(getSelectedParent() == null){
return;
}
children = service.findChildrenByParent(getSelectedParent());
selectedChildren = globalSelectedChildren.stream().filter(c -> c.getParent().equals(selectedParent)).collect(Collectors.toList());
System.out.println(selectedChildren.size());
}
public void selectedSonChanged(){
System.out.println(selectedChildren.size());
globalSelectedChildren = globalSelectedChildren.stream().filter(c -> !c.getParent().equals(selectedParent)).collect(Collectors.toList());
globalSelectedChildren.addAll(selectedChildren);
}
public List<Parent> getParents() {
return parents;
}
public void setParents(List<Parent> parents) {
this.parents = parents;
}
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
public List<Child> getSelectedChildren() {
return selectedChildren;
}
public void setSelectedChildren(List<Child> selectedChildren) {
this.selectedChildren = selectedChildren;
}
public Parent getSelectedParent() {
return selectedParent;
}
public void setSelectedParent(Parent selectedParent) {
this.selectedParent = selectedParent;
}
public List<Child> getGlobalSelectedChildren() {
return globalSelectedChildren;
}
public void setGlobalSelectedChildren(List<Child> globalSelectedChildren) {
this.globalSelectedChildren = globalSelectedChildren;
}
}
XHTML:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form id="selectOne">
<p:messages autoUpdate="true" />
<h:outputLabel for="parents" value="Parents:" />
<p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
<p:ajax update="children" listener="#{backingBean.parentChanged}" />
<f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
<f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
</p:selectOneMenu>
<h:outputLabel for="children" value="Children:" />
<p:selectCheckboxMenu converter="#{childConverter}" id="children"
value="#{backingBean.selectedChildren}"
label="Children" filter="true" filterMatchMode="startsWith">
<p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
<f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
</p:selectCheckboxMenu>
<p:outputPanel id="display">
<p:dataList value="#{backingBean.globalSelectedChildren}" var="sn" emptyMessage="No children selected">
#{sn.name}
</p:dataList>
</p:outputPanel>
<p:commandButton value="Submit" update="display, selectOne" />
</h:form>
</h:body>
</html>
Here's the branch with this solution: https://github.com/cenobyte321/jsfsamples/tree/solution-1/selectcheckboxmenu
I try to use tag <ace:datatable> inside composite component Mainly it works well. I want to getting row data from the table to use it in bean but when I click on the row, I get error message
Internal server error
I need your help (BalusC :)) to fix this bug.
This is my component:
<?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://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:ace="http://www.icefaces.org/icefaces/components"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:icecore="http://www.icefaces.org/icefaces/core"
xmlns:ice="http://www.icesoft.com/icefaces/component" >
<head>
<title>IGNORED</title>
</head>
<body>
<ui:composition>
<cc:interface componentType="partnercard">
<!-- properties -->
...
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<ace:dataTable id="partnerTable"
value="#{cc.partnersList}"
binding="#{cc.partnersTable}"
var="partner"
paginator="true"
paginatorPosition="bottom"
rows="10"
style="font-size: 11px;margin-top: 10px;"
selectionMode="single"
stateMap="#{cc.stateMap}" >
<ace:ajax event="select" render="#this" execute="#this" />
<ace:column id="id"
headerText="ID"
sortBy="#{partner.id}"
filterBy="#{partner.id}"
filterMatchMode="contains"
rendered="false">
<h:outputText id="idCell" value="#{partner.id}"/>
</ace:column>
<ace:column id="name"
headerText="Name"
sortBy="#{partner.name}"
filterBy="#{partner.name}"
filterMatchMode="contains">
<h:outputText id="nameCell" value="#{partner.name}"/>
</ace:column>
</ace:dataTable>
</div>
</cc:implementation>
</ui:composition>
</body>
</html>
Component backing bean
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.html.*;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.component.UIData;
import org.icefaces.ace.model.table.RowStateMap;
#FacesComponent("partnercard")
public class partnercard extends UINamingContainer implements Serializable {
private RowStateMap stateMap = new RowStateMap();
private List<PartnerData> partnersList = new ArrayList<PartnerData>();
private UIData partnersTable; // поиск партнера - таблица со списком партнеров
#Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
}
public UIData getPartnersTable() {
return partnersTable;
}
public void setPartnersTable(UIData partnersTable) {
this.partnersTable = partnersTable;
}
public RowStateMap getStateMap() {
return stateMap;
}
public void setStateMap(RowStateMap stateMap) {
this.stateMap = stateMap;
}
public List<PartnerData> getPartnersList() {
return partnersList;
}
public void setPartnersList(List<PartnerData> partnersList) {
this.partnersList = partnersList;
}
}
This is PartnerData.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
public class PartnerData implements Serializable {
private long id = 0;
private String name = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
I want to return null value of f:selectItem after I submitted data
<h:selectOneMenu id="tourCategory" value="#{placeBean.tourCateID}"
immediate="true"
required="true"
requiredMessage="tour category is required">
<f:selectItem itemValue="${null}" itemLabel="Select..."></f:selectItem>
<f:selectItems value="#{placeBean.listTourCategory()}"
var="tourCategory"
itemLabel="#{tourCategory.name}"
itemValue="#{tourCategory.tourCateId}">
</f:selectItems>
</h:selectOneMenu>
You can achieve by clear value of tourCateID
This is my example that present how to set default value into h:selectOneMenu
XHTML
<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>Setting Default selectOneMenu</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu id="coffeeSelected" value="#{coffeeBean.favCoffee3}">
<f:selectItem itemValue="${null}"
itemLabel="Select...">
</f:selectItem>
<f:selectItems value="#{coffeeBean.favCoffee3Value}"
var="c"
itemLabel="#{c.coffeeLabel}"
itemValue="#{c.coffeeValue}" />
</h:selectOneMenu>
<h:commandButton value="Submit"
actionListener="#{coffeeBean.clear}">
<f:ajax execute="#form"
render="coffeeSelected" />
</h:commandButton>
</h:form>
</h:body>
</html>
ManagedBean
package com.wittakarn.view;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
#ManagedBean(name = "coffeeBean")
#SessionScoped
public class CoffeeBean implements Serializable {
public String favCoffee3;
public Coffee[] coffee3List;
public String getFavCoffee3() {
return favCoffee3;
}
public void setFavCoffee3(String favCoffee3) {
this.favCoffee3 = favCoffee3;
}
public Coffee[] getFavCoffee3Value() {
coffee3List = new Coffee[3];
coffee3List[0] = new Coffee("Coffee3 - Cream Latte", "Cream Latte");
coffee3List[1] = new Coffee("Coffee3 - Extreme Mocha", "Extreme Mocha");
coffee3List[2] = new Coffee("Coffee3 - Buena Vista", "Buena Vista");
return coffee3List;
}
public void clear(ActionEvent event){
System.out.println("favCoffee3:" + favCoffee3);
favCoffee3 = null;
}
}
Domain
public class Coffee {
public String coffeeLabel;
public String coffeeValue;
public Coffee(String coffeeLabel, String coffeeValue) {
this.coffeeLabel = coffeeLabel;
this.coffeeValue = coffeeValue;
}
public String getCoffeeLabel() {
return coffeeLabel;
}
public String getCoffeeValue() {
return coffeeValue;
}
}
i'm using jsf/primefaces. I want to enable the 'addState' selectOneMenu dropdown should the user select 'Australia' from the 'addCountry' selectOneMenu, it works but on the first instance you have to change the country a couple of times before it will enable, after that it enables/disables on every change. How to get it to respond after first change?
<h:outputLabel value="#{bundle.AddressLabel_country}" for="addcountry" />
<p:selectOneMenu id="addcountry" value="#{addressBean.address.country}" immediate="true" >
<f:selectItems value="#{localeList.getCountryList()}" />
<f:ajax render="addstate"/>
</p:selectOneMenu>
<h:outputLabel value="#{bundle.AddressLabel_state}" for="addstate"/>
<p:selectOneMenu id="addstate" value="#{addressBean.address.state}" disabled="#{addressBean.address.country ne 'Australia'}">
<f:selectItem itemLabel="Select State" itemValue="" />
<f:selectItems value="#{localeList.getAUState()}" />
</p:selectOneMenu>
how about this way
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
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.ViewScoped;
#ManagedBean
#ViewScoped
public class AddressBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = 2439322307625952605L;
private List<String> countries;
private List<String> states;
private Address address;
private boolean disableState;
private Map<String,List<String>> map = new HashMap<String,List<String>>();
#PostConstruct
public void init(){
address= new Address();
countries = new ArrayList<String>();
states = new ArrayList<String>();
countries.add("Australia");
countries.add("Other");
String[] s1 = {"state 1","state 2"};
String[] s2 = {"state 3","state 4"};
map.put("Australia", Arrays.asList(s1));
map.put("Other", Arrays.asList(s2));
this.disableState = "Australia".equals(countries.get(0));
}
public void updateState(){
this.states = map.get(this.address.getCountry());
this.disableState = "Australia".equals(this.address.getCountry());
}
public List<String> getCountries() {
return countries;
}
public void setCountries(List<String> countries) {
this.countries = countries;
}
public List<String> getStates() {
return states;
}
public void setStates(List<String> states) {
this.states = states;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public boolean isDisableState() {
return disableState;
}
public void setDisableState(boolean disableState) {
this.disableState = disableState;
}
}
and
<!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://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:head></h:head>
<h:body>
<h:form>
<h:outputLabel value="Country"
for="addcountry" />
<p:selectOneMenu id="addcountry" value="#{addressBean.address.country}">
<f:selectItems value="#{addressBean.getCountries()}" />
<p:ajax listener="#{addressBean.updateState}" update="addstate"/>
</p:selectOneMenu>
<h:outputLabel value="State" for="addstate" />
<p:selectOneMenu id="addstate" value="#{addressBean.address.state}" disabled="#{addressBean.disableState}">
<f:selectItem itemLabel="Select State" itemValue="" />
<f:selectItems value="#{addressBean.getStates()}" />
</p:selectOneMenu>
</h:form>
</h:body>
</html>
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.