Adam, Thank you for the feedback. Looking forward to using the AJAX XMLHttp changes.
Regards, Graeme. -----Original Message----- From: Adam Winer [mailto:[EMAIL PROTECTED] Sent: Friday, 8 June 2007 1:44 AM To: MyFaces Discussion Subject: Re: [Trinidad] PPR in panelFormLayout - Changing required/rendered states Currently, you have to put the partialTriggers on the panelFormLayout as a whole, which is awkward. I think it's about time we look at re-jiggering the DOM here to support PPR of labels, but I've got plenty on my plate right now. FYI, the workaround of not using trh:body isn't going to be a workaround for much longer. I'm hard at work swapping out the iframe-based PPR mechanism for real AJAX XMLHttp (going very well), and as part of that PPR now works no matter what components you have on the page. (Bye, bye, panelPartialRoot!) --- Adam On 6/6/07, Graeme Steyn <[EMAIL PROTECTED]> wrote: > > > Hi, > > Would anyone be able to shed some light on the problem that I am > trying to find a suitable work-around for. I have two sections of > code where I am attempting to make use of PPR in Trinidad (using > Facelets 1.1.12, Trinidad 1.2, JSF 1.2_04 p02, SJSAS 9.0 ur1 patch 03). > > 1. In the first instance, a change in the value of a field needs to > set the required field indicator on the dependant fields. The PPR is > however not updating the label indicator to show a required status in > this case. I am assuming that this is related to ADFFACES-471, where > the resolution indicates that the labels in a panelFormLayout cannot be updated via PPR. > The component will however, be set to required so that when the user > navigates to the next page, they get corresponding required error > messages (would be nice to show the field as required before getting the errors). > > The current work-around that I have used is to enclose all of the > dependant fields in a separate panelFormLayout that has its > partialTriggers property set to the prefChannel. This works, but > messes up the page layout a little as the dependant fields are no longer aligned with the driving field. > > The ability to change a field's required status based on some other > driving value is common throughout the application making a suitable > work-around important. > > > 2. In the second instance, I am attempting to hide/unhide a field > using PPR. Once again, with the fields laid out using the normal > panelFormLayout, the PPR does not work and the rendered state of the > component does not change - it is always displayed. The disabled > attribute for the birthCountry does work. The problem sample appears below. > > In this case the work-around is basically the same as the first one, > but using a panelGroupLayout with its partialTriggers set to the > driving components. Once again, not ideal as it changes the original form layout. > > For both scenarios a third work-around is to do the following: > > a. Change the <trh:body> tag to a normal <body> tag. > b. Change the ValueChangeListeners to update the model when a value > changes and force rendering using getFacesContext().renderResponse(); > c. Link the required / rendered properties to the updated model values. > > The big disadvantage is that this provides the required effect by > doing a full page refresh every time a driving value changes - PPR has > effectively been removed. > > Would anyone have any suggestions on a more efficient work-around for > the two problem scenarios. > > Thank you. > > Regards, > > Graeme. > > > > > ---------------------------------------------------------------------- > ------------------------------------------------------- > Problem Code Sample 1: > ------------------------------------------------------------------------ ----------------------------------------------------- > <tr:panelFormLayout > shortDesc="#{bundle.fldSetContact}"> > > <tr:selectOneChoice > id="prefChannel" > label="#{bundle.contactPrefChannel}" > value="#{contact.preferredChannel}" > immediate="true" > autoSubmit="true" > > binding="#{contact.preferredChannelComponent}" > > valueChangeListener="#{contact.preferredChannelValueChange}" > required="true" > disabled="#{formReadOnly}" > shortDesc="#{bundle.contactPrefChannel}"> > <f:selectItems > value="#{applicationSelectItems.contactTypeList}" /> > </tr:selectOneChoice> > > <tr:inputText > id="WRK_PH" > label="#{bundle.contactPhoneDay}" > value="#{contact.dayPhone}" > disabled="#{formReadOnly}" > partialTriggers="prefChannel" > binding="#{contact.workComponent}" > required="#{visit.candidate.prefContact == > 'WRK_PH'}" > shortDesc="#{bundle.contactPhoneDay}"> > <f:validateLength maximum="12" /> > <tr:validateRegExp > pattern="[\s0-9]+" > > messageDetailNoMatch="#{bundle.formatTelephoneNumber}" /> > </tr:inputText> > > <tr:inputText > id="AH_PH" > label="#{bundle.contactPhoneAH}" > value="#{contact.afterHrsPhone}" > disabled="#{formReadOnly}" > partialTriggers="prefChannel" > binding="#{contact.afterHoursComponent}" > required="#{visit.candidate.prefContact == 'AH_PH'}" > shortDesc="#{bundle.contactPhoneAH}"> > <f:validateLength maximum="12" /> > <tr:validateRegExp > pattern="[\s0-9]+" > > messageDetailNoMatch="#{bundle.formatTelephoneNumber}" /> > </tr:inputText> > > ...etc. > > ---------------------------------------------------------------------- > ------------------------------------------------------- > preferredChannelValueChange contains: > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > public void > preferredChannelValueChange(ValueChangeEvent event) { > > // Reset all required indicators. > afterHoursComponent.setRequired(false); > emailComponent.setRequired(false); > faxComponent.setRequired(false); > mobileComponent.setRequired(false); > workComponent.setRequired(false); > > Contact.ContactType preferredChannel = (Contact.ContactType) > event.getNewValue(); > switch (preferredChannel) { > > case AH_PH: > afterHoursComponent.setRequired(true); > break; > case EMAIL: > emailComponent.setRequired(true); > break; > case FAX: > faxComponent.setRequired(true); > break; > case MOB: > mobileComponent.setRequired(true); > break; > case WRK_PH: > workComponent.setRequired(true); > break; > } > > getFacesContext().renderResponse(); > > } > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > Problem 1 Work-around: > ------------------------------------------------------------------------ ----------------------------------------------------- > <tr:panelFormLayout > shortDesc="#{bundle.fldSetContact}" > > > <tr:selectOneChoice > id="prefChannel" > label="#{bundle.contactPrefChannel}" > value="#{contact.preferredChannel}" > immediate="true" > autoSubmit="true" > > binding="#{contact.preferredChannelComponent}" > > valueChangeListener="#{contact.preferredChannelValueChange}" > required="true" > disabled="#{formReadOnly}" > shortDesc="#{bundle.contactPrefChannel}"> > <f:selectItems > value="#{applicationSelectItems.contactTypeList}" /> > </tr:selectOneChoice> > > </tr:panelFormLayout> > > <tr:spacer > height="12" /> > > <tr:panelFormLayout > shortDesc="#{bundle.fldSetContact}" > partialTriggers="prefChannel" > > > <tr:inputText > id="WRK_PH" > label="#{bundle.contactPhoneDay}" > value="#{contact.dayPhone}" > disabled="#{formReadOnly}" > binding="#{contact.workComponent}" > required="#{visit.candidate.prefContact == > 'WRK_PH'}" > shortDesc="#{bundle.contactPhoneDay}"> > <f:validateLength maximum="12" /> > <tr:validateRegExp > pattern="[\s0-9]+" > > messageDetailNoMatch="#{bundle.formatTelephoneNumber}" /> > </tr:inputText> > > <tr:inputText > id="AH_PH" > label="#{bundle.contactPhoneAH}" > value="#{contact.afterHrsPhone}" > disabled="#{formReadOnly}" > binding="#{contact.afterHoursComponent}" > required="#{visit.candidate.prefContact == 'AH_PH'}" > shortDesc="#{bundle.contactPhoneAH}"> > <f:validateLength maximum="12" /> > <tr:validateRegExp > pattern="[\s0-9]+" > > messageDetailNoMatch="#{bundle.formatTelephoneNumber}" /> > </tr:inputText> > > ...etc. > > ValueChangeListener code unchanged. > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > > ---------------------------------------------------------------------- > ------------------------------------------------------- > Problem Code Sample 2: > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > <tr:panelFormLayout > shortDesc="#{bundle.fldSetEthnicity}"> > > <tr:panelLabelAndMessage > id="residencyLabel" > for="residency" > label="#{bundle.ethnicResidency}" > shortDesc="#{bundle.ethnicResidency}" > showRequired="true"> > > <tr:panelGroupLayout > id="residency" > layout="vertical" > binding="#{bio.residencyComponent}"> > > <tr:selectBooleanRadio > id="residency_1" > disabled="#{formReadOnly or !visit.domesticStudent}" > group="residency" > simple="true" > value="#{visit.citizenshipItems['au'].selected}" > text="#{bundle.ethnicResidencyAu}" > valueChangeListener="#{bio.residencyValueChange}" > immediate="true" > autoSubmit="true" /> > > <tr:selectBooleanRadio > id="residency_2" > disabled="#{formReadOnly or !visit.domesticStudent}" > group="residency" > simple="true" > value="#{visit.citizenshipItems['nz'].selected}" > valueChangeListener="#{bio.residencyValueChange}" > immediate="true" > autoSubmit="true" > text="#{bundle.ethnicResidencyNz}" /> > > </tr:panelGroupLayout> > > <tr:message > for="residency" /> > > </tr:panelLabelAndMessage> > > <tr:selectOneChoice > id="birthCountry" > label="#{bundle.ethnicBirthCountry}" > binding="#{bio.birthCountryComponent}" > partialTriggers="residency_1 residency_2" > > value="#{visit.candidate.culture.birthCountry}" > disabled="#{formReadOnly > or > visit.candidate.culture.citizenshipStatus == 1}" > > <f:selectItems > value="#{applicationSelectItems.countryList}" /> > </tr:selectOneChoice> > > <tr:selectOneChoice > id="citizenshipCountry" > label="#{bundle.ethnicCitizenshipCountry}" > > value="#{visit.candidate.culture.citizenCountry}" > partialTriggers="residency_1 residency_2" > binding="#{bio.citizenshipCountryComponent}" > disabled="#{formReadOnly}" > > <f:selectItems > value="#{applicationSelectItems.countryList}" /> > </tr:selectOneChoice> > > </tr:panelFormLayout> > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > ValueChangeListener contains: > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > public void residencyValueChange(ValueChangeEvent > event) { > > // Force updating of the model so that render process > // uses the most current value > > residencyComponent.processUpdates(getFacesContext()); > boolean selectionExists = updateCitizenshipModel(); > > CitizenshipItem AUSCit = > (CitizenshipItem)getBean("au"); > > // Reset if this candidate has indicated that they are AUS. > if (AUSCit.getResidencyCode() != null && > AUSCit.getResidencyCode().equals(getCandidate().getCulture().getCitize > nshipStatus())) > { > > getCandidate().getCulture().setBirthCountry(null); //reset the model > birthCountryComponent.resetValue(); > birthCountryComponent.setDisabled(true); > citizenshipCountryComponent.setRendered(false); > } else { > birthCountryComponent.setDisabled(false); > citizenshipCountryComponent.setRendered(true); > } > > // Render response to prevent going to the validation phase for the > // other components. This prevents validation errors for the as yet > // incomplete fields. > getFacesContext().renderResponse(); > } > > > ---------------------------------------------------------------------- > ------------------------------------------------------- > > Problem 2 Work-around: > > ------------------------------------------------------------------------ ----------------------------------------------------- > <tr:panelFormLayout > shortDesc="#{bundle.fldSetEthnicity}"> > > <tr:panelLabelAndMessage > id="residencyLabel" > for="residency" > label="#{bundle.ethnicResidency}" > shortDesc="#{bundle.ethnicResidency}" > showRequired="true"> > > <tr:panelGroupLayout > id="residency" > layout="vertical" > binding="#{bio.residencyComponent}"> > > <tr:selectBooleanRadio > id="residency_1" > disabled="#{formReadOnly or !visit.domesticStudent}" > group="residency" > simple="true" > value="#{visit.citizenshipItems['au'].selected}" > text="#{bundle.ethnicResidencyAu}" > valueChangeListener="#{bio.residencyValueChange}" > immediate="true" > autoSubmit="true" /> > > <tr:selectBooleanRadio > id="residency_2" > disabled="#{formReadOnly or !visit.domesticStudent}" > group="residency" > simple="true" > value="#{visit.citizenshipItems['nz'].selected}" > valueChangeListener="#{bio.residencyValueChange}" > immediate="true" > autoSubmit="true" > text="#{bundle.ethnicResidencyNz}" /> > > </tr:panelGroupLayout> > > <tr:message > for="residency" /> > </tr:panelLabelAndMessage> > > <tr:panelGroupLayout > layout="vertical" > partialTriggers="residency_1 residency_2"> > > <tr:selectOneChoice > id="birthCountry" > label="#{bundle.ethnicBirthCountry}" > binding="#{bio.birthCountryComponent}" > > value="#{visit.candidate.culture.birthCountry}" > disabled="#{formReadOnly > or > visit.candidate.culture.citizenshipStatus == 1}" > > <f:selectItems > value="#{applicationSelectItems.countryList}" /> > </tr:selectOneChoice> > > <tr:selectOneChoice > id="citizenshipCountry" > label="#{bundle.ethnicCitizenshipCountry}" > > value="#{visit.candidate.culture.citizenCountry}" > binding="#{bio.citizenshipCountryComponent}" > disabled="#{formReadOnly}" > > <f:selectItems > value="#{applicationSelectItems.countryList}" /> > </tr:selectOneChoice> > </tr:panelGroupLayout> > > </tr:panelFormLayout> > > ValueChangeListener remains unchanged. > > ---------------------------------------------------------------------- > ------------------------------------------------------- > >

