Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The <code>FacesContext#getViewRoot()</code> returns the JSF component tree. This is exactly the same tree as represented by XHTML source code after thinking away all <a href="https://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense">taghandlers</a> (JSTL, <code>&lt;ui:include&gt;</code>, etc). You need to realize that there's <strong>only one</strong> <code>&lt;h:selectBooleanCheckbox id="checkbox"&gt;</code> in there. It's available in <code>UIViewRoot#findComponent()</code> by exactly that ID <code>"form:rm:checkbox"</code>. </p> <p>It's just its HTML representation which get regenerated multiple times depending on the current iteration round of the parent <code>&lt;h:dataTable&gt;</code>. This generated HTML representation has in turn client IDs with the current row index inlined. This HTML representation is obviously not available in the component tree.</p> <p>The component's state (the submitted values, etc), is also only available <strong>during</strong> iterating the <code>&lt;h:dataTable&gt;</code> and not before or after. Essentially, you're trying to access the value of the component in bean's action method while the <code>&lt;h:dataTable&gt;</code> component isn't iterating over it, so the values will always return <code>null</code>.</p> <p>In order to programmatically simulate a <code>&lt;h:dataTable&gt;</code> iteration so that you can collect the desired values, you need to visit the <code>&lt;h:dataTable&gt;</code> by <a href="http://docs.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#visitTree%28javax.faces.component.visit.VisitContext,%20javax.faces.component.visit.VisitCallback%29" rel="nofollow noreferrer"><code>UIComponent#visitTree()</code></a> and collect the information of interest in the <code>VisitCallback</code> implementation.</p> <pre><code>UIData table = (UIData) viewRoot.findComponent("form:rm"); table.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), new VisitCallback() { @Override public VisitResult visit(VisitContext context, UIComponent target) { if (target instanceof HtmlSelectBooleanCheckbox) { HtmlSelectBooleanCheckbox checkbox = (HtmlSelectBooleanCheckbox) target; System.out.println("id: " + checkbox.getId()); System.out.println("value: " + checkbox.getValue()); // Collect them in an arraylist orso. } return VisitResult.ACCEPT; } }); </code></pre> <hr> <p><strong>However</strong>, you're going in completely the wrong direction as to solving the concrete problem. You should be performing the validation in a validator associated with the input component you'd like to validate, not in the action method. Here's how you could solve the particular concrete functional requirement of validating the input field as <code>required</code> only when the checkbox in the same row is checked:</p> <pre class="lang-html prettyprint-override"><code>&lt;h:column&gt; &lt;h:selectBooleanCheckbox binding="#{checkbox}" ... /&gt; &lt;/h:column&gt; &lt;h:column&gt; &lt;h:inputText ... required="#{checkbox.value}" /&gt; &lt;/h:column&gt; </code></pre> <p>That's all. Additional advantage is, the validators run <em>while</em> the <code>&lt;h:dataTable&gt;</code> is iterating, so you don't need all that <code>visitTree()</code> code as well.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload