Reputation: 3742
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?
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>
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
Upvotes: 1
Views: 4000
Reputation: 1108732
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>
Upvotes: 1