tags:

views:

38

answers:

2

I'd like to do client side component updates. Example: disable a button when a checkbox is clicked:

<h:selectBooleanCheckbox value="true" onchange="button.disabled=true" />
<h:commandButton id="button" value="Save" />

The above doesn't work. Is there a way to do this declaratively in JSF?

+2  A: 

simply use javascript

document.getElementById("buttonId").disabled="true";  

Check this

org.life.java
+1, simple and sufficient answer
Bozho
Can you give an example? Is there a way to do this declaratively in JSF (I've updated the question).
Theo
@Theo Ultimately JSF will be HTML at browser, just use the updated code
org.life.java
Actually, the OP is already using JavaScript.
BalusC
+1  A: 

It doesn't work because the JSF component ID is not necessarily the same as the generated HTML ID. JSF composes the HTML element ID and form element name based on the ID's of all UINamingContainer components in the tree -if any. The UIForm component is one of them. Rightclick the page in webbrowser and choose View Source. See and learn.

There are two ways to solve this problem:

  1. Set prependId attribtue of <h:form> to false.

    <h:form prependId="false">
        <h:selectBooleanCheckbox value="true" onclick="button.disabled=true" />
        <h:commandButton id="button" value="Save" />
    </h:form>
    

    Note that I'd rather use onclick="button.disabled=!checked" instead. The onchange is only fired when the input element loses focus and that is non-intuitive in case of checkboxes and radiobuttons. Also, you'd like to turn it back on when the checkbox is checked again, right?

  2. Give the <h:form> a fixed ID so that you know how the generated form element name look like:

    <h:form id="form">
        <h:selectBooleanCheckbox value="true" onclick="form['form:button'].disabled=true" />
        <h:commandButton id="button" value="Save" />
    </h:form>
    

    The brace notation is mandatory because the : is an illegal identifier character and just onclick="form:button.disabled=true" won't work. Also here, I'd rather use onclick="form['form:button'].disabled=!checked instead.

The same problem applies on document.getElementById() as well. So simply replacing button by document.getElementById('button') alone won't fix the problem.

BalusC
+1 I remember that I had a hard time understanding this when I started with JSF, and I think this is the way to go if you want to keep your code clean.
Abel Morelos
What if I want to change an attribute of a component that does not exist in the rendered HTML output. I guess the component writer needs to expose a client side JS API, right?
Theo
Use `<f:ajax>` to do partial updates which get reflected in both server and client sides.
BalusC