You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Adam Zimowski <zi...@gmail.com> on 2011/04/20 00:11:34 UTC

T5: select zone update in a form

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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
https://issues.apache.org/jira/browse/TAP5-1512

On Mon, Apr 25, 2011 at 12:15 PM, Adam Zimowski <zi...@gmail.com> wrote:
> After more debugging, the problem seems to be with Tapestry's
> IdAllocator and how it generates client side id's for select
> components, particularly when Zone is updated.
>
> In this case, what happens is that every time I update zone while form
> is in error, the ID of my select changes with incremented suffix:
>
> ORIGINAL AS EXPECTED BY FORM: a_state
>
> After resetting country causing state dropdown to repopulate, id
> becomes: a_state_1
> then a_state_2 etc...
>
> This causes ValidationTracker put error under wrong key, and
> consequently error to field binding in tracker's map cannot be
> resolved, causing <t:error/> thinking that all is good. That's why
> <t:errors/> does display the error, as it simply loops over collection
> of errors.
>
> Out of lack of deep understanding of Tapestry, I coded a simple hack
> to verify that if select update via zone kept its original id things
> would work, and indeed, the following hack fixes the problem for my
> case:
>
> Tapestry 5.2.5, AbstractField line 183:
>
>    private void setupControlName(String controlName)
>    {
>        if(controlName.startsWith("a_state"))
>                this.controlName = "a_state";
>        else
>                this.controlName = controlName;
>    }
>
> I tried filing this in JIRA but it seems to be down (Bad Gateway). In
> any case, I do not know enough about framework internals to fix this
> properly. Additional insight would be highly appreciated.
>
> Adam
>
> On Thu, Apr 21, 2011 at 11:33 AM, Adam Zimowski <zi...@gmail.com> wrote:
>> Okay, now I am pretty sure this is a bug related to usage of
>> <t:error/> in 5.2.5.  If I put <t:errors/> (which I didn't have
>> before), the state required error shows up as expected. If I use
>> <t:error/> attached to state field, the error does not show.
>>
>> It's like looking for a needle in a haystack.. lol..... still could
>> appreciate suggestion if anyone knows how to temporarily fix this.
>>
>> Adam
>>
>> On Thu, Apr 21, 2011 at 11:14 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>> Quick update:
>>>
>>> By debugging Select component I see that validation tracker correctly
>>> records the error when I submit the blank option for state. The blank
>>> option is submitted throug the following use case:
>>>
>>> 1. Select country and state (both have blank options therefore are
>>> required), but leave other fields empty.
>>> 2. Submit form. Validation on required fields (such as city, zip)
>>> results in form rendering error messages. Note: Country and State are
>>> not in error at this point.
>>> 3. While correcting errors on the form, change country. As a result,
>>> state select component is repopulated (zone update), and default blank
>>> option is select. Do not chose state.
>>> 4. Submit form with state NOT selected. Debugging select shows that it
>>> records error. Yet form is not displaying the error.
>>>
>>> So the problem is that on the first submit Tapestry is not rendering
>>> the error, which is really there. Bug?
>>>
>>> Adam
>>>
>>>
>>>
>>> On Thu, Apr 21, 2011 at 10:20 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>>> I'm sorry, I am on Tapestry 5.2.5 :-)
>>>>
>>>> On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>>>> @Josh - When I debug Select in 5.2.4 (break on processSubmission(),
>>>>> line 166), selectedValue is blank which is expected. So select
>>>>> correctly submits without a value, it's just it seems that the
>>>>> validator does not recognize that select state was repopulated via
>>>>> zone and consequently no value was submitted the 2nd time. It seems to
>>>>> me like the form validator somehow things that select has the value
>>>>> from the prior submission, but it really doesn't since it was reset
>>>>> via zone update.
>>>>>
>>>>> @Mark - by validation kicks in, I meant that form was submitted and
>>>>> validated. I have a debug on state code passed from the state select
>>>>> component when form activates, and AddressUiBean comes back with the
>>>>> correct value. That is, when I select the state from the dropdown,
>>>>> AddressUiBean carries the state as expected. Even when form is in
>>>>> error, as I change the country thereby causing state dropdown get
>>>>> repopulated, and resubmit the form with blank option for state (did
>>>>> not select the state), AddressUiBean shows null state code (as
>>>>> expected). Yet the form does not report the error on the required
>>>>> state field.
>>>>>
>>>>> Adam
>>>>>
>>>>> On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
>>>>>> When you say "Validation kicks in" does this occur after a submit?  If so,
>>>>>> is it possible that AddressUIBean is remembering the value that was present
>>>>>> when the submit occurred and then on the second submit it is getting set to
>>>>>> null again?
>>>>>>
>>>>>> At the point when you would expect an error to occur, what is the value of
>>>>>> the state field?  That should give you a good clue as to what is happening.
>>>>>>
>>>>>> Mark
>>>>>>
>>>>>> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>>>>>>
>>>>>>> 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-unsubscribe@tapestry.apache.org
>>>>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
After more debugging, the problem seems to be with Tapestry's
IdAllocator and how it generates client side id's for select
components, particularly when Zone is updated.

