You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Rich M <ri...@moremagic.com> on 2010/08/11 23:33:40 UTC

Custom Validation Bubbles

Hi,

I've found resources that explain how to remove the validation bubbles, 
but I'm looking to display validation bubbles similar to how it's 
possible to record form errors to <t:errors/> after a 'failed' form 
submission.

I have tight spacing in the UI layout and having to accommodate for the 
<t:errors/> isn't much of an option as it shifts the layout down and 
takes up valuable vertical space. The bubbles are really nice because 
they overlay!

One note is that I've seen that it's possible to create customer 
validators (like 'letters' from the jumpstart demo) but my validation is 
server-side not client side, as it compares a password with the 
confirmation password. So I'm trying to achieve this after the user has 
submitted the form to be sure they think the passwords are what they want.

Thanks,
Rich

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


Re: Custom Validation Bubbles

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Wed, 18 Aug 2010 18:16:31 -0300, Rich M <ri...@moremagic.com> wrote:

> Hi,

Hi!

> 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.

They're not AJAX bubbles: they're triggered by the JavaScript  
implementation of the validators (unless you created some validator that  
uses AJAX). In other words, there's validation that is done client-side  
though JavaScript (required, min, max, minlength, maxlength, etc) and  
they're also done server-side.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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


Re: Custom Validation Bubbles

Posted by Josh Canfield <jo...@gmail.com>.
> 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 <ri...@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<ri...@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-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
> 

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


Re: Custom Validation Bubbles

Posted by Rich M <ri...@moremagic.com>.
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<ri...@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-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: Custom Validation Bubbles

Posted by Josh Canfield <jo...@gmail.com>.
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 <ri...@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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
--
http://www.bodylabgym.com - a private, by appointment only, one-on-one
health and fitness facility.
--
http://www.ectransition.com - Quality Electronic Cigarettes at a
reasonable price!
--
TheDailyTube.com. Sign up and get the best new videos on the internet
delivered fresh to your inbox.

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


Re: Custom Validation Bubbles

Posted by Rich M <ri...@moremagic.com>.
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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Custom Validation Bubbles

Posted by Rich M <ri...@moremagic.com>.
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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Custom Validation Bubbles

Posted by Rich M <ri...@moremagic.com>.
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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Custom Validation Bubbles

Posted by Josh Canfield <jo...@gmail.com>.
You can control the look of the errors component using CSS. I also use
a component that extends Errors so that it can render outside of the
form:

public class FormErrors extends Errors {
    @Parameter(required = true)
    private Form _form;

    @Inject
    private Environment _environment;

    void setupRender() {
        final ValidationTracker tracker = _form.getDefaultTracker();
        _environment.push(ValidationTracker.class, tracker);
    }

    boolean beforeRenderTemplate() {
        return false; // don't render the body
    }

    void cleanupRender() {
        _environment.pop(ValidationTracker.class);
    }
}


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:


public static void contributeMarkupRenderer(
            OrderedConfiguration<MarkupRendererFilter> configuration,
            final Environment environment,
            final RenderSupport support) {

        MarkupRendererFilter validationDecorator = new MarkupRendererFilter() {
            public void renderMarkup(MarkupWriter writer,
MarkupRenderer renderer) {
                ValidationDecorator decorator = new
                        BubbleValidationDecorator(environment, support);

                environment.push(ValidationDecorator.class, decorator);
                renderer.renderMarkup(writer);
                environment.pop(ValidationDecorator.class);

            }
        };

        configuration.override("DefaultValidationDecorator",
validationDecorator);
    }

On Wed, Aug 11, 2010 at 2:33 PM, Rich M <ri...@moremagic.com> wrote:
> Hi,
>
> I've found resources that explain how to remove the validation bubbles, but
> I'm looking to display validation bubbles similar to how it's possible to
> record form errors to <t:errors/> after a 'failed' form submission.
>
> I have tight spacing in the UI layout and having to accommodate for the
> <t:errors/> isn't much of an option as it shifts the layout down and takes
> up valuable vertical space. The bubbles are really nice because they
> overlay!
>
> One note is that I've seen that it's possible to create customer validators
> (like 'letters' from the jumpstart demo) but my validation is server-side
> not client side, as it compares a password with the confirmation password.
> So I'm trying to achieve this after the user has submitted the form to be
> sure they think the passwords are what they want.
>
> Thanks,
> Rich
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
--
http://www.bodylabgym.com - a private, by appointment only, one-on-one
health and fitness facility.
--
http://www.ectransition.com - Quality Electronic Cigarettes at a
reasonable price!
--
TheDailyTube.com. Sign up and get the best new videos on the internet
delivered fresh to your inbox.

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