Wow! That was a bit too easy!

Here's how to override onInitialize to dynamically add components to a
page that are specified in the markup:

        protected void onInitialize()
        {
                super.onInitialize();

                IMarkupFragment markupElements = getMarkup();

                for (MarkupElement markupElement: markupElements)
                {
                        if ( markupElement instanceof ComponentTag )
                        {
                                ComponentTag tag =
(ComponentTag)markupElement;
                                String tagId = tag.getId();
                                System.out.println("Markup Element: " +
tag.getName() + " ID: " + tagId);

                                if ( tagId != null )
                                {
                                        if (
tagId.equals("systemPanel"))
                                        {
                                                add(new
SystemPanel("systemPanel"));
                                        }
                                }
                        }
                }
        }

In this example "systemPanel" represents the ID of a single component
that should be added dynamically in onInitialize if it is discovered in
the markup.

It could be easily enhanced to support multiple dynamic components by
providing a set of IDs that represent components that should be
dynamically added and then add them when they are discovered during
onInitialize.

This could easily be applied to an application's Panel base class to
work inside Panels in addition to pages.


My only concern was that we're adding another iteration process to the
page construction cycle - iterating through all MarkupElements of the
markup of a component each time it's onInitialize is called but I guess
it's not that much of an issue. I was hoping to 'piggy back' the
processing onto some other process that is already iterating the markup
elements but I haven't found a suitable spot for that yet.


