Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-06-06 Thread dukejansen

I'm not sure the use case is common or consistent enough.

Too often I have two panels with two separate model objects that are both
backed by the same actual underlying object, so the code I wrote below will
fail anyway.

I actually think using a marker interface on Components might be more
reliable and effective, though less generic.

(Or the more drawn out listener pattern. Or using equals and overriding it
to report whether to models are backed by the same object. Or a marker
interface on your models that can report that etc.)

-Jason


Matej Knopp-2 wrote:
> 
> TBH I don't see this as a very common usecase. And it's not difficult
> to implement on your own (although the code isn't entirely trivial).
> 
> -Matej
> 
> On 6/5/07, Eelco Hillenius <[EMAIL PROTECTED]> wrote:
>> That looks like a lot of work actually. Johan, others, you think we
>> should build in better support for this in Wicket?
>>
>> Eelco
>>
>> On 6/5/07, dukejansen <[EMAIL PROTECTED]> wrote:
>> >  I've gone ahead and implemented this, but instead of using the
>> > Component.saveInnermostModel method, I coded up my own. The
>> implementation
>> > in Component only traverses IWrapModel implementations, not
>> IChainedModel
>> > implementations. My implementation handles both. Note that this will
>> only
>> > find components backed by the exact same IModel instance. Two distinct
>> model
>> > objects wrapping the exact same object will not match. /**
>> >  * Searches the component tree and finds any components backed by the
>> same
>> > model as the model passed in, then
>> >  * adds those components to the given AjaxRequestTarget to be rendered
>> > (after first verifying that they have
>> >  * outputMarkupId set to true).
>> >  *
>> >  * @param root the root MarkupContainer whose descendents will be
>> examined
>> > for matching backing models
>> >  * @param target the AjaxRequestTarget to add all the matching
>> components to
>> >  * @param model the model to match
>> >  */
>> >  public static void
>> > addComponentsBackedBySameModel(MarkupContainer root, final
>> > AjaxRequestTarget target, final IModel model) {
>> >
>> >  // Visit all children, looking for components backed by the same
>> model.
>> >  root.visitChildren(new IVisitor() {
>> >  public Object component(Component component) {
>> >  if (WicketUtils.isSameInnermostModel(component.getModel(),
>> > model)) {
>> >  if (component.getOutputMarkupId()) {
>> >  // Refresh the component.
>> >  target.addComponent(component);
>> >  // No need to go deeper if we're already refreshing the entire
>> component!
>> >  return IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
>> >  }
>> >  }
>> >  return IVisitor.CONTINUE_TRAVERSAL;
>> >  }
>> >  });
>> >
>> >  // TODO: Return the list of components that were re-rendered?
>> >  // See also:
>> >  //
>> >
>> http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html
>> >
>> >  }
>> >
>> >  /**
>> >  * Returns true if the given models ultimately share the same innermost
>> > model;
>> >  * otherwise returns false.
>> >  *
>> >  * @param model1 the first model
>> >  * @param model2 the second model
>> >  * @return true if they share the same innermost model; otherwise
>> >  * false
>> >  */
>> >  public static boolean isSameInnermostModel(IModel model1, IModel
>> model2) {
>> >  // There is a version of this on Component, but it is only aware of
>> > IWrapModel.
>> >  // Our version knows how to traverse chained models as well as warpped
>> > models.
>> >  if (model1 != null && model2 != null) {
>> >  return getInnermostModel(model1) == getInnermostModel(model2);
>> >  } else {
>> >  return false;
>> >  }
>> >  }
>> >
>> >  /**
>> >  * Returns the innermost model within the given model; similar to
>> > Component.getInnermostModel,
>> >  * except that it follows both IWrapModel and IChainingModel, not just
>> the
>> > former.
>> >  *
>> >  * @param model the model
>> >  * @return the innermost model within that model
>> >  */
>> >  public static IModel getInnermostModel(IModel model) {
>> >
>> >  // Pass through nulls.
>> >  if (model == null) {
>> >  return null;
>> >  }
>> >
>> >  // Try to figure out an inner model.
>> >  IModel innerModel = null;
>> >  if (model instanceof IWrapModel) {
>> >  innerModel =
>> > getInnermostModel(((IWrapModel)model).getWrappedModel());
>> >  } else if (model instanceof IChainingModel) {
>> >  innerModel =
>> > getInnermostModel(((IChainingModel)model).getChainedModel());
>> >  }
>> >
>> >  if (innerModel != null) {
>> >  // If we got an inner model, return it.
>> >  return innerModel;
>> >  } else {
>> >  // Otherwise the given model was the innermost, so return it.
>> >  return model;
>> >  }
>> >
>> >  }
>> >
>> >  /**
>> >  * Returns the root ancestor of this component by walking up the parent
>> tree
>> > until a component is found with no parent;
>> >  * note that this could return the same component passed in.
>> >  *
>> >  * @param component the compone

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-06-05 Thread Matej Knopp
TBH I don't see this as a very common usecase. And it's not difficult
to implement on your own (although the code isn't entirely trivial).

-Matej

On 6/5/07, Eelco Hillenius <[EMAIL PROTECTED]> wrote:
> That looks like a lot of work actually. Johan, others, you think we
> should build in better support for this in Wicket?
>
> Eelco
>
> On 6/5/07, dukejansen <[EMAIL PROTECTED]> wrote:
> >  I've gone ahead and implemented this, but instead of using the
> > Component.saveInnermostModel method, I coded up my own. The implementation
> > in Component only traverses IWrapModel implementations, not IChainedModel
> > implementations. My implementation handles both. Note that this will only
> > find components backed by the exact same IModel instance. Two distinct model
> > objects wrapping the exact same object will not match. /**
> >  * Searches the component tree and finds any components backed by the same
> > model as the model passed in, then
> >  * adds those components to the given AjaxRequestTarget to be rendered
> > (after first verifying that they have
> >  * outputMarkupId set to true).
> >  *
> >  * @param root the root MarkupContainer whose descendents will be examined
> > for matching backing models
> >  * @param target the AjaxRequestTarget to add all the matching components to
> >  * @param model the model to match
> >  */
> >  public static void
> > addComponentsBackedBySameModel(MarkupContainer root, final
> > AjaxRequestTarget target, final IModel model) {
> >
> >  // Visit all children, looking for components backed by the same model.
> >  root.visitChildren(new IVisitor() {
> >  public Object component(Component component) {
> >  if (WicketUtils.isSameInnermostModel(component.getModel(),
> > model)) {
> >  if (component.getOutputMarkupId()) {
> >  // Refresh the component.
> >  target.addComponent(component);
> >  // No need to go deeper if we're already refreshing the entire component!
> >  return IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
> >  }
> >  }
> >  return IVisitor.CONTINUE_TRAVERSAL;
> >  }
> >  });
> >
> >  // TODO: Return the list of components that were re-rendered?
> >  // See also:
> >  //
> > http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html
> >
> >  }
> >
> >  /**
> >  * Returns true if the given models ultimately share the same innermost
> > model;
> >  * otherwise returns false.
> >  *
> >  * @param model1 the first model
> >  * @param model2 the second model
> >  * @return true if they share the same innermost model; otherwise
> >  * false
> >  */
> >  public static boolean isSameInnermostModel(IModel model1, IModel model2) {
> >  // There is a version of this on Component, but it is only aware of
> > IWrapModel.
> >  // Our version knows how to traverse chained models as well as warpped
> > models.
> >  if (model1 != null && model2 != null) {
> >  return getInnermostModel(model1) == getInnermostModel(model2);
> >  } else {
> >  return false;
> >  }
> >  }
> >
> >  /**
> >  * Returns the innermost model within the given model; similar to
> > Component.getInnermostModel,
> >  * except that it follows both IWrapModel and IChainingModel, not just the
> > former.
> >  *
> >  * @param model the model
> >  * @return the innermost model within that model
> >  */
> >  public static IModel getInnermostModel(IModel model) {
> >
> >  // Pass through nulls.
> >  if (model == null) {
> >  return null;
> >  }
> >
> >  // Try to figure out an inner model.
> >  IModel innerModel = null;
> >  if (model instanceof IWrapModel) {
> >  innerModel =
> > getInnermostModel(((IWrapModel)model).getWrappedModel());
> >  } else if (model instanceof IChainingModel) {
> >  innerModel =
> > getInnermostModel(((IChainingModel)model).getChainedModel());
> >  }
> >
> >  if (innerModel != null) {
> >  // If we got an inner model, return it.
> >  return innerModel;
> >  } else {
> >  // Otherwise the given model was the innermost, so return it.
> >  return model;
> >  }
> >
> >  }
> >
> >  /**
> >  * Returns the root ancestor of this component by walking up the parent tree
> > until a component is found with no parent;
> >  * note that this could return the same component passed in.
> >  *
> >  * @param component the component whose root ancestor should be returned;
> > must be non-null
> >  * @return the root ancestor
> >  */
> >  public static Component getRootAncestor(Component component) {
> >  ExceptionUtils.throwIfNull(component, "component");
> >  Component cur = component;
> >  while (cur.getParent() != null) {
> >  cur = cur.getParent();
> >  }
> >  return cur;
> >  }
>
> -
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> ___
> Wicket-user mailing list
> Wic

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-06-05 Thread Eelco Hillenius
That looks like a lot of work actually. Johan, others, you think we
should build in better support for this in Wicket?

Eelco

On 6/5/07, dukejansen <[EMAIL PROTECTED]> wrote:
>  I've gone ahead and implemented this, but instead of using the
> Component.saveInnermostModel method, I coded up my own. The implementation
> in Component only traverses IWrapModel implementations, not IChainedModel
> implementations. My implementation handles both. Note that this will only
> find components backed by the exact same IModel instance. Two distinct model
> objects wrapping the exact same object will not match. /**
>  * Searches the component tree and finds any components backed by the same
> model as the model passed in, then
>  * adds those components to the given AjaxRequestTarget to be rendered
> (after first verifying that they have
>  * outputMarkupId set to true).
>  *
>  * @param root the root MarkupContainer whose descendents will be examined
> for matching backing models
>  * @param target the AjaxRequestTarget to add all the matching components to
>  * @param model the model to match
>  */
>  public static void
> addComponentsBackedBySameModel(MarkupContainer root, final
> AjaxRequestTarget target, final IModel model) {
>
>  // Visit all children, looking for components backed by the same model.
>  root.visitChildren(new IVisitor() {
>  public Object component(Component component) {
>  if (WicketUtils.isSameInnermostModel(component.getModel(),
> model)) {
>  if (component.getOutputMarkupId()) {
>  // Refresh the component.
>  target.addComponent(component);
>  // No need to go deeper if we're already refreshing the entire component!
>  return IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
>  }
>  }
>  return IVisitor.CONTINUE_TRAVERSAL;
>  }
>  });
>
>  // TODO: Return the list of components that were re-rendered?
>  // See also:
>  //
> http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html
>
>  }
>
>  /**
>  * Returns true if the given models ultimately share the same innermost
> model;
>  * otherwise returns false.
>  *
>  * @param model1 the first model
>  * @param model2 the second model
>  * @return true if they share the same innermost model; otherwise
>  * false
>  */
>  public static boolean isSameInnermostModel(IModel model1, IModel model2) {
>  // There is a version of this on Component, but it is only aware of
> IWrapModel.
>  // Our version knows how to traverse chained models as well as warpped
> models.
>  if (model1 != null && model2 != null) {
>  return getInnermostModel(model1) == getInnermostModel(model2);
>  } else {
>  return false;
>  }
>  }
>
>  /**
>  * Returns the innermost model within the given model; similar to
> Component.getInnermostModel,
>  * except that it follows both IWrapModel and IChainingModel, not just the
> former.
>  *
>  * @param model the model
>  * @return the innermost model within that model
>  */
>  public static IModel getInnermostModel(IModel model) {
>
>  // Pass through nulls.
>  if (model == null) {
>  return null;
>  }
>
>  // Try to figure out an inner model.
>  IModel innerModel = null;
>  if (model instanceof IWrapModel) {
>  innerModel =
> getInnermostModel(((IWrapModel)model).getWrappedModel());
>  } else if (model instanceof IChainingModel) {
>  innerModel =
> getInnermostModel(((IChainingModel)model).getChainedModel());
>  }
>
>  if (innerModel != null) {
>  // If we got an inner model, return it.
>  return innerModel;
>  } else {
>  // Otherwise the given model was the innermost, so return it.
>  return model;
>  }
>
>  }
>
>  /**
>  * Returns the root ancestor of this component by walking up the parent tree
> until a component is found with no parent;
>  * note that this could return the same component passed in.
>  *
>  * @param component the component whose root ancestor should be returned;
> must be non-null
>  * @return the root ancestor
>  */
>  public static Component getRootAncestor(Component component) {
>  ExceptionUtils.throwIfNull(component, "component");
>  Component cur = component;
>  while (cur.getParent() != null) {
>  cur = cur.getParent();
>  }
>  return cur;
>  }

-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user


Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-06-05 Thread dukejansen

I've gone ahead and implemented this, but instead of using the
Component.saveInnermostModel method, I coded up my own. The implementation
in Component only traverses IWrapModel implementations, not IChainedModel
implementations. My implementation handles both. Note that this will only
find components backed by the exact same IModel instance. Two distinct model
objects wrapping the exact same object will not match.


/**
 * Searches the component tree and finds any components backed by the
same model as the model passed in, then
 * adds those components to the given AjaxRequestTarget to be rendered
(after first verifying that they have
 * outputMarkupId set to true).
 * 
 * @param root the root MarkupContainer whose descendents will be
examined for matching backing models 
 * @param target the AjaxRequestTarget to add all the matching
components to
 * @param model the model to match
 */
public static void addComponentsBackedBySameModel(MarkupContainer root,
final AjaxRequestTarget target, final IModel model) {

// Visit all children, looking for components backed by the same
model.
root.visitChildren(new IVisitor() {
public Object component(Component component) {
if (WicketUtils.isSameInnermostModel(component.getModel(),
model)) {
if (component.getOutputMarkupId()) {
// Refresh the component.
target.addComponent(component);
// No need to go deeper if we're already refreshing
the entire component! 
return
IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
}
}
return IVisitor.CONTINUE_TRAVERSAL;
}
});

// TODO: Return the list of components that were re-rendered?
// See also:
//  
http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html

}

/**
 * Returns true if the given models ultimately share the same innermost
model;
 * otherwise returns false.
 * 
 * @param model1 the first model
 * @param model2 the second model
 * @return true if they share the same innermost model; otherwise
 * false
 */
public static boolean isSameInnermostModel(IModel model1, IModel model2)
{
// There is a version of this on Component, but it is only aware of
IWrapModel.
// Our version knows how to traverse chained models as well as
warpped models.
if (model1 != null && model2 != null) {
return getInnermostModel(model1) == getInnermostModel(model2);
} else {
return false;
}
}

/**
 * Returns the innermost model within the given model; similar to
Component.getInnermostModel,
 * except that it follows both IWrapModel and IChainingModel, not just
the former.
 * 
 * @param model the model
 * @return the innermost model within that model
 */
public static IModel getInnermostModel(IModel model) {

// Pass through nulls.
if (model == null) {
return null;
}

// Try to figure out an inner model.
IModel innerModel = null; 
if (model instanceof IWrapModel) {
innerModel =
getInnermostModel(((IWrapModel)model).getWrappedModel());
} else if (model instanceof IChainingModel) {
innerModel =
getInnermostModel(((IChainingModel)model).getChainedModel());
}

if (innerModel != null) {
// If we got an inner model, return it.
return innerModel;
} else {
// Otherwise the given model was the innermost, so return it.
return model;
}

}

/**
 * Returns the root ancestor of this component by walking up the parent
tree until a component is found with no parent;
 * note that this could return the same component passed in.
 * 
 * @param component the component whose root ancestor should be
returned; must be non-null
 * @return the root ancestor
 */
public static Component getRootAncestor(Component component) {
ExceptionUtils.throwIfNull(component, "component");
Component cur = component;
while (cur.getParent() != null) {
cur = cur.getParent();
}
return cur;
}





Jonathan Locke wrote:
> 
> 
> It shouldn't be hard to write the method you're talking about.  To find
> all the components using the same model as a given component, just walk
> the component hierarchy using visitChildren() and add any component which
> returns true for sameInnermostModel(component).
> 
> There is a more general case of this problem though where one area of a
> web page may need to be updated because some completely unrelated area
> changed.  This I'm handling by hand right now, but I was asking a day or
> two ago if th

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-31 Thread ChuckDeal


Mats Norén-2 wrote:
> 
> It would be great of you had some code to share, it makes it easier to
> follow... :)
> 

