Jesse's idea seems reasonable. I was about to spout off some ideas, but
then realized that I need to understand your situation better first. :)
In particular, can you explain in more detail how the components are
configured from a db or xml file? More explicitly, is the number and
type of components determined by the db or xml file? Or is it just the
parameters for the n components which are determined by the db/xml file?
Those are two subtlety different things, after all. :) One implies that
for each company, you actually know the set of components that need to
go on the page, but need to get the actual /parameters/ for those
components from some configuration.  The other implies that, for
instance, the company may at runtime add various types of fields to
their page config.

For the former scenario (you know the components for a given company,
but you just need to be able select based on company), you can render
the consistent components, and then for the custom components, do
something like:

<span jwcid="@RenderBlock" block="ognl:getBlock(company)"/>

.java:

public Block getBlock(Company c) {
  return (Block)
getRequestCycle().getPage(c.getBlockPageName()).getComponent(c.getBlockName());
}

Now you can have a separate page for each company which contains a block
which, in turn, contains the components for that company.

If it's the latter scenario, then I'd probably head down a path similar
to what jesse suggested. In reality, the type of components that the
user can add is going to be limited... select, text, checkbox, radio...
am I missing anything? :) So, yeah... I think jesse's idea would hold
well. So, you would do something like this:

<span jwcid="@Foreach" source="ognl:company.extraFields"
value="ognl:currentField">
  <span jwcid="@RenderBlock"
block="ognl:components[currentField.blockName]" field="ognl:currField"/>

</span>
<span jwcid="[EMAIL PROTECTED]">
   <span jwcid="@Insert"
value="ognl:components.foo.inserter.bindings['field'].object.label"/>
<span jwcid="[EMAIL PROTECTED]"
value="ognl:components.foo.inserter.bindings['field'].object.value/>
</span>

A couple of notes... here as well, the block doesn't have to be on the
same page as the RenderBlock. You could get fancy and have your field
specify the page name and block name, or whatever. Also note that the
finally-rendered component has the "inserter" parameter... very useful.
You can get at any informal parameters of the "RenderBlock" parameter
that way. (In fact, there's probably a shorter ognl path than the one I
put in, although the one I put in will work). So, you can pass whatever
objects along that you need to that way to configure the components.

HTH. (Hrm. Looks like I ended up spouting off, anyway :)

Robert

Jesse Kuhnert wrote:
> That sounds like one crazy set of requirements ;)
> 
> I don't know how you will possibly handle the layout issues involved, but it
> wouldn't be far-fetched to do something like(taken from
> http://jakarta.apache.org/tapestry/tapestry/ComponentReference/RenderBlock.html
> ):
> 
> <foreach looping element here>
> 
> <span jwcid="<your field type block name>@Block" >
>       <span jwcid="[EMAIL PROTECTED]" />
> </span>
> 
> <span jwcid="<your field type block name>@Block">
>       <span jwcid="[EMAIL PROTECTED]" />
> </span>
> 
> </for>
> 
> Your page would then hand out blocks depending on the type of field you need
> to render "for each" loop. I've used a similar technique for handling
> varying data type renders, but they were always based around rendering a
> custom component "form" configuration.
> 
> Ie if I had a classification system for ummm... "pets", I might have a
> different form component grouping for each pet:
> 
> Dog:
> <number of cats chased>
> <likes to be pet>
> <known to bite>
> 
> Cat:
> <number of dogs hissed at>
> <definitely hates everyone>
> 
> etc...
> 
> hope that helps..
> 
> jesse
> 
> On 1/26/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> 
>>We're neck deep in Tapestry 3.0.3 and are struggling with how to handle N
>>number of components in a form.
>>
>>(from thread, below) "I've found that anything you might think of solving
>>by using dynamic components can be solved as well or better by some other
>>method which
>>tapestry /does/ provide."
>>
>>If this is true, how would Tapestry solve the following problem?
>>
>>(basically this is the problem of putting N text fields in a form, where N
>>is derived from a db/sml configuration)
>>
>>We have a page containing a form, let's say it's an order form.  The user
>>is entering data for various companies, not just their employer.  The form
>>contains a bare minium of form elements / components, e.g., name, address,
>>item, quantity, price, etc., and these are common to all companies.
>>
>>However, depending on the company for whom we are filling out the form,
>>there may be additional fields.  There can be from zero to n additional
>>fields.  These additional fields are configured in a database or XML file.
>>How do I dynamically generate the addittional, company-specific
>>components on the form?  Note, this is important because each component
>>must use Tapestry's validation/delegate mechanism to perform server-side
>>validation.
>>
>>Currently, we have resorted to doing client-side validation on the
>>custom/dynamic form elements & then letting Tapestry perform server-side
>>validation on the static form components.  From a usibility stance, this
>>is unacceptable.  But we're stumped on how to have N components in our
>>form.  We must fulfill this requirement.  Yes, we could create 20 extra
>>components & use conditionals, but we don't want to be limited to any
>>number--there really could be 50 or 100 or more.
>>
>>Thanks,
>>  - Mike
>>
>>
>>---------------------------------------------------------------------------------------
>>Re: instantiating components directly
>>Robert Zeigler
>>Thu, 12 Jan 2006 12:28:46 -0800
>>
>>Yes... but you don't need to use dynamically added components to
>>accomplish that. You can accomplish it using a static structure, including
>>direct links. Or, your "tree" component implements the "IDirect"
>>interface. Then it generates the urls needed, and provides the necessary
>>listener and gets called-back automatically by the direct service. I think
>>there are some pretty good reasons to keep the component tree static. For
>>one thing, page objects are very expensive to create, which necessitates
>>(the oft maligned) page pooling. However, because you are pooling the
>>pages, the component tree MUST be static, because you can't guarantee that
>>the same page instance will be used the /next/ time the page is rendered.
>>There may be ways around that, but generally, I've found that anything you
>>might think of solving by using dynamic components can be solved as well
>>or better by some other method which
>>tapestry /does/ provide.
>>(That said, I won't deny wishing for being able to add components at
>>runtime on occasion. :)
>>
>>Robert
>>
> 
> 


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

Reply via email to