Okay, I took a look at the the ws-crud project and I think the main difference is that ws-crud works on a flat list of properties, so you can use a listview to add panels that are appropriate for the type of property you want to crud (TextEditor etc), whereas what we want to do is deeply nested (see Wouter's example).

We'd need to parse up to

<div>
 <p>some silly info here</p>

Insert that using a Label or a Panel containing a Label or something. Then insert a TextField (or a Panel containing..) for

 <somenamespace:interaction type="a" >[custom stuff for this
namespace]</somenamespace:interaction>


Then keep on parsing:

 <p>even more info here, and a nested element:


This might all be possible but has a few drawbacks:
1. We're inserting Labels with ill-formed xhtml. It will become well formed again when the parsing and inserting is done but it feels very dirty (in a bad way). 2. Parsing and examining the x(ht)ml in java code is hard, especially the somenamespace:interaction elements. Using xslt to transform to meaningful xhtml is *much* easier.

The proof-of-concepts we have done with our method have proven successful so far, but we like to do things 'the wicket way'. That is; if there is a solution within the framework, use that.

Igor Vaynberg wrote:
see wicketstuff-crud project in wicket-stuff svn. that should give you all
the good ideas.

-igor


On 9/25/07, Wouter Huijnink <[EMAIL PROTECTED]> wrote:
Hi list,

I've seen some threads on dynamically adding components to a form, but
those mainly concern a dynamic *number* of components of the same type.
Our use case concerns adding dynamically typed components to a form. The
idea is as follows:

We have XML consisting of XHTML elements and optional nested  xml
elements from another namespace - something like:

<div>
  <p>some silly info here</p>
  <somenamespace:interaction type="a" >[custom stuff for this
namespace]</somenamespace:interaction>
  <p>even more info here, and a nested element:
    <somenamespace:interaction type="b" >[custom stuff for this
namespace]</somenamespace:interaction>
  </p>
</div>

What we want to achieve, is to create a (Form?)Component subclass that
can add a FormComponent to itself (or to the form?) for each
interaction, where the actual component created depends on the 'type '
attribute of the interaction.

So the xml snippet should in the end be displayed in the user's browser
as:

<div>
  <p>some silly info here</p>
  <input type="text" id="generatedId1" class="type-a"/>
  <p>even more info here, and a nested element:
    <textarea id="generatedId2" class="type-b"></textarea>
  </p>
</div>

Our thoughts on this:
1. Transform the XML to wicket markup. Temporary result:
<div>
  <p>some silly info here</p>
  <input type="text" wicket:id="generatedId1" class="type-a"/>
  <p>even more info here, and a nested element:
    <textarea wicket:id="generatedId2" class="type-b"></textarea>
  </p>
</div>

2. Feed this markup to a Panel subclass that overriding
getMarkupResourceStream()

The panel overrides getMarkupResourceStream thus:
    public IResourceStream getMarkupResourceStream(MarkupContainer
container,
            Class containerClass) {
        String markup = String.format("<wicket:panel>%s</wicket:panel>",
getModelObject());
        return new StringResourceStream(markup);
    }


In the constructor of this panel the provided wicket markup is set as
its model, and the associated markup stream is iterated to dynamically
add form components backing the generated input tags:

    public MarkupProvidingPanel(String id, IModel model) {
    // model contains a modelObject of type String containing wicket
markup
        super(id, model);

        final MarkupStream associatedMarkupStream =
getAssociatedMarkupStream(false);
        while(associatedMarkupStream.hasMore()) {
            MarkupElement element = associatedMarkupStream.next();
            if (element instanceof ComponentTag) {
                ComponentTag componentTag = (ComponentTag) element;

                if ("input".equals(componentTag.getName())) {
                    String type =
componentTag.getAttributes().getString("type", "text");
                    if ("text".equals(type)) {
                        add(new TextField(componentTag.getId()));
                    } else if ("submit".equals(type)) {
                        add(new Button(componentTag.getId(), new
Model("do it!")));
                    }
                }
            }
        }
    }


Any thoughts on the viability of this approach? Any alternative
approaches?

Regards,
Wouter

--
Wouter Huijnink
Func. Internet Integration
W http://www.func.nl
T +31 20 4230000
F +31 20 4223500



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
Matthijs Wensveen
Func. Internet Integration
W http://www.func.nl
T +31 20 4230000
F +31 20 4223500

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to