Yeah, no kidding.. :)

Here is a quickstart (minus the lib folder, see below for list of jars) that
should illustrate what I am trying to accomplish, yes it's pretty stupid,
but hopefully covers some of the normal usage scenarios...

http://www.nabble.com/file/p10895313/quickstart-listener.zip
quickstart-listener.zip 

One problem that I know that it suffers from is that Components that should
act as "event source's" can't be named _easily_ within a repeater.  You'll
have to use an actual Component reference (instead of the name) in those
cases.

Chuck


Here is the contents of my lib folder, this should be standard for a
quickstart...
commons-collections-3.2.jar
commons-logging-1.0.4.jar
jetty-6.1.1.jar
jetty-management-6.1.1.jar
jetty-util-6.1.1.jar
log4j-1.2.13.jar
mx4j-3.0.1.jar
mx4j-tools-3.0.1.jar
servlet-api-2.5-6.1.1.jar
slf4j-api-1.3.1.jar
slf4j-log4j12-1.3.1.jar
wicket-1.3.0-incubating-SNAPSHOT.jar  (latest version)
wicket-extensions-1.3.0-incubating-SNAPSHOT.jar  (latest version)



Mats Norén-2 wrote:
> 
> On 5/31/07, ChuckDeal <[EMAIL PROTECTED]> wrote:
>>
>> I had the same (at least it sounds similar) problem.  My pages use a
>> role-based authorization strategy.  Sometimes the role is based upon the
>> data on the page.  A good example of this is Responsible Individual (RI);
>> if you are not an RI, you have read-only access, but as soon as you are
>> added to the RI List, you get read-write access to certain fields (maybe
>> not
>> all fields).  In an effort to avoid page flashing, we use AJAX to refresh
>> the components whose access are based upon the RI field.
>>
>> At first the solution was specific to this scenario, then I realized that
>> I
>> could have any number of fields on the page that worked in concert with
>> each
>> other to either RENDER or ENABLE other fields based upon roles.  In the
>> end,
>> I created an abstract methodology based on the concept of of Listeners. 
>> So,
>> a field registers itself with another component as a listener, then the
>> source component has the responsibility of telling the target components
>> what to do and when to do it (in this case, repaint targets when source
>> is
>> updated).
>>
>> The rough idea:  I use the Component MetaData on the source to store a
>> List
>> of target Component references.  The whole design is based upon
>> MetaDataRoleAuthorizationStrategy.  Now, I know what you're thinking: 
>> What
>> about the case where the source component hasn't been instantiated yet,
>> but
>> I want to register a target against it?  Well, I use the Page (actually
>> an
>> object on the Page) and a custom Panel (that all other panels extend
>> from)
>> as mediators.  A Component can actually register with another Component
>> via
>> an actual reference to the source Component or by "name".  In the latter
>> case, the source Component would have to register themselves with the
>> Page/Panel in a Component registry.  This helped with the problem of
>> fragility because I didn't need to know the full path to a Component from
>> the targets position which meant I could change the hierarchy without
>> having
>> to go back and adjust all these register() methods.  That covers the
>> basics
>> of building the web of source/targets.
>>
>> Using the knowledge is up to the developer.  For my immediate needs,
>> whenever I repaint the source (which is usually due to an AJAX update of
>> the
>> model), I repaint anyone registered to me.  I even created behaviors that
>> extend AjaxFormComponentUpdatingBehavior to help make this even more
>> transparent.
>>
>> I just reread this post and it seems a little abstract.  If anyone is
>> actually interested in this, I will do my best to elaborate.  I also
>> welcome
>> criticism of this approach because I would hate to get into full
>> production
>> mode and find some stupid loophole that takes me "back to the drawing
>> board".
>>
>> Chuck
>>
>>
>> James McLaughlin-3 wrote:
>> >
>> > +1. It can be tedious sometimes  figuring out  how to update
>> > components that are on the other side of the tree from the onClick.
>> >
>> > best,
>> > jim
>> >
>> > On 5/30/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
>> >>
>> >>
>> >> Maybe another way to auto-ajax-update a component would be to have it
>> do
>> >> that whenever its model changes.  There are a lot of caveats with
>> model
>> >> change notifications, but that seems to be a pretty clean idea if the
>> >> rules
>> >> for model changes were respected.  Might make a good RFE for next
>> Wicket
>> >> version.
>> >>
>> >>
>> >> Jonathan Locke wrote:
>> >> >
>> >> >
>> >> > It shouldn't be hard to write the method you're talking about.  To
>> find
>> >> > all the components using the same model as a given component, just
>> walk
>> >> > the component hierarchy using visitChildren() and add any component
>> >> which
>> >> > returns true for sameInner

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-31 Thread Mats Norén
It would be great of you had some code to share, it makes it easier to
follow... :)

