0

Seems basic enough...

I have a custom JSF component and its associated renderer. The renderer does the decode and encodeEnd.

In decode i successfully retrie the submitted value via component.setSubmittedValue(ctx.getExternalContext().getRequestParameterMap().get(c.getClientId()));

In encodeEnd, i basically create the markup and if component.getValue() is not null, i insert its contents in the markup. So far so good.

Problem is that getValue() can be only be String. I have custom class that represents a compound data type and i want to use that as the component's local value. But doesn't work - JSF converts to String.

I also tried using component.getAttributes() - from the decode method, where i put my custom object in keyed to private static final String someKey = "asd". But later at encodeEnd there is no value/key in the map.

I want the users of this component to be able to specify in their backing bean the custom data type and not worry about serialization/deserialization to text representation between client/server. Presumably i have to use a converter for that? But how can i set up a default and immutable converter for the custom component?

4
  • 1
    Although you are not using it, take a look at the source of the PrimeFaces p:calendar. It calls converters to/from a Date using a dateFormat. I think you can extrapolate that from specifying a class somewhere Commented Jan 13, 2019 at 23:55
  • Kukeltje, found it. So it basically overrides getConvertedValue of the renderer itself? Simple enough... Will try it later when I get a chance. It's incredible how the official tutorial - javaee7tutorial will not include that. Thanks for the response. Commented Jan 14, 2019 at 9:21
  • 1
    It does not include this since it is something that is rarely used by end-users. Of you have a solution or direction, please create an answer and accept it. But maybe there is a duplicate Q/A in google.com/… Commented Jan 14, 2019 at 9:28
  • 2
    This comes close: stackoverflow.com/q/17235721 Commented Jan 14, 2019 at 10:11

1 Answer 1

0

The problem has a simple enough of a solution. Inside the Renderer class (or right into the Component class if using that directly):

@Override public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException { SomeCustomObject thing; //... do magic to create SomeCustomObject based on submittedValue return thing; } 

Now whenever getValue() is called on that component, SomeCustomObject will be returned and you can safely cast to it. Also in the backing beans can use SomeCustomObject as the type.

Also note when calling component.getValue() in the actual Renderer, it will return SomeCustomObject as well, so if you're restoring state, you must convert back to its String representation.

For more details see and @Kukeltje's answer above and check how the same thing is done for primefaces calendar component here: https://github.com/primefaces/primefaces/blob/master/src/main/java/org/primefaces/component/calendar/BaseCalendarRenderer.java

For another more concise and clear illustration, check @BalusC's answer as well.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.