> I'm curious though, how did you know about the FieldToTracker map and the 
> control name?

Whenever it's not obvious what's happening I step into the code with a 
debugger. Set a breakpoint before you call recordError and you can step through 
the whole process. Then you can set a breakpoint in the validation decorator 
and step through the code to see why it doesn't think there is an error.

I saw that it was depending on the control name, tracked down where it was set, 
and there you have it!


-- Josh

On Aug 19, 2010, at 7:27 AM, Rich M <rich...@moremagic.com> wrote:

> Thanks again Josh. That was simple. I'm curious though, how did you know 
> about the FieldToTracker map and the control name? I gave a shot at looking 
> through the Tapestry source code to try and see if I could figure something 
> out by that, but I felt a bit lost and reading the Errors class mislead me a 
> bit.
> 
> Thanks,
> Rich
> 
> On 08/18/2010 06:33 PM, Josh Canfield wrote:
>> Sooo...
>> 
>> When you set an error on a field before it's been rendered then the
>> error goes into the list of errors (so you see it in t:errors) but the
>> connection between the field and the error is lost. The reason is that
>> the fieldToTracker map is keyed on the fields control name which isn't
>> allocated until the field's setupRender phase. You could
>> 
>> So, how do you get on the other side of the field's setupRender phase?
>> How about a mixin! ;)
>> 
>> @MixinAfter
>> public class AttachError {
>>     @Parameter(required = true, allowNull = true)
>>     private String message;
>> 
>>     @Environmental
>>     private ValidationTracker tracker;
>> 
>>     @InjectContainer
>>     private Field field;
>> 
>>     void setupRender() {
>>         if (message != null)
>>             tracker.recordError(field, message);
>>     }
>> }
>> 
>> And use it like so:
>> 
>>     @Component(parameters = {"AttachError.message=fieldError"})
>>     @Mixins("AttachError")
>>     private TextField _textField;
>> 
>> 
>> Josh
>> 
>> 
>> 
>> On Wed, Aug 18, 2010 at 2:16 PM, Rich M<rich...@moremagic.com>  wrote:
>>   
>>> Hi,
>>> 
>>> I'm still having a hard time grasping this. I tried thinking of a way to
>>> trigger an event in the CustomerLogin component to resubmit so the errors
>>> would show, no go. I tried using the onActivate of the container Page to
>>> load things in the CustomerLogin component and then resubmit the page, no
>>> go. I tried using RenderSupport like in the ValidationDecorator to add the
>>> error script, but RenderSupport isn't available inside the component before
>>> the render cycle and it's too late at setupRender phase or after.
>>> 
>>> Strangely enough, if I include<t:errors/>  in the form of CustomerLogin, it
>>> actually displays the error, which really suprised me when I did a sanity
>>> check. I'm not sure why that gets triggered and not the AJAX bubbles from
>>> the ValidationDecorator that works in other places after form submit.
>>> 
>>> At this point if you couldn't tell I'm trying any half-baked alternative
>>> strategy I can imagine to try and make progress. There's got to be something
>>> I'm missing no?
>>> 
>>> Included below is some related code, this is all triggered by the activation
>>> URL<http://localhost/myapp/index/expired>
>>> 
>>> Thanks,
>>> Rich
>>> 
>>> CustomerLogin
>>> 
>>> public class CustomerLogin {
>>>    /**
>>>     * Customer Log-In Form */
>>> 
>>>    @Parameter(defaultPrefix = BindingConstants.LITERAL)
>>>    private String expired;
>>> 
>>>    @Inject
>>>    private Logger log;
>>> 
>>>    @InjectPage
>>>    private CaiIndex caiIndex;
>>> 
>>>    @Property
>>>    private Customer custLog;
>>> 
>>>    @Property @Persist("flash")
>>>    private String custId;
>>>    @Property @Persist("flash")
>>>    private String custPw;
>>> 
>>>    @Component(id="custPw")
>>>    private PasswordField custPwField;
>>> 
>>>    @Component
>>>    private Form custLoginForm;
>>> 
>>>    @Inject
>>>    private CustomerDAO cdao;
>>> 
>>>    @Inject
>>>    private CustSession custSession;
>>> 
>>>    @Environmental
>>>    private RenderSupport _renderSupport;
>>> 
>>> 
>>>    public void setExpired(){
>>>        log.debug("In setExpired of CustomerLogin");
>>> 
>>>        if ("expired".equals(expired)){
>>>            log.debug("Setting recordError in setupRender for expired
>>> customer session" +
>>>                    "\n" + " custPwField: " + custPwField);
>>>            custLoginForm.recordError(custPwField, "Session expired. Please
>>> login again.");
>>> 
>>>            ValidationTracker vt = custLoginForm.getDefaultTracker();
>>>            log.debug("Is custPwField in error?" + vt.inError(custPwField));
>>> 
>>>        //
>>>  
>>> _renderSupport.addScript("$('%s').getFieldEventManager().showValidationMessage('%s');",
>>>          //          custPwField.getClientId(), vt.getError(custPwField));
>>>        }
>>>    }
>>> 
>>>    public void setupRender(){
>>>        //log.debug("In onActivate of CustomerLogin");
>>>        //
>>>        //if ("expired".equals(expired)){
>>>        //    log.debug("Setting recordError in setupRender for expired
>>> customer session" +
>>>        //            "\n" + " custPwField: " + custPwField);
>>>        //    custLoginForm.recordError(custPwField, "Session expired. Please
>>> login again.");
>>> 
>>>        //    ValidationTracker vt = custLoginForm.getDefaultTracker();
>>>        //    log.debug("Is custPwField in error?" +
>>> vt.inError(custPwField));
>>> 
>>>        //
>>>  
>>> _renderSupport.addScript("$('%s').getFieldEventManager().showValidationMessage('%s');",
>>>         //           custPwField.getClientId(), vt.getError(custPwField));
>>>    //    }
>>>    }
>>> 
>>>    Object onSuccessFromCustLoginForm(){
>>>        log.debug("In onSuccessFromCustLoginForm, going to see if customer is
>>> valid then go to index");
>>> 
>>>        if(!cdao.validate(custId, custPw)){
>>>            custLoginForm.recordError(custPwField, "Invalid user name or
>>> password");
>>>            log.error("User failed validation on login page");
>>>            return this;
>>>        }
>>> 
>>>        log.debug("User was validated successfully");
>>> 
>>>        custSession.setUserName(custId);
>>>        custSession.setValid();
>>> 
>>>        return caiIndex.initialize(custSession);
>>>    }
>>> }
>>> 
>>> Index page:
>>> 
>>> public class Index {
>>>    public Object onActionFromRegister(){
>>>        return "register";
>>>    }
>>> 
>>>    @Inject
>>>    private Logger log;
>>> 
>>>    @Property @Persist("flash")
>>>    private Boolean expired;
>>> 
>>>    @Component
>>>    private CustomerLogin clogin;
>>> 
>>>    void onActivate(String s){
>>>        log.debug("in setupRender of index page: activation string = " + s);
>>> 
>>>        if ("expired".equals(s)){
>>>            expired = true;
>>>            clogin.setExpired();
>>>            //return "index";
>>>        }
>>> 
>>>        //return this;
>>>    }
>>> }
>>> 
>>> 
>>> On 08/16/2010 04:52 PM, Rich M wrote:
>>>     
>>>> Hi,
>>>> 
>>>> a somewhat related question. It's now possible thanks to the Decorator for
>>>> my webapp to display validation bubbles after a form submit. I'd also like
>>>> to be able to set an error somewhere in the beginning of the rendering
>>>> process and have it show. I'm having a hard time figuring out how to
>>>> accomplish this. By the time setupRender or beginRender occurs, it seems 
>>>> the
>>>> form.recordError(String) method and its overload do not affect the current
>>>> render cycle.
>>>> 
>>>> I tried doing something along the lines of dumping the first render cycle,
>>>> returning false at a late render cycle and going back through, but that
>>>> doesn't seem to do anything useful.
>>>> 
>>>> To give more perspective, my application manages a session timer, and when
>>>> the timeout occurs the user gets booted to the main page. As before I don't
>>>> want to introduce more text to the page and would prefer to have the login
>>>> form of the main page grab the user's focus with a "Session has timed out"
>>>> pop up bubble.
>>>> 
>>>> I am passing an activation context to the main page, and having this pipe
>>>> into the login component via a parameter. The trouble is what can I do
>>>> within the Login component to display the popup error when it becomes aware
>>>> the parameter for the session timeout is triggered.
>>>> 
>>>> Thanks,
>>>> Rich
>>>> 
>>>> On 08/12/2010 10:40 AM, Rich M wrote:
>>>>       
>>>>> Thanks Josh,
>>>>> 
>>>>> that was exactly what I was looking to do. Hopefully I'll be able to
>>>>> start seeing these things on my own sometime soon!
>>>>> 
>>>>> -Rich
>>>>> 
>>>>> On 08/11/2010 08:11 PM, Josh Canfield wrote:
>>>>>         
>>>>>> If you are looking to get the error bubble to pop up after you submit
>>>>>> the form you could use this:
>>>>>> 
>>>>>> public class BubbleValidationDecorator extends BaseValidationDecorator {
>>>>>>     private final Environment _environment;
>>>>>> 
>>>>>>     private final RenderSupport _renderSupport;
>>>>>> 
>>>>>>     public BubbleValidationDecorator(Environment environment,
>>>>>>                                      RenderSupport renderSupport) {
>>>>>>         _environment = environment;
>>>>>>         _renderSupport = renderSupport;
>>>>>>     }
>>>>>> 
>>>>>>     public void afterField(Field field) {
>>>>>>         final ValidationTracker validationTracker =
>>>>>> _environment.peekRequired(ValidationTracker.class);
>>>>>>         if (validationTracker.inError(field)) {
>>>>>>             _renderSupport.addScript(
>>>>>> 
>>>>>> "$('%s').getFieldEventManager().showValidationMessage('%s');",
>>>>>>                     field.getClientId(),
>>>>>> validationTracker.getError(field));
>>>>>>         }
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> 
>>>>>> Add to AppModule:
>>>>>> 
>>>>>> 
>>>>>>           
>>>>>         
>>>>       
>>> 
>>> ---------------------------------------------------------------------
>>> 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
> 

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

Reply via email to