/Mats

On 5/31/07, ChuckDeal <[EMAIL PROTECTED]> wrote:
>
> I had the same (at least it sounds similar) problem.  My pages use a
> role-based authorization strategy.  Sometimes the role is based upon the
> data on the page.  A good example of this is Responsible Individual (RI);
> if you are not an RI, you have read-only access, but as soon as you are
> added to the RI List, you get read-write access to certain fields (maybe not
> all fields).  In an effort to avoid page flashing, we use AJAX to refresh
> the components whose access are based upon the RI field.
>
> At first the solution was specific to this scenario, then I realized that I
> could have any number of fields on the page that worked in concert with each
> other to either RENDER or ENABLE other fields based upon roles.  In the end,
> I created an abstract methodology based on the concept of of Listeners.  So,
> a field registers itself with another component as a listener, then the
> source component has the responsibility of telling the target components
> what to do and when to do it (in this case, repaint targets when source is
> updated).
>
> The rough idea:  I use the Component MetaData on the source to store a List
> of target Component references.  The whole design is based upon
> MetaDataRoleAuthorizationStrategy.  Now, I know what you're thinking:  What
> about the case where the source component hasn't been instantiated yet, but
> I want to register a target against it?  Well, I use the Page (actually an
> object on the Page) and a custom Panel (that all other panels extend from)
> as mediators.  A Component can actually register with another Component via
> an actual reference to the source Component or by "name".  In the latter
> case, the source Component would have to register themselves with the
> Page/Panel in a Component registry.  This helped with the problem of
> fragility because I didn't need to know the full path to a Component from
> the targets position which meant I could change the hierarchy without having
> to go back and adjust all these register() methods.  That covers the basics
> of building the web of source/targets.
>
> Using the knowledge is up to the developer.  For my immediate needs,
> whenever I repaint the source (which is usually due to an AJAX update of the
> model), I repaint anyone registered to me.  I even created behaviors that
> extend AjaxFormComponentUpdatingBehavior to help make this even more
> transparent.
>
> I just reread this post and it seems a little abstract.  If anyone is
> actually interested in this, I will do my best to elaborate.  I also welcome
> criticism of this approach because I would hate to get into full production
> mode and find some stupid loophole that takes me "back to the drawing
> board".
>
> Chuck
>
>
> James McLaughlin-3 wrote:
> >
> > +1. It can be tedious sometimes  figuring out  how to update
> > components that are on the other side of the tree from the onClick.
> >
> > best,
> > jim
> >
> > On 5/30/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
> >>
> >>
> >> Maybe another way to auto-ajax-update a component would be to have it do
> >> that whenever its model changes.  There are a lot of caveats with model
> >> change notifications, but that seems to be a pretty clean idea if the
> >> rules
> >> for model changes were respected.  Might make a good RFE for next Wicket
> >> version.
> >>
> >>
> >> Jonathan Locke wrote:
> >> >
> >> >
> >> > It shouldn't be hard to write the method you're talking about.  To find
> >> > all the components using the same model as a given component, just walk
> >> > the component hierarchy using visitChildren() and add any component
> >> which
> >> > returns true for sameInnermostModel(component).
> >> >
> >> > There is a more general case of this problem though where one area of a
> >> > web page may need to be updated because some completely unrelated area
> >> > changed.  This I'm handling by hand right now, but I was asking a day
> >> or
> >> > two ago if there was a way to add a component to every ajax request
> >> (Eelco
> >> > answered that you can do this by implementing a request processor, I
> >> > think).  It seems to be pretty common in an AJAX request to want a
> >> global
> >> > feedback component to update.  Maybe we could have a poor-man's version
> >> of
> >> > this where if you override some boolean method, your component will get
> >> > auto-ajax-updated on every AJAX request. For many problems, this would
> >> be
> >> > convenient because it's easier to just update the thing every time than
> >> to
> >> > think about all the places it might need to be updated.
> >> >
> >> >
> >> > dukejansen wrote:
> >> >>
> >> >> I have some state which backs two panels, Panel A and Panel B, that
> >> may
> >> >> be included as part of other panels. Ultimately they are both on the
> >> same
> >> >> page, and their backing state is shared via the mod

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-31 Thread ChuckDeal

