https://issues.apache.org/jira/browse/TAP5-1512

On Mon, Apr 25, 2011 at 12:15 PM, Adam Zimowski <zimowsk...@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 <zimowsk...@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 <zimowsk...@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 <zimowsk...@gmail.com> 
>>> wrote:
>>>> I'm sorry, I am on Tapestry 5.2.5 :-)
>>>>
>>>> On Thu, Apr 21, 2011 at 10:19 AM, Adam Zimowski <zimowsk...@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 <mark-li...@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 <zimowsk...@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-unsubscr...@tapestry.apache.org
>>>>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

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

Reply via email to