Rendered is not working properly on JSF - jsf-2

My class is as follows:
public class TestBean implements Serializable{
private int id;
private String name;
private boolean showOut;
public TestBean(){
showOut=false;
}
public void submit(){
System.out.println("id-----"+id);
}
public void whatsTheName(AjaxBehaviorEvent e){
System.out.println("listener called");
if(id==0){
name="Dog";
showOut=true;
}
else if(id==1)
name="Cat";
else
name="Bird";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
System.out.println("name called-----"+name);
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isShowOut() {
System.out.println("showOut called----"+showOut);
return showOut;
}
public void setShowOut(boolean showOut) {
this.showOut = showOut;
}
}
and xhtml is :
<!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:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form id="frm1">
<h:selectOneMenu value="#{testBean.id}">
<f:selectItem itemLabel="Dog" itemValue="0"></f:selectItem>
<f:selectItem itemLabel="Cat" itemValue="1"></f:selectItem>
<f:selectItem itemLabel="Bird" itemValue="2"></f:selectItem>
<f:ajax execute="#form" event="change"
listener="#{testBean.whatsTheName}" render=":frm2:out"></f:ajax>
</h:selectOneMenu>
</h:form>
<br></br>
<br></br>
<h:form id="frm2">
<h:outputText id="out" value="#{testBean.name}" rendered="#{testBean.showOut}"/>
</h:form>
I want to show the Output box only when 'Dog' is selected. But rendered on outputText is not working even though the value of the particular variable is set properly on the backing bean.

You can fix by rendering entire frm2 render=":frm2".

As suggested by wittakarn, modify the render attribute and your outputText is rendered correctly.
But it will never disapper, because you never set showOut to false if a new selection is different to "Dog".
My suggestion is to change the content von whatsTheName(...) like so:
public void whatsTheName(AjaxBehaviorEvent e) {
System.out.println("listener called");
// change showOut in any case
showOut = (id == 0);
// apply text accordingly to the selected id
switch (id) {
case 0:
name = "Dog";
break;
case 1:
name = "Cat";
break;
case 2:
name = "Bird";
break;
}
}

Related

why when I start my JSF2 application on jboss EAP 6.3 it doesn't display in the inputText the value i set in the Managed Bean?

i have a simple file.xhtml in a JSF2.2 application, that's its code:
<!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:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ez="http://xmlns.jcp.org/jsf/composite/ezcomp">
<head>
<title>Insert title here</title>
</head>
<body>
<f:view>
<h:form id="greeting">
<h:inputText id="num1" value="#{jSFeatBean.num1}" />
<h:inputText id="num2" value="#{jSFeatBean.num2}"/>
<h:commandButton type="submit"
value="Submit"
action="#{jSFeatBean.addNumbers()}"/>
<h:outputText value="#{jSFeatBean.result}"/>!
</h:form>
</f:view>
</body>
</html>
and this is my #ManagedBean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "jSFeatBean", eager = true)
#SessionScoped
public class JSFeatursBean {
private String result;
public int num1 = 1;
int num2;
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public Object addNumbers() {
setResult("il risultato e': "+ Integer.toString(num1+num2));
return null;
}
}
after i start jboss from Eclipse the browser display all elements of my file.xhtml properly but the values in the first (id = num1) inputText is 0 and not 1. Why this happens? If i put new values in the inputText boxes everything works fine, so i think that the Mbean is instantiated and working.
I have the same problem with a h:SelectOneListbox element, that doesn't show the list i create when i call the MBean constructor.
It looks like the MBean gets instatiated right after the display of html page.
The code looks fine to me with just one thing that might cause the problem.
Try remove "eager = true" attribute in your ManagedBean annotation. "eager = true" only works with ApplicationScoped Beans.

Primefaces BlockUI blocks all with widgetvar

i want use Primefaces BlockUI's widgetvar (at the moment i use a modal dialog for it). The application should block only when i select something (a long method will call) and unblock after complete. But it blocks the full side on first side access. Make i something wrong?
When i block the table specific it works. (block="table") But i want block the whole page.
Use Primefaces 5.1 & Mojarra 2.2.8
Short example:
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"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>test</title>
</h:head>
<h:body>
<h:form>
<p:blockUI widgetVar="block" blocked="false"/>
<p:dataTable id="table" value="#{myController.tableItems}" rowKey="#{data}"
selection="#{myController.selectedItem}" selectionMode="Single"
var="data">
<p:ajax event="rowSelect" onstart="PF('block').show()"
listener="#{myController.doSomething}"
oncomplete="PF('block').hide()" />
<p:column>#{data}</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
Bean:
#ManagedBean
#ViewScoped
public final class MyController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<String> tableItems;
private String selectedItem;
#PostConstruct
public void init() {
tableItems = new ArrayList<String>();
tableItems.add("test1");
tableItems.add("test2");
}
public void doSomething(SelectEvent event){
System.out.println("DO Something");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(String selectedItem) {
this.selectedItem = selectedItem;
}
public List<String> getTableItems() {
return tableItems;
}
public void setTableItems(List<String> tableItems) {
this.tableItems = tableItems;
}
}
Add an id attribute the body and use that in the block= attribute on the blockui component

Creating dynamic inputs in jsf2

i want to create dynamic textbox in jsf2 in datatable having textboxes based on clicking add row button. Iam a newbie for jsf programming.Can someone tell me a basic example for dynamic for generation . I have read ui:repeatand c:foreach but i need some practical example.
For your sample,
xhtml code:
<?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>
</h:head>
<h:body>
<h:form id="form1">
<h:commandButton value="Add new Row" actionListener="#{myBean.addNewEmployee}"/>
<h:dataTable value="#{myBean.employeeList}" var="emp">
<h:column>
<f:facet name="header">
Employee Id
</f:facet>
#{emp.empId}
</h:column>
<h:column>
<h:inputText value="#{emp.empName}"/>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
jsf manged bean
#ManagedBean
#ViewScoped
public class MyBean implements Serializable {
List<Employee> employeeList;
public List<Employee> getEmployeeList() {
return employeeList;
}
public void setEmployeeList(List<Employee> employeeList) {
this.employeeList = employeeList;
}
public void addNewEmployee(ActionEvent event) {
employeeList.add(new Employee(employeeList.size(), null));
}
#PostConstruct
public void init() {
employeeList = new ArrayList<Employee>();
employeeList.add(new Employee(1, "Emp1"));
employeeList.add(new Employee(2, "Emp2"));
}
public MyBean() {
}
}
Employee Class(You can use your entity class)
public class Employee {
Integer empId;
String empName;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Employee(Integer empId, String empName) {
this.empId = empId;
this.empName = empName;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Employee other = (Employee) obj;
if (this.empId != other.empId && (this.empId == null || !this.empId.equals(other.empId))) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 5;
hash = 41 * hash + (this.empId != null ? this.empId.hashCode() : 0);
return hash;
}
}
You can directly use above code. And also I suggest to use PrimeFaces component for advanced manipulations

How to prevent multiple composite components reset themselves on a JSF page?

I put this problem in a simple example, a composite component that calculates the sum of 2 inputs and prints the result in an outputText
Main JSF page:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ez="http://java.sun.com/jsf/composite/ezcomp/">
<h:head></h:head>
<h:body>
<ez:Calculator />
<br/>
<br/>
<ez:Calculator />
<br/>
<br/>
<ez:Calculator />
</h:body>
</html>
Composite component 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:composite="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>This content will not be displayed</title>
</h:head>
<h:body>
<composite:interface componentType="calculator">
</composite:interface>
<composite:implementation>
<h:form>
<h:inputText id="first" value="#{cc.firstNumber}" />
<h:commandButton value="+" action="#{cc.sum}"/>
<h:inputText id="second" value="#{cc.secondNumber}" />
</h:form>
<h:outputText id="result" value="#{cc.result}" />
</composite:implementation>
</h:body>
</html>
Composite component backing bean:
package ez;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
#FacesComponent("calculator")
public class Calculator extends UINamingContainer {
private Long firstNumber;
private Long secondNumber;
private Long result;
public Calculator() {
}
#Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
public void setFirstNumber(String firstNumber) {
this.firstNumber = Long.parseLong(firstNumber);
}
public String getFirstNumber() {
if(firstNumber == null) {
return null;
}
return firstNumber.toString();
}
public void setSecondNumber(String secondNumber) {
this.secondNumber = Long.parseLong(secondNumber);
}
public String getSecondNumber() {
if(secondNumber == null) {
return null;
}
return secondNumber.toString();
}
public String getResult() {
if(result == null) {
return null;
}
return result.toString();
}
public void setResult(String result) {
this.result = Long.parseLong(result);
}
public void sum() {
this.result = this.firstNumber + this.secondNumber;
}
}
So, I have 3 Composite Components that all should do the same thing, but when I press a SUM button, after the server processes the request, the result is printed out on the page, but the other 2 components are cleared of their values.
How can I prevent this? How can I force it to retain those values?
UIComponent instances are recreated on every request, hereby losing all instance variables everytime. They basically act like request scoped managed beans, while you intend to have them in the view scope. You need to take view state saving into account on a per-attribute basis. This is normally by default already done for all attributes of #{cc.attrs}. So, if you can, just make use of it:
<cc:interface componentType="calculator">
<cc:attribute name="firstNumber" type="java.lang.Long" />
<cc:attribute name="secondNumber" type="java.lang.Long" />
</cc:interface>
<cc:implementation>
<h:form>
<h:inputText id="first" value="#{cc.attrs.firstNumber}" />
<h:commandButton value="+" action="#{cc.sum}"/>
<h:inputText id="second" value="#{cc.attrs.secondNumber}" />
</h:form>
<h:outputText id="result" value="#{cc.attrs.result}" />
</cc:implementation>
with just this (nullchecks omitted; I recommend to make use of required="true" on the inputs)
#FacesComponent("calculator")
public class Calculator extends UINamingContainer {
public void sum() {
Long firstNumber = (Long) getAttributes().get("firstNumber");
Long secondNumber = (Long) getAttributes().get("secondNumber");
getAttributes().put("result", firstNumber + secondNumber);
}
}
Otherwise, you'd have to take state saving into account yourself by delegating all attribute getters/setters to UIComponent#getStateHelper(). Based on the very same Facelets code as you have, the entire backing component would look like this:
#FacesComponent("calculator")
public class Calculator extends UINamingContainer {
public void sum() {
setResult(getFirstNumber() + getSecondNumber());
}
public void setFirstNumber(Long firstNumber) {
getStateHelper().put("firstNumber", firstNumber);
}
public Long getFirstNumber() {
return (Long) getStateHelper().eval("firstNumber");
}
public void setSecondNumber(Long secondNumber) {
getStateHelper().put("secondNumber", secondNumber);
}
public Long getSecondNumber() {
return (Long) getStateHelper().eval("secondNumber");
}
public void setResult(Long result) {
getStateHelper().put("result", result);
}
public Long getResult() {
return (Long) getStateHelper().eval("result");
}
}
See, no local variables anymore. Note that I also removed the need for those ugly manual String-Long conversions by just declaring the right getter return type and setter argument type. JSF/EL will do the conversion automagically based on default converters or custom Converters. As there's already a default one for Long, you don't need to provide a custom Converter.
Unrelated to the concrete problem, you can safely remove the getFamily() method. The UINamingContainer already provides exactly this. If you were implementing NamingContainer interface instead, then you'd indeed need to provide it yourself, but this is thus not the case here. The above backing component examples have it already removed.

JSF Initialize Map Object

I'm starting my first steps in JSF.
I've already read this link
http://docs.oracle.com/javaee/6/tutorial/doc/bnawq.html#bnaww
in regards to map initialization.
The problem is, I want to populate my map with values residing in a file.
How can I do that?
I've tried not using faces-config.xml and calling a support method in the bean's constructor, but my select list box isn't populated.
My bean class:
#ManagedBean
public class ADGroupListBean {
private static final String WITH_ACCESS = "D:\\workspace\\AccessControl\\permissions.txt";
private static final String WITHOUT_ACCESS = "D:\\workspace\\AccessControl\\noPermissions.txt";
private Map<String,String> withAccess, withoutAccess;
private LDAPQueries queries;
public ADGroupListBean(){
withAccess = new LinkedHashMap<String, String>();
withoutAccess = new LinkedHashMap<String, String>();
queries = new LDAPQueries();
initList(WITH_ACCESS, withAccess);
initList(WITHOUT_ACCESS, withoutAccess);
}
private void initList(String filename, Map<String,String> list) {
File f = new File(filename);
if ( !f.exists() && f.getAbsolutePath().equals(WITHOUT_ACCESS) )
{
queries.queryAllGroups(WITHOUT_ACCESS);
}
try
{
Scanner sc = new Scanner(f);
while (sc.hasNext())
{
String group = sc.nextLine();
list.put(group, group);
}
}catch (IOException e) {
e.printStackTrace();
}
}
// public void populateList() {
//
//
// }
public Map<String,String> getWithAccess() {
return withAccess;
}
public Map<String,String> getWithoutAccess() {
return withoutAccess;
}
public void setWithoutAccess(Map<String,String> withoutAccess) {
this.withoutAccess = withoutAccess;
}
public void setwithAccess(Map<String,String> withAccess) {
this.withAccess = withAccess;
}
public void test() {
System.out.println("workssssssssssssssssss");
}
}
As for my JSF file, it is like this:
<!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">
<h:head><title>Your Title Here</title>
</h:head>
<h:body>
<h1>Your Heading Here</h1>
<h:form>
<h:selectOneMenu value="teste">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{ADGroupListBean.withoutAccess}" />
</h:selectOneMenu>
</h:form>
</h:body>
</html>
I've tested the bean's functions in a test application, and everything works fine.
So my guess is the bean isn't instantiated?
Regards,
Nuno.

Resources