I had the same (at least it sounds similar) problem.  My pages use a
role-based authorization strategy.  Sometimes the role is based upon the
data on the page.  A good example of this is Responsible Individual (RI); 
if you are not an RI, you have read-only access, but as soon as you are
added to the RI List, you get read-write access to certain fields (maybe not
all fields).  In an effort to avoid page flashing, we use AJAX to refresh
the components whose access are based upon the RI field.  

At first the solution was specific to this scenario, then I realized that I
could have any number of fields on the page that worked in concert with each
other to either RENDER or ENABLE other fields based upon roles.  In the end,
I created an abstract methodology based on the concept of of Listeners.  So,
a field registers itself with another component as a listener, then the
source component has the responsibility of telling the target components
what to do and when to do it (in this case, repaint targets when source is
updated).

The rough idea:  I use the Component MetaData on the source to store a List
of target Component references.  The whole design is based upon
MetaDataRoleAuthorizationStrategy.  Now, I know what you're thinking:  What
about the case where the source component hasn't been instantiated yet, but
I want to register a target against it?  Well, I use the Page (actually an
object on the Page) and a custom Panel (that all other panels extend from)
as mediators.  A Component can actually register with another Component via
an actual reference to the source Component or by "name".  In the latter
case, the source Component would have to register themselves with the
Page/Panel in a Component registry.  This helped with the problem of
fragility because I didn't need to know the full path to a Component from
the targets position which meant I could change the hierarchy without having
to go back and adjust all these register() methods.  That covers the basics
of building the web of source/targets.