In this case, what happens is that every time I update zone while form
is in error, the ID of my select changes with incremented suffix:

ORIGINAL AS EXPECTED BY FORM: a_state

After resetting country causing state dropdown to repopulate, id
becomes: a_state_1
then a_state_2 etc...

This causes ValidationTracker put error under wrong key, and
consequently error to field binding in tracker's map cannot be
resolved, causing <t:error/> thinking that all is good. That's why
<t:errors/> does display the error, as it simply loops over collection
of errors.

Out of lack of deep understanding of Tapestry, I coded a simple hack
to verify that if select update via zone kept its original id things
would work, and indeed, the following hack fixes the problem for my
case:

Tapestry 5.2.5, AbstractField line 183:

    private void setupControlName(String controlName)
    {
    	if(controlName.startsWith("a_state"))
    		this.controlName = "a_state";
    	else
    		this.controlName = controlName;
    }

I tried filing this in JIRA but it seems to be down (Bad Gateway). In
any case, I do not know enough about framework internals to fix this
properly. Additional insight would be highly appreciated.

Adam

On Thu, Apr 21, 2011 at 11:33 AM, Adam Zimowski <zi...@gmail.com> wrote:
> Okay, now I am pretty sure this is a bug related to usage of
> <t:error/> in 5.2.5.  If I put <t:errors/> (which I didn't have
> before), the state required error shows up as expected. If I use
> <t:error/> attached to state field, the error does not show.
>
> It's like looking for a needle in a haystack.. lol..... still could
> appreciate suggestion if anyone knows how to temporarily fix this.
>
> Adam
>
> On Thu, Apr 21, 2011 at 11:14 AM, Adam Zimowski <zi...@gmail.com> wrote:
>> Quick update:
>>
>> By debugging Select component I see that validation tracker correctly
>> records the error when I submit the blank option for state. The blank
>> option is submitted throug the following use case:
>>
>> 1. Select country and state (both have blank options therefore are
>> required), but leave other fields empty.
>> 2. Submit form. Validation on required fields (such as city, zip)
>> results in form rendering error messages. Note: Country and State are
>> not in error at this point.
>> 3. While correcting errors on the form, change country. As a result,
>> state select component is repopulated (zone update), and default blank
>> option is select. Do not chose state.
>> 4. Submit form with state NOT selected. Debugging select shows that it
>> records error. Yet form is not displaying the error.
>>
>> So the problem is that on the first submit Tapestry is not rendering
>> the error, which is really there. Bug?
>>
>> Adam
>>
>>
>>
>> On Thu, Apr 21, 2011 at 10:20 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>> I'm sorry, I am on Tapestry 5.2.5 :-)
>>>
>>> On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>>> @Josh - When I debug Select in 5.2.4 (break on processSubmission(),
>>>> line 166), selectedValue is blank which is expected. So select
>>>> correctly submits without a value, it's just it seems that the
>>>> validator does not recognize that select state was repopulated via
>>>> zone and consequently no value was submitted the 2nd time. It seems to
>>>> me like the form validator somehow things that select has the value
>>>> from the prior submission, but it really doesn't since it was reset
>>>> via zone update.
>>>>
>>>> @Mark - by validation kicks in, I meant that form was submitted and
>>>> validated. I have a debug on state code passed from the state select
>>>> component when form activates, and AddressUiBean comes back with the
>>>> correct value. That is, when I select the state from the dropdown,
>>>> AddressUiBean carries the state as expected. Even when form is in
>>>> error, as I change the country thereby causing state dropdown get
>>>> repopulated, and resubmit the form with blank option for state (did
>>>> not select the state), AddressUiBean shows null state code (as
>>>> expected). Yet the form does not report the error on the required
>>>> state field.
>>>>
>>>> Adam
>>>>
>>>> On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
>>>>> When you say "Validation kicks in" does this occur after a submit?  If so,
>>>>> is it possible that AddressUIBean is remembering the value that was present
>>>>> when the submit occurred and then on the second submit it is getting set to
>>>>> null again?
>>>>>
>>>>> At the point when you would expect an error to occur, what is the value of
>>>>> the state field?  That should give you a good clue as to what is happening.
>>>>>
>>>>> Mark
>>>>>
>>>>> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>>>>>
>>>>>> 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-unsubscribe@tapestry.apache.org
>>>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
Okay, now I am pretty sure this is a bug related to usage of
<t:error/> in 5.2.5.  If I put <t:errors/> (which I didn't have
before), the state required error shows up as expected. If I use
<t:error/> attached to state field, the error does not show.

