You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Peter Ertl (JIRA)" <ji...@apache.org> on 2007/12/08 13:42:43 UTC
[jira] Issue Comment Edited: (WICKET-1213) enable subclassing of
AjaxRequestTarget
[ https://issues.apache.org/jira/browse/WICKET-1213?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12549696 ]
pete edited comment on WICKET-1213 at 12/8/07 4:41 AM:
-------------------------------------------------------------
here's an example of how this could be used -- you might get an better idea of what I want to achieve with this patch...
this is some code inside my template page:
@Override
public AjaxRequestTarget newAjaxRequestTarget()
{
final AjaxRequestTarget target = super.newAjaxRequestTarget();
target.addListener(new AjaxRequestTarget.IListener()
{
@SuppressWarnings({"RawUseOfParameterizedType"})
public void onBeforeRespond(final Map map, final AjaxRequestTarget target)
{
// always render the feedback component that belongs to this template
// no need to include it in all pages that use this template
target.addComponent(feedbackPanel);
}
@SuppressWarnings({"RawUseOfParameterizedType"})
public void onAfterRespond(final Map map, final AjaxRequestTarget.IJavascriptResponse response)
{
//
// set the focus on the first form component that has errors
// this is very convenient for the user as he doesn't have to click on the erroneous field first
//
// this has to be rendered in onAfterRespond to be sure the dom component for setting focus on has
// already been rendered in the dom structure of the browser
//
final FormComponent focus = (FormComponent) visitChildren(FormComponent.class, new IVisitor()
{
public Object component(final Component component)
{
final FormComponent formComponent = (FormComponent) component;
if (formComponent.hasErrorMessage() && formComponent.getOutputMarkupId())
return formComponent;
return CONTINUE_TRAVERSAL;
}
});
if (focus != null)
target.focusComponent(focus);
}
});
return target;
}
another possible example (using common functionality specific to your application this time)
@Override
public AjaxRequestTarget newAjaxRequestTarget()
{
return new CustomAjaxRequestTarget(); // extends AjaxRequestTarget
}
so inside your pages you could for example do this:
public void onClick(final AjaxRequestTarget target)
{
final CustomAjaxRequestTarget customTarget = (CustomAjaxRequestTarget)target;
// change some setting on the page
// ..
// let the user take notice of the change (the heavily-used effect from Ruby on Rails we probably all know)
customTarget.applyYellowFadeEffect(component);
// make it even more obvious (some freaky javascript :-)
customTarget.letScreenShakeUpAndDown();
// even half-blind people should see that (another crazy js)
customTarget.zoomInAndOutAgain(component);
}
this way you could provide some common ajax functionality to your application which is easy to use and implementation details are perfectly hidden
was (Author: pete):
here's an example of how this could be used -- you might get an better idea of what I want to achieve with this patch...
this is some code inside my template page:
@Override
public AjaxRequestTarget newAjaxRequestTarget()
{
final AjaxRequestTarget target = super.newAjaxRequestTarget();
target.addListener(new AjaxRequestTarget.IListener()
{
@SuppressWarnings({"RawUseOfParameterizedType"})
public void onBeforeRespond(final Map map, final AjaxRequestTarget target)
{
// always render the feedback component that belongs to this template
// no need to include it in all pages that use this template
target.addComponent(feedbackPanel);
}
@SuppressWarnings({"RawUseOfParameterizedType"})
public void onAfterRespond(final Map map, final AjaxRequestTarget.IJavascriptResponse response)
{
//
// set the focus on the first form component that has errors
// this is very convenient for the user as he doesn't have to click on the erroneous field first
//
// this has to be rendered in onAfterRespond to be sure the dom component for setting focus on has
// already been rendered in the dom structure of the browser
//
final FormComponent focus = (FormComponent) visitChildren(FormComponent.class, new IVisitor()
{
public Object component(final Component component)
{
final FormComponent formComponent = (FormComponent) component;
if (formComponent.hasErrorMessage() && formComponent.getOutputMarkupId())
return formComponent;
return CONTINUE_TRAVERSAL;
}
});
if (focus != null)
target.focusComponent(focus);
}
});
return target;
}
another possible example (using common functionality specific to your application this time)
@Override
public AjaxRequestTarget newAjaxRequestTarget()
{
return new CustomAjaxRequestTarget();
}
so inside your pages you could for example do this:
public void onClick(final AjaxRequestTarget target)
{
final CustomAjaxRequestTarget customTarget = (CustomAjaxRequestTarget)target;
// change some setting on the page
// ..
// let the user take notice of the change (the heavily-used effect from Ruby on Rails we probably all know)
customTarget.applyYellowFadeEffect(component);
// make it even more obvious (some freaky javascript :-)
customTarget.letScreenShakeUpAndDown();
// even half-blind people should see that (another crazy js)
customTarget.zoomInAndOutAgain(component);
}
this way you could provide some common ajax functionality to your application which is easy to use and implementation details are perfectly hidden
> enable subclassing of AjaxRequestTarget
> ---------------------------------------
>
> Key: WICKET-1213
> URL: https://issues.apache.org/jira/browse/WICKET-1213
> Project: Wicket
> Issue Type: Wish
> Components: wicket
> Affects Versions: 1.3.0-rc1
> Reporter: Peter Ertl
> Fix For: 1.4.0-alpha
>
> Attachments: AjaxRequestTarget_with_subclassing.patch
>
>
> In my wicket programming life I always had some trouble with the ajax part when wanting stuff like this:
> - "Always update a common feedback panel from my template page"
> --> add 'target.addComponent(feedbackPanel)' just _everywhere_ (very cumbersome and not elegant at all)
> - add a listener using AjaxRequestTarget#addListener
> --> not quite possible without subclassing the request cycle (which is *yuk* if you ask me) to catch the short moment in between AjaxRequestTarget is instantiated and IRequestTarget#onRespond() is called
> - automatically set focus on the first form component with errors
> --> add bulky code into all onError() to check for the proper component and call AjaxRequestTarget#setFocus
> - add some common function like AjaxRequestTarget#yellowFadeEffect(FormComponent)
> --> have some utility method and call it like this: AjaxUtil.yellowFade(target) -- not nice as functionality like this should really belong to the ajax target which represents the ajax request / response.
> I found that all these issues can be solved very elegantly if you could just catch the moment where AjaxRequestTarget is instantiated.
> I attached a very little patch (!) which enables you to
> - subclass
> - add listeners to
> the AjaxRequestTarget
> In AbstractDefaultAjaxBehavior:281
> public final void onRequest()
> {
> AjaxRequestTarget target = new AjaxRequestTarget(getComponent().getPage()); // *******
> RequestCycle.get().setRequestTarget(target);
> respond(target)
> }
> is changed to
> public final void onRequest()
> {
> AjaxRequestTarget target = getComponent().getPage().newAjaxRequestTarget(); // *******
> RequestCycle.get().setRequestTarget(target);
> respond(target);
> }
> org.apache.wicket.Page will have an additional method:
> public AjaxRequestTarget newAjaxRequestTarget()
> {
> return new AjaxRequestTarget(this);
> }
> }
> so by overriding newAjaxRequestTarget in your page you could customize or subclass the ajax response very easily
> also, this will not break current code but is just an enhancement you will not notice unless you need it.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.