Using the knowledge is up to the developer.  For my immediate needs,
whenever I repaint the source (which is usually due to an AJAX update of the
model), I repaint anyone registered to me.  I even created behaviors that
extend AjaxFormComponentUpdatingBehavior to help make this even more
transparent.

I just reread this post and it seems a little abstract.  If anyone is
actually interested in this, I will do my best to elaborate.  I also welcome
criticism of this approach because I would hate to get into full production
mode and find some stupid loophole that takes me "back to the drawing
board".

Chuck


James McLaughlin-3 wrote:
> 
> +1. It can be tedious sometimes  figuring out  how to update
> components that are on the other side of the tree from the onClick.
> 
> best,
> jim
> 
> On 5/30/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
>>
>>
>> Maybe another way to auto-ajax-update a component would be to have it do
>> that whenever its model changes.  There are a lot of caveats with model
>> change notifications, but that seems to be a pretty clean idea if the
>> rules
>> for model changes were respected.  Might make a good RFE for next Wicket
>> version.
>>
>>
>> Jonathan Locke wrote:
>> >
>> >
>> > It shouldn't be hard to write the method you're talking about.  To find
>> > all the components using the same model as a given component, just walk
>> > the component hierarchy using visitChildren() and add any component
>> which
>> > returns true for sameInnermostModel(component).
>> >
>> > There is a more general case of this problem though where one area of a
>> > web page may need to be updated because some completely unrelated area
>> > changed.  This I'm handling by hand right now, but I was asking a day
>> or
>> > two ago if there was a way to add a component to every ajax request
>> (Eelco
>> > answered that you can do this by implementing a request processor, I
>> > think).  It seems to be pretty common in an AJAX request to want a
>> global
>> > feedback component to update.  Maybe we could have a poor-man's version
>> of
>> > this where if you override some boolean method, your component will get
>> > auto-ajax-updated on every AJAX request. For many problems, this would
>> be
>> > convenient because it's easier to just update the thing every time than
>> to
>> > think about all the places it might need to be updated.
>> >
>> >
>> > dukejansen wrote:
>> >>
>> >> I have some state which backs two panels, Panel A and Panel B, that
>> may
>> >> be included as part of other panels. Ultimately they are both on the
>> same
>> >> page, and their backing state is shared via the model class that backs
>> >> both of them. Panel A has an Ajax event handler which modifies the
>> >> backing model state, after which I want to force Panel A and Panel B
>> to
>> >> repaint.
>> >>
>> >> I've dealt with this in a few different ways so far, and they all
>> bother
>> >> me:
>> >>
>> >> 1. Walk up the containership tre

Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-30 Thread James McLaughlin
+1. It can be tedious sometimes  figuring out  how to update
components that are on the other side of the tree from the onClick.

