[
https://issues.apache.org/jira/browse/TAPESTRY-2350?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12595996#action_12595996
]
Philip Lopez commented on TAPESTRY-2350:
----------------------------------------
In case anyone has a similar need, here's a simple alternative approach that
seems to be working. It's a little more verbose, and not as flexible, but also
avoids a duplicate component hierarchy problem.
Haven't had a chance yet to follow on through the BeanEditor idea (although I
did borrow some of those techniques for something else), but I did come up with
a simpler approach to overriding the element IDs, that doesn't violate
encapsulation.
The solution I used was a "QuestionTemplate" component that is simpler and will
work most of the time. The only real ugliness is the duplication of the "for"
element...
QuestionTemplate.tml:
<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<div class="question">
<t:label t:id="label" class="prompt" for="prop:field" />
<t:body />
<t:if test="required">
<span class="requiredIndicator">*</span>
</t:if>
</div>
</t:container>
QuestionTemplate.java:
public class QuestionTemplate
{
@Parameter(name = "for", required = true, defaultPrefix = "component")
private Field field;
public Field getField()
{
return field;
}
public boolean isRequired()
{
return field.isRequired();
}
}
Example usage:
<div t:type="form/QuestionTemplate" for="eCode">
<t:textfield t:id="eCode" validate="required,regexp" />
</div>
> Overriding/alternative to t:id when building composite sub-form components
> --------------------------------------------------------------------------
>
> Key: TAPESTRY-2350
> URL: https://issues.apache.org/jira/browse/TAPESTRY-2350
> Project: Tapestry
> Issue Type: Improvement
> Components: Core Components
> Affects Versions: 5.0.11, 5.0.12
> Reporter: Philip Lopez
> Assignee: Howard M. Lewis Ship
>
> It does not appear to be possible to specify the t:id value through more than
> one layer of a component hierarchy. This becomes a problem when trying to
> build reusable form widgets, particularly as the validation infrastructure
> uses the component's t:id as the key into configuration (via properties),
> e.g. for regexp.
> Here is an example of what I'm trying to do -- the motivation being to build
> a set of reusable form building blocks for a large number of corporate
> developers (and many separate systems), the goal being to encapsulate
> markup/CSS standards into a library... effectively a simple DSL.
> Imagine a set of "Question" widgets, e.g. a QuestionText that has something
> like the following TML:
> <div>
> <t:label class="question" for="textQuestion" />
> <t:textfield t:id="textQuestion" ... />
> <t:if test="required"> <em>*</em> </t:if>
> </div>
> Using this widget we can write simply:
> <div t:type="QuestionText" t:id="accreditationCode"
> validate="required,regexp" />
> rather than the full set of markup for each question, and we've encapsulated
> non-semantic markup such as the wrapping div, the order of label and field,
> the presence of a mandatory field marker (*) and css classes. Component
> frameworks are ideal...
> BUT... because we have to set the t:id="textQuestion" in this QuestionText
> component (e.g. for label to work, and because t:id cannot be bound to a
> parameter/expression), when we drill into using Tapestry's sophisticated
> features, life becomes hard.
> We can reproduce the automatic "value" -> "id" transformation that Tapestry
> does for TextField by reproducing AbstractTextField.defaultValue() in our
> QuestionText component. Similarly, we can pass through validators by
> injecting FieldValidatorSource. It's a little painful, but worth the effort
> (for my use case). Using clientId is necessary also, to build nice, testable
> (e.g. WebDriver) markup -- although perhaps that will break in
> larger/iterated composites.
> But since FIeldValidatorSourceImpl uses ComponentResources.getId() to lookup
> constraints and messages in the Messages "context", it does not appear
> possible (at least to me) to easily override this behaviour.
> Being able to programmatically override t:id might break the static structure
> / dynamic behaviour model, but I'm wondering whether t:id is doing
> double-duty here, and perhaps there needs to be another abstraction for id (~
> controlName, ~clientId) that <em>can</em> be injected across multiple layers
> of components -- perhaps defaulting to t:id otherwise... but that would seem
> to need another entity such as t:logicalId, with all the required changes
> back up to the template parser...
> AFAIK, Field.controlName or ClientElement.clientId are a little too
> "generated" for uniqueness reasons.
> I'm not sure if mixins can be used here, but I'd rather use the existing
> Tapestry validation framework than implement a parallel one. Perhaps a less
> obvious approach, but maybe more elegant, is to look at decorating standard
> Field components.
> In summary... does t:id have to be overridden to build up reusable (larger)
> form widgets, or are there some more feasible alternatives?
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]