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
Related
Someone maybe knows why I can't display list of categories in my app. File categories.xhtml shows only word Categories. Class Category sets id and name in constructor.
categories.xhtml
<ui:component>
<h:form>
<h4>Categories</h4>
<ul>
<ui:repeat var="category" value="#{categoriesBean.modelCategories}">
<li><h:outputText value="#{category.name}">
</h:outputText>
</li>
</ui:repeat>
</ul>
</h:form>
</ui:component>
CategoriesBean.java
#ManagedBean
#RequestScoped
public class CategoriesBean {
private ListDataModel<Category> modelCategories = new ListDataModel<Category>();
public ListDataModel<Category> getModelCategories() {
return modelCategories;
}
public void setModelCategories(ListDataModel<Category> modelCategories) {
this.modelCategories = modelCategories;
}
public CategoriesBean() {
modelCategories.setWrappedData(DAO.getDAO().getCategories());
}
}
DAO.java
public class DAO {
private static DAO instance = new DAO();
private List<Category> categories = new ArrayList<Category>();
{
Category smartphones = new Category(1, "Smartphones");
Category consoles = new Category(2, "Consoles");
categories.add(smartphones);
categories.add(consoles);
}
public static DAO getDAO() {
return instance;
}
public List<Category> getCategories() {
return this.categories;
}
Here is site source:
<form id="j_idt2" name="j_idt2" method="post" action="/Shop/categories.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt2" value="j_idt2" />
<ul>
</ul><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="H4sIAAAAAAAAAJVSQWvUQBR+Tbp2G1Zpt9KL6KkIgmSp2IuLuIvt0sXULqSCxYPOZqebWSfJOPOym/RQ8B8InoSKVw/e/AXVgyAo6FFv3j16dyaN3R704EBe8vK+9+Z773tvfkJFKAmLIzImboqMu5tEhVtEVOa+Hb1ffvTFBqsDDk/IoEMCTGQX5jGUVIUJH2TiVgvMqU2q2i7ox0Y4M3rIBriaSlh64BV1OYmH7nZ/RANsPvt8/9WCusItgEzohIrQJ30CB2Ab70CCa3Iyd48EVLlBEokkpjG697q3/3yv9GQiqMT8Ds0VlKeuC0o4N71wI06j00GB4BBEyfopUqWbXpo23ZaS5B5TmD39evHFB/LShpkuzCq2TwuW9mTWWJ10+e/sfCRIN/VMqPTJmMrdj29vPj/8tGWB5cF8wIlSd0lEEerFSBqGYcPXZOJh0wNH6ZxBUQNh+RjBkoZPJSOc7ZM+p81MiLEZEyhja7qbS/p6V6VxScZYTlG57V7P626slzjNee0fQBYJ7q7TPZJy7Bz/XGkLwfOd5DGNf72+unvYGrVqZnaTC7DYCDS/YSKZrpGFGHGAme13338cZZmWbe3/ZOtJNtblTgtk+M4hnJ+KtBMSbEvqa7Im6GigVShhlc0VE3FKx9i6kflssYHXbhSv6yfLVTWrpsPVso/cOBUDWj3BWEJkvwHxOyj9FQMAAA==" autocomplete="off" />
</form>
You don't need to call a list of DataModel when using ui:repeat :
<ui:repeat var="category" value="#{categoriesBean.categories}">
<li><h:outputText value="#{category.name}">
</h:outputText>
</li>
</ui:repeat>
Then when you'll call a service it will be most of the time be database interactions where you inject a service in your bean. For that you should use the #PostConstruct attribute (which is not needed in your case).
#ManagedBean
#RequestScoped
public class CategoriesBean {
// this is not needed but that's how you'd get from db.
//#Inject
//private MyService service;
private List<Category> categories;
// getters and setters
#PostConstruct // in your case this is not needed but it is if you use injection
public void init() {
categories = yourService.getCategories(); // this is not needed.
//instead you can add it like this.
categories = new ArrayList<Category>();
categories.add(1, "blabla");
}
}
I have a JSF2 application that should show a page where a number os items must be added in a list. The user wants to add those items, set some properties of them and finally persist them all together, in a single save operation.
The domain object that should be handled by this page looks like this:
public class Item {
private long id;
private String name;
private Item previous;
public Item() { }
public Item(Item previousItem) {
this.previous = previousItem;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Item getPrevious() {
return previous;
}
}
The ItemBean class looks like this:
#ManagedBean
public class ItemBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
if(items.size()==0) {
items.add(new Item()); // adding the first item
}
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public void addItem(Item previousItem) {
Item newItem = new Item(previousItem);
items.add(newItem);
}
public void save() {
...
}
}
The view is a xhtml file that looks like 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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="/templates/layout.xhtml">
<ui:define name="content">
<h2>Items</h2>
<fieldset>
<legend>Items being added</legend>
<ui:repeat value="#{itemBean.items}" var="item">
<div>
<h:outputLabel value="Item" for="name" />
<h:inputHidden value="#{item.id}" />
<h:inputText id="name" value="#{item.name}" />
<h:commandLink action="#{itemBean.addItem(item)}">Add</h:commandLink>
</div>
</ui:repeat>
</fieldset>
<div class="options">
<h:commandButton action="#{itemBean.save}" value="Save"/>
<div class="clear border-bottom"></div>
</div>
</ui:define>
</ui:composition>
</body>
</html>
Notice that in order to add a new item, the current one must be sent to satisfy business rules.
The problem is that I can add a second item with no problema, but when I click in the Add link next to the second item, the page is rerendered with one single item, just like it was in the beggining.
Unfortunatelly, I can't see what's missing to make it work, even after reading a lot of posts, pages and some book chapters.
Update 1
I was asked about the kind of scope used with this bean. It´s de default scope (#RequestScoped). I was trying to avoid using #SessionScoped for the sake of scalability, but in this particular case, I´m not sure I have a choice. Anyone with more experience could give me tip?
What is the scope of your ManagedBean ?
Since you didn't post any persistence code, I suppose the items List only exists througout your Bean's life. This means that if your Bean is #ViewScoped or #RequestScoped, your items cease to exist after you submit your form.
You need use an ajax component, something like:
<fieldset id="list">
<legend>Items being added</legend>
<ui:repeat value="#{itemBean.items}" var="item">
<div>
<h:outputLabel value="Item" for="name" />
<h:inputHidden value="#{item.id}" />
<h:inputText id="name" value="#{item.name}" />
<h:commandLink action="#{cargoBean.addItem(item)}">
<f:ajax render="list" />
Add
</h:commandLink>
</div>
</ui:repeat>
</fieldset>
I see no form in your xhtml page like :
<h:form>
<ui:repeat>
<h:inputBlabla/>
</ui:repeat>
</h:form>
A form is needed while using h:input fields.
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
i wish to retrieve List based on the selection of dropdownlist item. for that i am using the following code which is not working:
<p:selectOneMenu style="width: 150px" value="#{watchBean.exchange}">
<f:selectItem itemLabel="NSE" itemValue="nse"/>
<f:selectItem itemLabel="BSE" itemValue="bse"/>
<p:ajax event="change" update=":frm" listener="#{watchBean.doScripList}" />
</p:selectOneMenu>
bean code:
public void doScripList(ValueChangeEvent e)
{
sl=getAllScripByExchange((String)e.getNewValue()); //sl is of type List<MasterScrip>
}
when i debug , i see that the event is not fired and i get the following error:
javax.el.MethodNotFoundException: Method not found: beans.watchBean#9ac2e4.doScripList(javax.faces.event.AjaxBehaviorEvent)
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155)...
when i omit p:ajax the 'exchange' type is also not get/set
what is causing this problem? what is its solution?
edited
renamed the method to wow() still the same error :
javax.el.MethodNotFoundException: Method not found: beans.watchBean#1732d83.wow(javax.faces.event.AjaxBehaviorEvent)
edited : managed bean code
import java.util.List;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceRef;
import service.MasterScrip;
import service.StatelessWebService_Service;
#Named(value = "watchBean")
#RequestScoped
public class watchBean {
#WebServiceRef(wsdlLocation = "WEB-INF/wsdl/localhost_8080/StatelessWebService/StatelessWebService.wsdl")
private StatelessWebService_Service service;
/** Creates a new instance of watchBean */
public watchBean() {
}
String uname,scripSym,exchange;
Integer scripID;
List<UserTrack> ut;
List<MasterScrip> sl;
public List<MasterScrip> getSl() {
return sl;
}
public void setSl(List<MasterScrip> sl) {
this.sl = sl;
}
public String getExchange() {
return exchange;
}
public void setExchange(String exchange) {
sl=getAllScripByExchange(exchange);
this.exchange = exchange;
}
public void wow(ValueChangeEvent e)
{
sl=getAllScripByExchange((String)e.getNewValue());
// setSl(sl);
//FacesContext.getCurrentInstance().renderResponse();
// sl=getAllScripByExchange(exchange);
}
Try changing
<p:ajax event="change" update=":frm" listener="#{watchBean.doScripList}" />
to
<p:ajax event="change" update=":frm" listener="#{watchBean.doScripList()}" />
add parenthesis at the end of the method.
JSF is looking for a method setDoScripList in your backing bean, but when adding the parenthesis at the end you're calling this method doScripList explicitly.
Landed on the same problem as yours, but I figured out that the valueChangeListener
public void doScripList(ValueChangeEvent e)
works only when you use <f:ajax> tag and not when you use <p:ajax>.
But since selectOneMenu is of type <p:selectOneMenu>, so <f:ajax> won't work.
I worked out by removing the parameter ValueChangeEvent e and it worked.
So try out a no-parameter listener in case of <p:ajax> tag.
public void doScripList()
{
sl=getAllScripByExchange(getExchangeName());
}
Note: here you don't have the event parameter so, it sets the new value by calling respective setter methods, and you can access updated values in the listener.
For this case you also need to provide id to selectOneMenu like this:
<p:selectOneMenu id="exchangeName" style="width: 150px" value="#{watchBean.exchange}">
...
</p:selectOneMenu>
and then you add get and set methods for exchangeName in your Bean class:
private String exchangeName;
public String getExchangeName(){
return exchangeName;
}
public void setExchangeName(String exchangeName) {
this.exchangeName = exchangeName;
}
It is primefaces 3.2 bug, please replace your code as the following.
<h:selectOneMenu style="width: 150px" value="#{watchBean.exchange}" valueChangeListener="#{watchBean.doScripList}" onchange="submit()">
<f:selectItem itemLabel="NSE" itemValue="nse"/>
<f:selectItem itemLabel="BSE" itemValue="bse"/>
</h:selectOneMenu>
Change your method likes here;
public void doScripList(ValueChangeEvent e){
sl = getAllScripByExchange((String)e.getNewValue());
setAllScriptExchange(sl); //please write setAllScriptExchange method yourself
FacesContext.getCurrentInstance().renderResponse();
}
Your page is reloaded, because of onchange event.
I have a page where I have a static list containing the list of products which are again grouped into product groups.I have a toggle button in the JSP page which shuffles between the enabled and disabled products .Code for my toggle button is as follows
<h:commandButton value="retrieve" image="#{displayProductsBean.productsToggleImage}" actionListener="#{displayProductsBean.fetchProductsBasedOnStatus}">
<c:choose>
<c:when test="${displayProductsBean.productFetchCriteria=='0'}">
<f:attribute name="buttonSelected" value="1" />
</c:when>
<c:otherwise>
<f:attribute name="buttonSelected" value="0" />
</c:otherwise>
</c:choose>
</h:commandButton>
Now in the managed bean I am able to get the value of the button selected and have logic to retrieve either enabled or disabled products
But I don't know how would I get back to the same page and also I don't want the list to be reloaded again from the DB.Code in my bean class is as follows
public void fetchProductsBasedOnStatus(ActionEvent event)
{
System.out.println("The fetchProductsBasedOnStatus in bean is called");
String selected = (String) event.getComponent().getAttributes().get("buttonSelected");
System.out.println("The value of toggle button is"+selected);
setProductFetchCriteria(Integer.parseInt(selected));
System.out.println("The value of toggle button is"+this.toString());
}
Somebody please help me resolve this .....
But I don't know how would I get back to the same page
Just return null or void in action method.
and also I don't want the list to be reloaded again from the DB
Just don't do that? If you keep the bean in the view scope and load the lists in the (post)constructor, then the same lists will be kept as long as the enduser is interacting with the same view. You should only not use JSTL tags as it breaks the view scope.
Your code can be simplified as follows:
<h:commandButton value="retrieve" image="#{bean.showDisabledProducts ? 'enabled' : 'disabled'}.png" action="#{bean.toggle}">
<f:ajax render="#form" />
</h:commandButton>
<h:dataTable value="#{bean.products}" ...>
...
</h:dataTable>
with
#ManagedBean
#ViewScoped
public class Bean {
private boolean showDisabledProducts;
private List<Product> enabledProducts;
private List<Product> disabledProducts;
#EJB
private ProductService service;
#PostConstruct
public void init() {
enabledProducts = service.listEnabledProducts();
disabledProducts = service.listDisabledProducts();
}
public void toggle() {
showDisabledProducts = !showDisabledProducts;
}
public List<Product> getProducts() {
return showDisabledProducts ? disabledProducts : enabledProducts;
}
public boolean isShowDisabledProducts() {
return showDisabledProducts;
}
}