best,
jim

On 5/30/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
>
>
> Maybe another way to auto-ajax-update a component would be to have it do
> that whenever its model changes.  There are a lot of caveats with model
> change notifications, but that seems to be a pretty clean idea if the rules
> for model changes were respected.  Might make a good RFE for next Wicket
> version.
>
>
> Jonathan Locke wrote:
> >
> >
> > It shouldn't be hard to write the method you're talking about.  To find
> > all the components using the same model as a given component, just walk
> > the component hierarchy using visitChildren() and add any component which
> > returns true for sameInnermostModel(component).
> >
> > There is a more general case of this problem though where one area of a
> > web page may need to be updated because some completely unrelated area
> > changed.  This I'm handling by hand right now, but I was asking a day or
> > two ago if there was a way to add a component to every ajax request (Eelco
> > answered that you can do this by implementing a request processor, I
> > think).  It seems to be pretty common in an AJAX request to want a global
> > feedback component to update.  Maybe we could have a poor-man's version of
> > this where if you override some boolean method, your component will get
> > auto-ajax-updated on every AJAX request. For many problems, this would be
> > convenient because it's easier to just update the thing every time than to
> > think about all the places it might need to be updated.
> >
> >
> > dukejansen wrote:
> >>
> >> I have some state which backs two panels, Panel A and Panel B, that may
> >> be included as part of other panels. Ultimately they are both on the same
> >> page, and their backing state is shared via the model class that backs
> >> both of them. Panel A has an Ajax event handler which modifies the
> >> backing model state, after which I want to force Panel A and Panel B to
> >> repaint.
> >>
> >> I've dealt with this in a few different ways so far, and they all bother
> >> me:
> >>
> >> 1. Walk up the containership tree and back down again until I find the
> >> panel with a known ID or which implements a specific marker interface,
> >> finding it that way. (Or do a full DFS of the tree to be thorough.)
> >>
> >> 2. Assume how my Panel is included and how the other Panel are included,
> >> and explicitly walk up and back down the containership tree. This is
> >> fragile because if I decide to rework panel containership, the method
> >> could fail.
> >>
> >> Is there some better way of doing this that I'm missing? A best practice
> >> for reaching out to siblings and cousins?
> >>
> >> Or something more fundamental to trigger refreshes of all componets
> >> backed by that model? Seems like a common use case. A component updates
> >> some state as part of ajax event, then wants to use ajax to repaint any
> >> other components backed by that state.
> >>
> >> Interested to hear how others have solved this problem.
> >>
> >> -Jason
> >>
> >
> >
>
> --
> View this message in context: 
> http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html#a10883894
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> -
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> ___
> Wicket-user mailing list
> Wicket-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/wicket-user
>

