> 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