>-----Original Message-----
>From: Igor Vaynberg [mailto:igor.vaynb...@gmail.com]
>Sent: Saturday, 24 November 2012 12:33 PM
>To: users@wicket.apache.org
>Subject: Re: Ideas on implementing dynamic addition of components that
use
>AJAX?
>
>On Thu, Nov 22, 2012 at 11:46 PM, Martin Grigorov
<mgrigo...@apache.org>
>wrote:
>> Hi,
>>
>>
>> On Fri, Nov 23, 2012 at 9:33 AM, Chris Colman
>> <chr...@stepaheadsoftware.com>wrote:
>>
>>> >starting with wicket 1.5, however, components are able to resole
their
>>> >markup earlier in their lifecycle. the reason auto resolved
components
>>> >are added so late and treated specially was because the markup was
>>> >only available during render.  if you are using 1.5 or 6 you can
build
>>> >your own mechanism. something that kicks off a page/panel's
>>> >oninitialize(), gets the markup, walks it, and adds any components
-
>>>
>>> Would it be walking the markup as raw XHTML or will parsed element
>>> objects be available at this point?
>>>
>>
>> You have to use #getMarkup() or #getAssociatedMarkup(), so the result
is
>> already parsed (IMarkupFragment).
>>
>>
>>>
>>> If it walks the markup will Wicket also be walking it at some time
later
>>> as well, kind of duplicating the markup walking process?
>>>
>>
>> Wicket walks the markup of the whole page for every render of the
page.
>> In Ajax requests only the markup of the repainted components is
>traversed.
>>
>>
>>>
>>> >maybe ones you mark by special tags in your own namespace. the
problem
>>> >here is that even if you can find these components you may still
not
>>> >be able to put them into the right parent because in onInitialize()
>>> >the parent may not yet be added to the container. so perhaps you
>>>
>>
>> I think this is not correct. In #onInitialize() you have access to
the
>> markup of the current component and access to the Page instance, i.e.
you
>> have access to all parents between the current component and the Page
>> instance.
>
>it is correct. i am not talking about the component on which
>onInitialize() is being called... suppose you have a page that
>implements the mechanism and your markup is like this:
>
><body><div wicket:id="foo"><wicket:something/></div>
>
>what i meant is that inside the page's onInitialize() the component
>"foo" may not have yet been added so the wicket:something component
>cannot be properly put into it....
>
>in this case the page's subclass' onInitialize() may add "foo" or
>onConfigure() can add "foo" or some other component if the hierarchy
>is deeper.
>
>-igor
>
>>
>>
>>> >should have some mechanism that kicks off when
page#onComponentAdded()
>>> >is called. you can pull the newly added component's markup, see if
it
>>> >has any of these special components defined as a child of the
>>> >components markup, and add them right there. since you are doing
this
>>> >early on these components will have normal lifecycle and should
work
>>> >just like any other component.
>>> >
>>> >hope this helps you get started. keep us in the loop.
>>>
>>> Sounds so crazy that it just might work ;)
>>>
>>> >
>>> >-igor
>>> >
>>> >
>>> >On Thu, Nov 22, 2012 at 4:54 PM, Chris Colman
>>> ><chr...@stepaheadsoftware.com> wrote:
>>> >> We've been using Wicket since version 1.3 and have been using the
>>> >> IComponentResolver interface with great effect to allow the web
>>> >> designers to effectively 'plug and play' with the Wicket
components.
>>> >>
>>> >> We have multiple layouts using Wicket's 'variation' feature. Each
>>> >> designer can build up a different collection of components in any
>>> >> particular variation as they like - all without changing the Java
>>> code.
>>> >>
>>> >> Normally, without using IComponentResolver, the Java code to
support
>>> >> such flexibility would be mind boggingly complex and ugly but
with an
>>> >> IComponentResolver we simply have code that's capable of
>>> instantiating
>>> >> any component anywhere - and it works and the resulting code is
>>> >> extremely elegant.
>>> >>
>>> >> While we use lots of AJAX it is restricted to components that are
>>> >> explicitly added to components i.e. not added dynamically via the
>>> >> component resolver because such components are not able to
contribute
>>> >> anything to the <head> section.
>>> >>
>>> >> This is starting to become a bit of a problem as we want some of
the
>>> >> more advanced components (with AJAX) to take part in the 'plug
and
>>> play'
>>> >> flexibility. We also are starting to get into using Twitter
Bootstrap
>>> >> with Wicket and much of the 'funkiness' in some of those
components
>>> >> comes from JS that needs to be injected into the header.
>>> >>
>>> >> Is anyone else using this 'plug and play' capability of Wicket
made
>>> >> available via the IComponentResolver interface or is everyone
>>> sticking
>>> >> to the rigid 1 to 1 relationship between markup and the
corresponding
>>> >> statically coded Java component hierarchy? (which we found quite
>>> >> constricting after a few weeks =] )
>>> >>
>>> >> I understand that there are some workarounds suggested for
empowering
>>> >> AJAX in dynamically added components but they seem to involve
>>> manually
>>> >> parsing markup in the onInitialize method and then explicitly
adding
>>> any
>>> >> required components there - it sounds non ideal and would result
in
>>> an
>>> >> extra parse of all page and panel markups I would think - which
may
>>> >> affect performance. Would we be parsing raw XHTML at that stage
or
>>> would
>>> >> a preparsed DOM be available to search through?
>>> >>
>>> >> What is the fundamental issue with the Wicket architecture that
>>> prevents
>>> >> dynamically resolved components from contributing to the header?
>>> >>
>>> >> Is one of the causes the fact that by the time the
ComponentResolver
>>> is
>>> >> being called the header has already been rendered to the response
>>> stream
>>> >> and so once body rendering commences no more header injection is
>>> >> possible?
>>> >>
>>> >> If so, that could probably (thinking out aloud without an in
depth
>>> >> knowledge of Wicket's internals =] ) be solved by splitting the
>>> >> rendering into two streams: header injection goes to current
output
>>> >> stream while body rendering goes to a temporary 'body' stream.
When
>>> the
>>> >> page render is complete the output of the body is then appended
to
>>> the
>>> >> current stream, after the header rendering. This would allow
header
>>> >> injection to continue during processing of the body markup
because
>>> both
>>> >> are not being sequentially output to the same stream.
>>> >>
>>> >> There was mention of another issue - something about auto added
>>> >> (component resolver) objects being removed after rendering so
they
>>> are
>>> >> not there when AJAX actions occur. I don't fully understand the
>>> details
>>> >> of this or why it is necessary. Maybe this devs could offer more
>>> advice
>>> >> on this.
>>> >
>>>
>---------------------------------------------------------------------
>>> >To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>> >For additional commands, e-mail: users-h...@wicket.apache.org
>>>
>>>
>>>
---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>
>>>
>>
>>
>> --
>> Martin Grigorov
>> jWeekend
>> Training, Consulting, Development
>> http://jWeekend.com <http://jweekend.com/>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>For additional commands, e-mail: users-h...@wicket.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to