-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user


Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-30 Thread Jonathan Locke


Maybe another way to auto-ajax-update a component would be to have it do
that whenever its model changes.  There are a lot of caveats with model
change notifications, but that seems to be a pretty clean idea if the rules
for model changes were respected.  Might make a good RFE for next Wicket
version.


Jonathan Locke wrote:
> 
> 
> It shouldn't be hard to write the method you're talking about.  To find
> all the components using the same model as a given component, just walk
> the component hierarchy using visitChildren() and add any component which
> returns true for sameInnermostModel(component).
> 
> There is a more general case of this problem though where one area of a
> web page may need to be updated because some completely unrelated area
> changed.  This I'm handling by hand right now, but I was asking a day or
> two ago if there was a way to add a component to every ajax request (Eelco
> answered that you can do this by implementing a request processor, I
> think).  It seems to be pretty common in an AJAX request to want a global
> feedback component to update.  Maybe we could have a poor-man's version of
> this where if you override some boolean method, your component will get
> auto-ajax-updated on every AJAX request. For many problems, this would be
> convenient because it's easier to just update the thing every time than to
> think about all the places it might need to be updated.
> 
> 
> dukejansen wrote:
>> 
>> I have some state which backs two panels, Panel A and Panel B, that may
>> be included as part of other panels. Ultimately they are both on the same
>> page, and their backing state is shared via the model class that backs
>> both of them. Panel A has an Ajax event handler which modifies the
>> backing model state, after which I want to force Panel A and Panel B to
>> repaint.
>> 
>> I've dealt with this in a few different ways so far, and they all bother
>> me:
>> 
>> 1. Walk up the containership tree and back down again until I find the
>> panel with a known ID or which implements a specific marker interface,
>> finding it that way. (Or do a full DFS of the tree to be thorough.)
>> 
>> 2. Assume how my Panel is included and how the other Panel are included,
>> and explicitly walk up and back down the containership tree. This is
>> fragile because if I decide to rework panel containership, the method
>> could fail.
>> 
>> Is there some better way of doing this that I'm missing? A best practice
>> for reaching out to siblings and cousins?
>> 
>> Or something more fundamental to trigger refreshes of all componets
>> backed by that model? Seems like a common use case. A component updates
>> some state as part of ajax event, then wants to use ajax to repaint any
>> other components backed by that state.
>> 
>> Interested to hear how others have solved this problem.
>> 
>> -Jason
>> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html#a10883894
Sent from the Wicket - User mailing list archive at Nabble.com.


