You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Martin Gruschi <pl...@chello.at> on 2014/07/09 17:54:14 UTC
Component unsing 2 inputs for 1 bean (as binding-attribute) containing
2 attributes
Preface: I'm not sure if the myfaces mailing list is the correct place
to ask my questions but I didn't find any general JSF-list.
I've seen many not myfaces-implementation-related questions in this
mailing list in the past so I just tried.
If it's the wrong place just please tell me (and perhaps you know
another more general JSF-related community to point me to).
So I'm at that point that I need an accordingly input component.
The bean containing value and unit has constructor and getters (no
setters) which works fine for reading only (see my previous mail).
Here is an example of the structure:
Bean1 contains "bean" which has 2 attributes, unit and value. bean
should be bound on the input-component to write.
I now do not know how to implement the custom "bean"-input-component
since there are other prerequisites.
value is a BigDecimal
There are 3 scenarios with the unit (String):
1) allowed 1 unit only: e.g Miles
This could be implemented separately as inputText.
2) selection of a set of use case defined possible units
This could be implemented separately as selectOneListbox.
3) selection of a set of all units defined in system
I therefore have a already a composite-component, in fact a
selectOnelistbox in an composite-xhtml with a Java-Class (extends
UINamingContainer) as componentType for reading the units from backend.
I analyzed the options and have different approaches in mind, but what
of them is the way to go (and in line with the JSF sepcification)?
a) Composite-Way (direct)
I believe there is no chance to use the beans constructor with 2
separated components within the composite-xhtml, since the binding (as
in my ouput composite) is 1 level to low (no setters!).
b) Composite Way using Javascript
It might be simple to write a Converter to serialize the bean to String
and back. So another approach would be to bind the bean to a inputHidden
using that converter and to code plain html-input tags for unit and
value also in the xhtml-part of the composite. With extra
onchange-Javascript it would be possible to create the same String (the
converter can parse) from unit and value html-inputs into that hidden
input which can than be processed by the converter. But than the
business logic of 3) (see above) must be implemented twice.
c) Composite-Way as Html-Renderer only
I mentioned that it works to implement the componentType extending
UIInput when overriding getFamily to return UINamingContainer.
My next step in thinking from b) was to use the xhtml-Part with plain
html-inputs doing the decoding in the Java-Class reading the 2
Parameters and creating 1 combined localeValue.
With a Converter-Superclass splitting that up in 2 parts and delegating
to 2 separate validator-Methods I would be able to do validation on each
field. Same way I think I could implement a converter from this
combined-String in localeValue to the bean-Object in value (as in b) ).
Beside of that I'm not sure which consequences overriding getFamily
might have at other points in JSF and I'm also not able to use my
existing composite-component to read the possible units from backend.
It's more ore less b) with doing that Javascript-thing in the
componentType-Java-class within "decode".
d) Composite-Way
Another idea was to hold information redundant. So I would code the
xhtml-Part with the JSF-components already there (see 1) - 3) ). The
componentType-class would have members unit and value an I would bind
them to the JSF-components hoping the values from the page are there
after the validation phase.
But what event can I listen to or which method of the
componentType-class might be the correct to build the bean from the
inner values and call setvalue before the update-model-phase?
In this way one could provide Converters and Validator for unit and
value separately (when defined as valueHolder in the composite-xhtml)
and existing components are reused.
But as in b): Is it legal from JSF's point of view to override getFamily?
e) pure Java-Component (plus Renderer)
The main issue for me is how can I reuse my Composite-Component (reading
possible units from backend) in a pure Java-component? If that doesn't
work I don't need to dig in any deeper into how to develope
Java-Components (with Renderers,...).
Can someone (experienced) give me an advice which is the correct way of
implementing components for single beans (with multiple attributes) with
existing components (for that attributes and with the flexibility to add
validators and/or converters for that attributes - in this case
unit/value)?
Thank you,
Martin
On 07.07.2014 16:46, pluenl@chello.at wrote:
> Works now for Ouptut:
>
> Since I'm new to JSF I was thinking valueHolder also does the binding, which is not wanted in that case.
> But the following works as intended:
>
> <composite:interface>
> <composite:attribute name="id" required="true"/>
> <composite:attribute name="bean" required="true" type="a.x.Y"/>
> <composite:valueHolder name="value"/>
> <composite:valueHolder name="unit"/>
> </composite:interface>
>
> <composite:implementation>
> <span id="#{cc.clientId}">
> <h:outputText value="#{cc.attrs.bean.value}" id="value"/>
> <span><h:outputText value="#{cc.attrs.bean.unit}" id="unit"/></span>
> </span>
> </composite:implementation>
>
> <my:compOut id="beanId" bean="#{bean}">
> <f:convertNumber pattern="#,##0.00" locale="de" for="unit"/>
> </my:compOut>
>
>
>
> ----pluenl@chello.at schrieb:
>> I've already tried this, which resulted in
>>
>> <f:convertNumber> is nested inside a composite component but does not have a for attribute.
>>
>> I forgot to mention that I need to use JSF 2.0.
>>
>> Martin
>>
>> ---- Martin Schacherl<Ma...@iteratec.at> schrieb:
>>> AFAIR you'll need to insert <composite:insertChildren /> in the composite component instead of <f:formatNumber>. When you call your composite component with a <f:convertNumber> tag as child, it gets inserted at the point where <composite:insertChildren /> occurs in your composite.
>>>
>>> Cheers,
>>> Martin
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von:pluenl@chello.at [mailto:pluenl@chello.at]
>>> Gesendet: Montag, 7. Juli 2014 13:06
>>> An:users@myfaces.apache.org
>>> Betreff: Composite with 2 outputs on 1 attribute
>>>
>>> I want to build a Composite handling a Bean with 2 members internally:
>>>
>>> Bean with Bigdecimal value and String unit
>>>
>>> as Attribute for the Composite:
>>>
>>> <composite:interface>
>>> <composite:attribute name="id" required="true"/>
>>> <composite:attribute name="bean" required="true" type="a.x.Y"/> </composite:interface>
>>>
>>> <composite:implementation>
>>> <span id="#{cc.clientId}">
>>> <h:outputText value="#{cc.attrs.bean.value}" id="value"/>
>>> <span><h:outputText value="#{cc.attrs.bean.unit}" id="unit"/></span>
>>> </span>
>>> </composite:implementation>
>>>
>>>
>>> This works fine for calling it like
>>>
>>> <my:compOut id="beanId" bean="#{bean}"/>
>>>
>>> Now I want to specify formatting, which works within the Composite like
>>>
>>> <h:outputText value="#{cc.attrs.bean.value}" id="value">
>>> <f:convertNumber pattern="#,##0.00" locale="de"/> </h:outputText>
>>>
>>> but I want to set it within the calling Facelet:
>>>
>>> <my:compOut id="beanId" bean="#{bean}">
>>> <f:convertNumber pattern="#,##0.00" locale="de"/> </my:compOut>
>>>
>>> which does not work. I assume this is since I have no editableValueHolder to refer to.
>>>
>>> In the following there schould be an accordingly Input implementation with 2 InputTexts <my:compIn>.
>>>
>>> Is there any solution to this (for output and/or input) or ist that combination with composites simply not possible (and must be coded in a Java-Component)?
>>>
>>> Martin Gruschi