1

Trying to refactor the following JSP version for a Yes/No/NA/Resolved checklist using JSF and Primefaces:

<c:forEach var="qAndA" items="${checklist.answer_attribute_list}">
 ..trim..
<td class="chklist"><input type="radio" name="radio_<c:out value="${qAndA.attribute_id}" />" onclick="this.form.no_<c:out value="${qAndA.attribute_id}" />.disabled=true;this.form.no_<c:out value="${qAndA.attribute_id}" />.style.backgroundColor='#808080';" value="1"></td>
<td class="chklist"><input type="radio" name="radio_<c:out value="${qAndA.attribute_id}" />" onclick="this.form.no_<c:out value="${qAndA.attribute_id}" />.style.backgroundColor='#ffffff';this.form.no_<c:out value="${qAndA.attribute_id}" />.disabled=false;" value="2"></td>
<td class="chklist"><textarea DISABLED onkeyup="sz(this);" style="background:#808080" name="no_<c:out value="${qAndA.attribute_id}" />" cols=19 rows="4" onkeypress="if(this.value.length>499){ alert('You have exceeded the limit of 500 characters. Please edit your entry.'); return false}"></textarea></td>
<td class="chklist"><input type="radio" name="radio_<c:out value="${qAndA.attribute_id}" />" onclick="this.form.no_<c:out value="${qAndA.attribute_id}" />.disabled=true;this.form.no_<c:out value="${qAndA.attribute_id}" />.style.backgroundColor='#808080';" value="3"></td>
<td class="chklist"><input type="checkbox" DISABLED name="check_<c:out value="${qAndA.attribute_id}" />" value="4"></td>

The Column headings got cutoff in image but they are:
Q No. | Question | Section | Yes | No | No Reason | N/A | Resolved?
Before

With the old JSP, if user clicked the "no" radio, it would allow them to enter text under "No Reason" but if they change their minds they could still click the "yes" or the "n/a" radio and the "No Reason" textbox would grey and disable. The radio value didn't really change until the user clicked the submit button, so the Resolved checkbox didn't appear until they clicked "No" and submitted the form.

But with JSF and datatable I don't know how to reference the textareas in each row as I did in the old Jsp. So based on help from BalusC with this post for a Quantity type checklist JSF disable inputbox with a checkbox in a ui:repeat on a composite component I tried the following JSF using Ajax:

<p:dataTable id="dataTable" value="#{cc.attrs.checklist.answer_attribute_list}" var="qAndA">

    <p:column headerText="Yes" width="50px;">
        <p:selectOneRadio id="yesNoNA" value="#{qAndA.toggle_value}" layout="custom">
            <f:selectItem itemLabel="Yes" itemValue="1" />
            <f:selectItem itemLabel="No" itemValue="2" />
            <f:selectItem itemLabel="NA" itemValue="3" />
            <f:selectItem itemLabel="Resolved" itemValue="4" />
            <p:ajax update="@form" />
        </p:selectOneRadio>

        <p:radioButton id="yes" for="yesNoNA" itemIndex="0" rendered="#{empty qAndA.toggle_value or qAndA.toggle_value == '0'}" />
        <h:outputText value="X" rendered="#{qAndA.toggle_value == '1'}" />
        <h:outputText value="" rendered="#{qAndA.toggle_value == '2' or qAndA.toggle_value == '3' or qAndA.toggle_value == '4'}" />
    </p:column>


    <p:column headerText="No" width="50px;">
        <p:radioButton id="no" for="yesNoNA" itemIndex="1" rendered="#{empty qAndA.toggle_value or qAndA.toggle_value == '0'}" />
        <h:outputText value="X" rendered="#{qAndA.toggle_value == '2' or qAndA.toggle_value == '4'}" />
        <h:outputText value="" rendered="#{qAndA.toggle_value == '1' or qAndA.toggle_value == '3'}" />
    </p:column>

    <p:column headerText="Reason For Attribute Failure" width="250px;">
        <h:inputTextarea value="#{qAndA.fail_reason}" rendered="#{qAndA.toggle_value == '2'}" />
        <h:outputText value="#{qAndA.fail_reason}" rendered="#{empty qAndA.toggle_value or qAndA.toggle_value == '0'}" />
        <h:outputText value="" rendered="#{qAndA.toggle_value == '1' or qAndA.toggle_value == '3'}" />
        <h:outputText value="#{qAndA.fail_reason}" rendered="#{qAndA.toggle_value == '2' or qAndA.toggle_value == '4'}" />THIS ONE IS REDUNDANT
    </p:column>

    <p:column headerText="N/A" width="50px;">
        <p:radioButton id="na" for="yesNoNA" itemIndex="2" rendered="#{empty qAndA.toggle_value or qAndA.toggle_value == '0'}" />
        <h:outputText value="X" rendered="#{qAndA.toggle_value == '3'}" />
        <h:outputText value="" rendered="#{qAndA.toggle_value == '1' or qAndA.toggle_value == '2' or qAndA.toggle_value == '4'}" />
    </p:column>

    <p:column headerText="Resolved *" width="75px;">
        <p:radioButton id="resolved" for="yesNoNA" itemIndex="3" rendered="#{qAndA.toggle_value == '2'}"
        disabled="#{qAndA.toggle_value != '2'}" />
        <h:outputText value="" rendered="#{qAndA.toggle_value == '1' or qAndA.toggle_value == '3'}" />
        <h:outputText value="X" rendered="#{qAndA.toggle_value == '4'}" />
    </p:column>

enter image description here

The problem with Ajax is it is changing the value immediately causing the behavior of the form to be different than with jsp. I'm not sure how to proceed, whether this is even feasible with Ajax.

I've also been playing around with more specific render and updates

 <f:ajax  render=":dataTable:2:texa"/>
 <p:ajax update="how to reference specific row" />

Cannot find component with expression ":texa" referenced from "j_idt19:j_idt48:0:j_idt99:j_idt101:dataTable:2:texa".

j_idt19:j_idt48:0:j_idt99:j_idt101:dataTable:ROWID:COMPONENT

Community
  • 1
  • 1
jeff
  • 3,618
  • 9
  • 48
  • 101

1 Answers1

1

First, when you intend to ajax-update conditionally rendered components, then you need to wrap it in another component which is always rendered and ajax-update it instead. Otherwise JS can't find anything in the HTML DOM to replace the nodes.

<p:column ...>
    <h:panelGroup id="reason">
        <h:inputTextarea ... rendered="#{...}" />
        ...
    </h:panelGroup>
</p:column>

Then, you can just use a table-relative client ID in <p:ajax update>.

<p:column ...>
    <p:selectOneRadio ...>
        ...
        <p:ajax update="reason" />
    </p:selectOneRadio>
</p:column>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks! That definitely fixed the issue with the radio button immediately updating to X when I click the NO. However I'd like the textbox (the one in the first row) to either not show and just have the h:outputText display the content, or have the textarea display the content but not be editable, because that Q was previously answered NO with a reason and form submitted (once answered no with a reason must not be able to change). I'm wondering if the only fix is to create a new status code to represent that state, but not preferred because it's a legacy app. – jeff Sep 11 '15 at 12:51
  • 1
    You're welcome. As to the follow-up question, not sure what you're after, but you should by now know that you can just use EL in `rendered` and `disabled` attributes the usual way and reference those components in `` (you can specify multiple client IDs space separated) – BalusC Sep 11 '15 at 13:02
  • I've submitted http://stackoverflow.com/questions/32525302/jsf-render-component-ajax-radio-button-selection which hopefully provides better clarity. – jeff Sep 11 '15 at 14:01