-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user


Re: [Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-30 Thread Jonathan Locke


It shouldn't be hard to write the method you're talking about.  To find all
the components using the same model as a given component, just walk the
component hierarchy using visitChildren() and add any component which
returns true for sameInnermostModel(component).

There is a more general case of this problem though where one area of a web
page may need to be updated because some completely unrelated area changed. 
This I'm handling by hand right now, but I was asking a day or two ago if
there was a way to add a component to every ajax request (Eelco answered
that you can do this by implementing a request processor, I think).  It
seems to be pretty common in an AJAX request to want a global feedback
component to update.  Maybe we could have a poor-man's version of this where
if you override some boolean method, your component will get
auto-ajax-updated on every AJAX request. For many problems, this would be
convenient because it's easier to just update the thing every time than to
think about all the places it might need to be updated.


dukejansen wrote:
> 
> I have some state which backs two panels, Panel A and Panel B, that may be
> included as part of other panels. Ultimately they are both on the same
> page, and their backing state is shared via the model class that backs
> both of them. Panel A has an Ajax event handler which modifies the backing
> model state, after which I want to force Panel A and Panel B to repaint.
> 
> I've dealt with this in a few different ways so far, and they all bother
> me:
> 
> 1. Walk up the containership tree and back down again until I find the
> panel with a known ID or which implements a specific marker interface,
> finding it that way. (Or do a full DFS of the tree to be thorough.)
> 
> 2. Assume how my Panel is included and how the other Panel are included,
> and explicitly walk up and back down the containership tree. This is
> fragile because if I decide to rework panel containership, the method
> could fail.
> 
> Is there some better way of doing this that I'm missing? A best practice
> for reaching out to siblings and cousins?
> 
> Or something more fundamental to trigger refreshes of all componets backed
> by that model? Seems like a common use case. A component updates some
> state as part of ajax event, then wants to use ajax to repaint any other
> components backed by that state.
> 
> Interested to hear how others have solved this problem.
> 
> -Jason
> 

-- 
View this message in context: 
http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html#a10883859
Sent from the Wicket - User mailing list archive at Nabble.com.


-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user


[Wicket-user] Best Practices for accessing/repainting sibling/cousin components?

2007-05-30 Thread dukejansen

I have some state which backs two panels, Panel A and Panel B, that may be
included as part of other panels. Ultimately they are both on the same page,
and their backing state is shared via the model class that backs both of
them. Panel A has an Ajax event handler which modifies the backing model
state, after which I want to force Panel A and Panel B to repaint.

I've dealt with this in a few different ways so far, and they all bother me:

1. Walk up the containership tree and back down again until I find the panel
with a known ID or which implements a specific marker interface, finding it
that way. (Or do a full DFS of the tree to be thorough.)

2. Assume how my Panel is included and how the other Panel are included, and
explicitly walk up and back down the containership tree. This is fragile
because if I decide to rework panel containership, the method could fail.

Is there some better way of doing this that I'm missing? A best practice for
reaching out to siblings and cousins?

Or something more fundamental to trigger refreshes of all componets backed
by that model? Seems like a common use case. A component updates some state
as part of ajax event, then wants to use ajax to repaint any other
components backed by that state.

Interested to hear how others have solved this problem.

-Jason
-- 
View this message in context: 
http://www.nabble.com/Best-Practices-for-accessing-repainting-sibling-cousin-components--tf3841514.html#a10877622
Sent from the Wicket - User mailing list archive at Nabble.com.


-
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
___
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user