I have a typical address form with street, city zip textfields and two
dropdowns: country and state. The state dropdown is wrapped in a zone
so that when country is selected, states are populated:

<div class="kk-field" t:type="zone" t:id="stateModelZone"><t:select
t:id="a_state" model="stateModel" validate="required"
value="stateKode" blankOption="ALWAYS" blankLabel="literal:--Please
Select"/></div>

All works okay, except for a test case my business analyst found which
I can't figure out.

You fill out a form, pick a country then pick a state and suppose you
leave city field empty which is required. Validation kicks in. While
correcting a city error, you decide to switch a country causing state
list to get repopulated and state be not selected again. Suppose you
submit the form, I expect the error that state is required, but error
is not thrown. Only if I resubmit the form a second time, state will
be flagged in error.

I am resetting state to null on country change. I have even tried
setting form state field in error, none of which works.

---------- TML --------------

<t:form t:id="registrationForm">
<div class="kk-hdr">Address Information</div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_line1"/> :</div>
 <div class="kk-field"><t:textfield t:id="a_line1" value="address.line1"/></div>
 <t:error class="literal:kk-error" for="a_line1"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_line2"/> :</div>
 <div class="kk-field"><t:textfield t:id="a_line2" value="address.line2"/></div>
 <t:error class="literal:kk-error" for="a_line2"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_line3"/> :</div>
 <div class="kk-field"><t:textfield t:id="a_line3" value="address.line3"/></div>
 <t:error class="literal:kk-error" for="a_line3"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_city"/> :</div>
 <div class="kk-field"><t:textfield t:id="a_city" value="address.city"/></div>
 <t:error class="literal:kk-error" for="a_city"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_zip"/> :</div>
 <div class="kk-field"><t:textfield t:id="a_zip" value="address.zipCode"/></div>
 <t:error class="literal:kk-error" for="a_zip"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_state"/> :</div>
 <div class="kk-field" t:type="zone" t:id="stateModelZone"><t:select
t:id="a_state" model="stateModel" validate="required"
value="address.stateCode" blankOption="ALWAYS"
blankLabel="literal:--Please Select"/></div>
 <t:error class="literal:kk-error" for="a_state"/>
 </div>
 <div class="kk-row">
 <div class="kk-label"><t:label for="a_country"/> :</div>
 <div class="kk-field"><t:select t:id="a_country" model="countryModel"
value="address.countryCode" blankOption="NEVER"
zone="stateModelZone"/></div>
 </div>
 <p>
 <input t:type="submit" value="message:submit-label"/>
 </p>
</t:form>

---------------- Page class -------------------------

public class Register extends BasePage {

        @Inject
        private Logger log;
        
        @Inject
        private UtilityServiceRemote utilityService;

        @Persist
        @Property
        private AddressUiBean address;

        @OnEvent(value=EventConstants.PREPARE)
        void initialize() {
                if(address == null) address = new AddressUiBean();
                if(contact == null) contact = new ContactUiBean();
                if(registration == null) registration = new RegisterUiBean();
                
                String countryCode = address.getCountryCode();
                if(countryCode == null) {
                        Locale locale = getLocale();
                        countryCode = locale.getCountry();
                        address.setCountryCode(countryCode);
                }
                
                log.debug("address state code {}", address.getStateCode());
        }

        @Cached
        public Map<String, String> getCountryModel() {
                Map<String, String> model = new LinkedHashMap<String, String>();
                List<CountryBean> countries =
                        utilityService.getAllCountries(getLocale());
                for(CountryBean country : countries) {
                        String code = country.getCodeIsoAlpha2();
                        String description = country.getShortName();
                        log.debug("code: {}, description: {}", code, 
description);
                        model.put(code, description);
                }
                return model;
        }
        
        @OnEvent(value=EventConstants.VALUE_CHANGED, component="a_country")
        public Object onCountrySelected(String aCountryCode) {
                log.debug("selected country: {}", aCountryCode);
                address.setStateCode(null);
                return stateModelZone.getBody();
        }
        
        @Cached
        public Map<String, String> getStateModel() {
                Map<String, String> model = new LinkedHashMap<String, String>();
                String countryCode = address.getCountryCode();
                List<StateProvinceBean> states =
                        
utilityService.getAllStateProvincesForCountry(countryCode, getLocale());
                for(StateProvinceBean state : states) {
                        String code = state.getLookupCode();
                        String name = state.getLongName();
                        log.debug("code: {}, name {}", code, name);
                        model.put(code, name);
                }
                return model;
        }
}

Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to