4

I have composite JSF component TimePicker.xhtml with a backing component timePickerComponent which is used as below:

      <mi:timePicker style="display: initial;"
        widgetVar="toTimepickerWidget"
        converter="#{timePickerConverter}"
                            value="#{calendarBean.event.to}" 
      /> 

And timePickerConverter created in usual way:

public class TimePickerConverter implements Converter, Serializable {
    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
            throws ConverterException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
            throws ConverterException {
        // TODO Auto-generated method stub
        return null;
    }
}

How can I use this converter in composite component?

UPDATE:

This is code of the Composite Component:

<cc:implementation componentType="timePickerComponent">
    <h:outputScript name="js/timepicker/timepicker_helper.js" target="head"/>
    <div id="#{cc.clientId}" style="#{cc.attrs.style}">

            <p:inputText id="timepicker"
                    scrollHeight="200"
                    value="#{cc.timeLocal}"  
                    size="5"/>

    </div>
</cc:implementation>

Basically what do I want is to convert plain text from inputText to Date object. Date's part irrelevant for me, I only need Time's part of the object. Btw, as a temporary solution I'll use getConvertedValue as described in this article from BalusC Composite component with multiple input fieldsBut would like to know how to delegate this functionality to an external converter too, as described in the article

Normally this method is not to be overridden and everything is delegated to default JSF Converter mechanisms

Anatoly
  • 5,056
  • 9
  • 62
  • 136
  • Can you add the `TimePicker.xhtml`? And where's your actual problem? – Smutje Apr 15 '15 at 10:05
  • @Smutje, due to company limitation I can't post exact code snippet so I posted MVCE with the same idea, thank you. – Anatoly Apr 15 '15 at 10:38
  • I don't quite understand, why don't you supply the converter to the `inputText` similar to `` – Smutje Apr 16 '15 at 05:37
  • @Smutje, if we're talking about **simple** composite component it's possible of course, but if we're talking about composite component with multiple input fields? Multiple ``? In this case only **delegated converter** can be a solution. – Anatoly Apr 16 '15 at 05:49

1 Answers1

4

In order to use converters you can invoke converter explicitly in your backing component in method getConvertedValue. The converter could be retrieved from component's converter attribute:

@FacesComponent("timePickerComponent")
public class TimePickerComponent extends UIInput implements NamingContainer {

    ...

    @Override
    public Object getSubmittedValue() {
        UIInput hourComp = (UIInput) findComponent("timepicker_hour");
        UIInput minutesComp = (UIInput) findComponent("timepicker_minutes");
        return hourComp.getSubmittedValue() + ":" + minutesComp.getSubmittedValue();
    }

    @Override
    protected Object getConvertedValue(FacesContext context,
            Object newSubmittedValue) throws ConverterException {
        Converter converter = (Converter) getAttributes().get("converter");
        if (converter != null) {
            return converter.getAsObject(context, this, (String) newSubmittedValue);
        } else {
            return newSubmittedValue;
        }
    }

}

See example code: https://github.com/destin/SO-answers/tree/master/SO-composite-jsf-component-with-converter

However, drawback of this method is that JSF components convert from String. As I understand your component consists of few subelements. All their values needs to be converted to string (like I did: hourComp.getSubmittedValue() + ":" + minutesComp.getSubmittedValue()).

So maybe you would prefer to define your own hierarchy if TimeConverters independent of JSF components. Such converters would be able to use few parameters or some complex object (like Time) as a source. Such converters could be retrieved in exactly the same way as I did.

Dawid Pytel
  • 2,750
  • 1
  • 23
  • 30