I have a checkbox and a button on my JSF page. I want the button
What is the JSF way of doing this with no javascript and no listener method on my java class
This is plain impossible. I gather that you actually meant, "no manually written JavaScript" (and thus you accept JSF-generated JavaScript as used by <f:ajax>) and "no manually written listener method" (and thus you accept JSF own magic on the component tree state).
In that case, this should do:
<h:form>
<h:selectBooleanCheckbox binding="#{checkbox}">
<f:ajax render="button" />
</h:selectBooleanCheckbox>
<h:commandButton id="button" value="submit"
action="#{bean.submit}"
disabled="#{not checkbox.value}" />
</h:form>
That's all. No additional JS code nor JSF bean properties or listener methods needed. Just a submit() action method.
The binding attribute will in this example put the UIComponent reference of <h:selectBooleanCheckbox> in the Facelet scope under the variable name checkbox. The EL expression #{checkbox.value} returns the value attribute of the component which represents in case of an UISelectBoolean component already a boolean, ready for use in command component's disabled attribute.
Note: if you're facing an incorrect EL error at the line disabled="#{not checkbox.value}" in an older Eclipse version, then you'd need to configure it as follows: Window > Preferences > Web > JavaServer Faces Tools > Validation > Type Coercion Problems > Unary operation boolean coercion problems set it to Warning or Ignore instead of Error. This is not necessary anymore since Eclipse Mars.
You need to this by calling a valueChangeListener on ajax call so you can enable/disable button
Here is checkboxes and button
<h:selectBooleanCheckbox id="deactivate" title="select to deactivate"
valueChangeListener="#{bean.myChangeListener}" onchange="submit()">
<h:selectManyCheckbox value="#{user.favNumber1}">
<f:selectItem itemValue="1" itemLabel="Number1 - 1" />
<f:selectItem itemValue="2" itemLabel="Number1 - 2" />
<f:selectItem itemValue="3" itemLabel="Number1 - 3" />
<f:ajax event="change" execute="@this" render="dummyButton"/>
</h:selectManyCheckbox>
<h:commandButton id="dummyButton" value="OK" render="#{renderBean.myButton}">
You need create a render class with just one attribute whose value will be set in listener method i-e bean#myChangeListener
public class RenderBean{
boolean myButton;
public RendeBean(){
myButton = true;
}
public void enableButton(){
myButton = true;
}
public void disableButton(){
myButton = false;
}
}
And here is your bean#myChangeListener
public void myChangeListener(ValueChangeEvent e){
RenderBean rb = (RenderBean) FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap().get("renderBean");
if(e.getNewValue().toString().equals("1"))
rb.enableButton();
else
rb.disableButton();
}