It's like looking for a needle in a haystack.. lol..... still could
appreciate suggestion if anyone knows how to temporarily fix this.

Adam

On Thu, Apr 21, 2011 at 11:14 AM, Adam Zimowski <zi...@gmail.com> wrote:
> Quick update:
>
> By debugging Select component I see that validation tracker correctly
> records the error when I submit the blank option for state. The blank
> option is submitted throug the following use case:
>
> 1. Select country and state (both have blank options therefore are
> required), but leave other fields empty.
> 2. Submit form. Validation on required fields (such as city, zip)
> results in form rendering error messages. Note: Country and State are
> not in error at this point.
> 3. While correcting errors on the form, change country. As a result,
> state select component is repopulated (zone update), and default blank
> option is select. Do not chose state.
> 4. Submit form with state NOT selected. Debugging select shows that it
> records error. Yet form is not displaying the error.
>
> So the problem is that on the first submit Tapestry is not rendering
> the error, which is really there. Bug?
>
> Adam
>
>
>
> On Thu, Apr 21, 2011 at 10:20 AM, Adam Zimowski <zi...@gmail.com> wrote:
>> I'm sorry, I am on Tapestry 5.2.5 :-)
>>
>> On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zi...@gmail.com> wrote:
>>> @Josh - When I debug Select in 5.2.4 (break on processSubmission(),
>>> line 166), selectedValue is blank which is expected. So select
>>> correctly submits without a value, it's just it seems that the
>>> validator does not recognize that select state was repopulated via
>>> zone and consequently no value was submitted the 2nd time. It seems to
>>> me like the form validator somehow things that select has the value
>>> from the prior submission, but it really doesn't since it was reset
>>> via zone update.
>>>
>>> @Mark - by validation kicks in, I meant that form was submitted and
>>> validated. I have a debug on state code passed from the state select
>>> component when form activates, and AddressUiBean comes back with the
>>> correct value. That is, when I select the state from the dropdown,
>>> AddressUiBean carries the state as expected. Even when form is in
>>> error, as I change the country thereby causing state dropdown get
>>> repopulated, and resubmit the form with blank option for state (did
>>> not select the state), AddressUiBean shows null state code (as
>>> expected). Yet the form does not report the error on the required
>>> state field.
>>>
>>> Adam
>>>
>>> On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
>>>> When you say "Validation kicks in" does this occur after a submit?  If so,
>>>> is it possible that AddressUIBean is remembering the value that was present
>>>> when the submit occurred and then on the second submit it is getting set to
>>>> null again?
>>>>
>>>> At the point when you would expect an error to occur, what is the value of
>>>> the state field?  That should give you a good clue as to what is happening.
>>>>
>>>> Mark
>>>>
>>>> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>>>>
>>>>> 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-unsubscribe@tapestry.apache.org
>>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>>
>>>>>
>>>>
>>>
>>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
Quick update:

