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