I've searched and tried various things from around here and the web; prependId, using full id paths (:form:panelid:componentid kinda thing), and others.
I'm still confused. I'm still a JSF noob :)
My problem is that whatever I specify in the f:ajax render part isn't the only parts the get "executed". What I mean is, the id specified in render won't get rerendered on screen, but the value of that component do get called.
So:
inputText's f:ajax render=outA event=blur
when blur happens, outA's getter is called and it rerendered, but also the getter of other components are called, but they're not rerendered.
Specifically, in light of the listed code below:
A) When val1 loses focus, it's blur event fires, which has it call getValue1() and rerender outval1. Happy. But, getStuff() is ALSO called (it happens for the other blur and btnCalc also) BUT the result from getStuff() is NOT rendered to tblStuff dataTable. Why?
How can I fix it, so that on the blur event, only the getters relevent to the render=".." component is executed?
Should I maybe use different sections?
B) when the refresh button is clicked, then it will call getStuff AGAIN, and now show the new dataTable / ie that new data with ALL THE MANY ValueTO's that was added during the blur events and the btnReload click event.
C) For any one event named in A, the getStuff method is called exactly 8 times. ie, click inside inputbox, click outside input box, getStuff() * 8. Yet, getValue1 is called only twice?
D) Any good JSF2 books out there?
Here is the 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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Stuff</title>
</h:head>
<h:body>
<h:form id="frmTrxMain" prependId="true">
<h1>
Stuff
</h1>
<h:dataTable title="Stuff" id="tblStuff" var="s" value="#{bean.stuff}" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{s.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{s.name}" />
</h:column>
</h:dataTable>
<h:outputText value="No stuff to display" rendered="#{empty bean.stuff}"/>
<h:commandButton value="Refresh" id="btnReload">
<f:ajax render="tblStuff" event="click"/>
</h:commandButton>
<hr/>
<h:panelGrid columns="3" id="pnlTwo">
<h:outputLabel value="Value1"/>
<h:inputText value="#{bean.value1}" id="val1">
<f:ajax event="blur" render="outVal1"/>
</h:inputText>
<h:outputText id="outVal1" value="Entered: #{bean.value1}" />
<h:outputLabel value="Value2"/>
<h:inputText value="#{bean.value2}" id="val2">
<f:ajax event="blur" render="outVal2"/>
</h:inputText>
<h:outputText id="outVal2" value="Entered: #{bean.value2}" />
<h:commandButton value="Calc" id="btnCalc">
<f:ajax event="click" render="outSum"/>
</h:commandButton>
</h:panelGrid>
<h:outputLabel id="outSum" value="#{bean.sum}"/>
</h:form>
</h:body>
</html>
And the backing bean:
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean(name = "bean")
@SessionScoped
public class TestStuffBean {
private int id=1;
private String name="a";
//test.xhtml
private String value1;
private String value2;
private List<TestVO> stuff = new ArrayList<TestVO>();
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getSum() {
String result = "";
int sum;
try {
sum = Integer.parseInt(value1) + Integer.parseInt(value2);
result = Integer.toString(sum);
} catch (NumberFormatException e) {
result = "Enter two integers";
}
return result;
}
public List<TestVO> getStuff() {
//the VO is just a POJO with a contructor that takes
//two strings and a getter/setter for each id and name
stuff.add(new TestVO(Integer.toString(id), name+id));
id++;
return stuff;
}
}