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

Reply via email to