By debugging Select component I see that validation tracker correctly
records the error when I submit the blank option for state. The blank
option is submitted throug the following use case:

1. Select country and state (both have blank options therefore are
required), but leave other fields empty.
2. Submit form. Validation on required fields (such as city, zip)
results in form rendering error messages. Note: Country and State are
not in error at this point.
3. While correcting errors on the form, change country. As a result,
state select component is repopulated (zone update), and default blank
option is select. Do not chose state.
4. Submit form with state NOT selected. Debugging select shows that it
records error. Yet form is not displaying the error.

So the problem is that on the first submit Tapestry is not rendering
the error, which is really there. Bug?

Adam



On Thu, Apr 21, 2011 at 10:20 AM, Adam Zimowski <zi...@gmail.com> wrote:
> I'm sorry, I am on Tapestry 5.2.5 :-)
>
> On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zi...@gmail.com> wrote:
>> @Josh - When I debug Select in 5.2.4 (break on processSubmission(),
>> line 166), selectedValue is blank which is expected. So select
>> correctly submits without a value, it's just it seems that the
>> validator does not recognize that select state was repopulated via
>> zone and consequently no value was submitted the 2nd time. It seems to
>> me like the form validator somehow things that select has the value
>> from the prior submission, but it really doesn't since it was reset
>> via zone update.
>>
>> @Mark - by validation kicks in, I meant that form was submitted and
>> validated. I have a debug on state code passed from the state select
>> component when form activates, and AddressUiBean comes back with the
>> correct value. That is, when I select the state from the dropdown,
>> AddressUiBean carries the state as expected. Even when form is in
>> error, as I change the country thereby causing state dropdown get
>> repopulated, and resubmit the form with blank option for state (did
>> not select the state), AddressUiBean shows null state code (as
>> expected). Yet the form does not report the error on the required
>> state field.
>>
>> Adam
>>
>> On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
>>> When you say "Validation kicks in" does this occur after a submit?  If so,
>>> is it possible that AddressUIBean is remembering the value that was present
>>> when the submit occurred and then on the second submit it is getting set to
>>> null again?
>>>
>>> At the point when you would expect an error to occur, what is the value of
>>> the state field?  That should give you a good clue as to what is happening.
>>>
>>> Mark
>>>
>>> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>>>
>>>> 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-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>>
>>>>
>>>
>>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
I'm sorry, I am on Tapestry 5.2.5 :-)

On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zi...@gmail.com> wrote:
> @Josh - When I debug Select in 5.2.4 (break on processSubmission(),
> line 166), selectedValue is blank which is expected. So select
> correctly submits without a value, it's just it seems that the
> validator does not recognize that select state was repopulated via
> zone and consequently no value was submitted the 2nd time. It seems to
> me like the form validator somehow things that select has the value
> from the prior submission, but it really doesn't since it was reset
> via zone update.
>
> @Mark - by validation kicks in, I meant that form was submitted and
> validated. I have a debug on state code passed from the state select
> component when form activates, and AddressUiBean comes back with the
> correct value. That is, when I select the state from the dropdown,
> AddressUiBean carries the state as expected. Even when form is in
> error, as I change the country thereby causing state dropdown get
> repopulated, and resubmit the form with blank option for state (did
> not select the state), AddressUiBean shows null state code (as
> expected). Yet the form does not report the error on the required
> state field.
>
> Adam
>
> On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
>> When you say "Validation kicks in" does this occur after a submit?  If so,
>> is it possible that AddressUIBean is remembering the value that was present
>> when the submit occurred and then on the second submit it is getting set to
>> null again?
>>
>> At the point when you would expect an error to occur, what is the value of
>> the state field?  That should give you a good clue as to what is happening.
>>
>> Mark
>>
>> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>>
>>> 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-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
@Josh - When I debug Select in 5.2.4 (break on processSubmission(),
line 166), selectedValue is blank which is expected. So select
correctly submits without a value, it's just it seems that the
validator does not recognize that select state was repopulated via
zone and consequently no value was submitted the 2nd time. It seems to
me like the form validator somehow things that select has the value
from the prior submission, but it really doesn't since it was reset
via zone update.

@Mark - by validation kicks in, I meant that form was submitted and
validated. I have a debug on state code passed from the state select
component when form activates, and AddressUiBean comes back with the
correct value. That is, when I select the state from the dropdown,
AddressUiBean carries the state as expected. Even when form is in
error, as I change the country thereby causing state dropdown get
repopulated, and resubmit the form with blank option for state (did
not select the state), AddressUiBean shows null state code (as
expected). Yet the form does not report the error on the required
state field.

Adam

On Wed, Apr 20, 2011 at 10:25 PM, Mark <ma...@xeric.net> wrote:
> When you say "Validation kicks in" does this occur after a submit?  If so,
> is it possible that AddressUIBean is remembering the value that was present
> when the submit occurred and then on the second submit it is getting set to
> null again?
>
> At the point when you would expect an error to occur, what is the value of
> the state field?  That should give you a good clue as to what is happening.
>
> Mark
>
> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>
>> 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-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>

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


Re: T5: select zone update in a form

Posted by Mark <ma...@xeric.net>.
When you say "Validation kicks in" does this occur after a submit?  If so,
is it possible that AddressUIBean is remembering the value that was present
when the submit occurred and then on the second submit it is getting set to
null again?

At the point when you would expect an error to occur, what is the value of
the state field?  That should give you a good clue as to what is happening.

Mark

On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:

> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: T5: select zone update in a form

Posted by Josh Canfield <jo...@gmail.com>.
I don't have the time now to dive into this, but it sounds like the
select thinks it has a value when it's time to validate. Have you set
a breakpoint in the Select component to see what it thinks that value
is?

Josh

On Wed, Apr 20, 2011 at 1:36 PM, Adam Zimowski <zi...@gmail.com> wrote:
> Nobody ran into this? I have a feeling that I'm doing something wrong,
> but then, I'm not sure either if Tapestry is just not working as
> expected.
>
> If I make the stateUpdateZone wrap entire form, then form is aware of
> state value change. But I do not want to refresh entire form, all I
> want to update is my little zone which I want to wrap state select in.
>
> Adam
>
> On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
>> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

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


Re: T5: select zone update in a form

Posted by Adam Zimowski <zi...@gmail.com>.
Nobody ran into this? I have a feeling that I'm doing something wrong,
but then, I'm not sure either if Tapestry is just not working as
expected.

If I make the stateUpdateZone wrap entire form, then form is aware of
state value change. But I do not want to refresh entire form, all I
want to update is my little zone which I want to wrap state select in.

Adam

On Tue, Apr 19, 2011 at 5:11 PM, Adam Zimowski <zi...@gmail.com> wrote:
> 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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org