public class ConvertibleComponent
extends javax.faces.component.UIInput
implements javax.faces.component.NamingContainer
    <xi:convertible id="dateSelect" var="items" varOptions="options"
        value="#{dateBean.date}" valueConverter="#{dateBean.dateConverter}">
        days: #{options}
        <div>
          <p:spinner id="year" value="#{items.year}" min="0" max="3000" stepFactor="1"/>
          <p:spinner id="month" value="#{items.month}" min="0" max="12" stepFactor="1">
            <p:ajax process="day month" update="day month" listener="#{dateBean.updateDays}" />
          </p:spinner>
          <p:spinner id="day" value="#{items.day}" min="1" max="#{options.days}" stepFactor="1"/>
        </div>
      </xi:convertible>
 
 The converter might look like this:
 
  class ConverterImpl implements IComponentValueConverter {
    @Override
    public Map<String, Object> externalToComponentValue(Object value) {
      Map<String, Object> map = new HashMap<>();
      if (value != null) {
        String[] values = value.toString().split("_");
        if (values.length >= 1)
          map.put("year", XNumberUtils.toInt(values[0], 1));
        if (values.length >= 2)
          map.put("month", XNumberUtils.toInt(values[1], 1));
        if (values.length >= 3)
          map.put("day", XNumberUtils.toInt(values[2], 1));
      }
      return map;
    }
    @Override
    public Object componentToExternalValue(Map<String, Object> componentValues) {
      return componentValues.get("year") + "_" + componentValues.get("month") + "_" + componentValues.get("day");
    }
    @Override
    public Map<String, Object> createOptions(Map<String, Object> componentValues) {
      Map<String, Object> options = new HashMap<>();
      Integer month = (Integer)componentValues.get("month");
      if (month == null) options.put("days", 31);
      else if (month == 2) options.put("days", 28);
      else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) options.put("days", 31);
      else options.put("days", 30);
      return options;
    }
  }
 
 And the method to update the number of days dynamically as the user changes the values:
 
 public void update(AjaxBehaviorEvent event) {
   ConvertibleComponent c = (ConvertibleComponent)event.getComponent().getNamingContainer();
   final int month = XNumberUtils.toInt((String)c.getComponents().get("month").getValue(), 0);
   Map<String, Object> options = new HashMap<>();
   if (month == 2)
     options.put("days", 28);
   else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
     options.put("days", 31);
   else if (month >= 1 && month <= 12)
     options.put("days", 30);
   else
     options.put("days", 31);
   c.updateOptions(options);
 }
 
 Please note that JSF usually attempts to detect the type of the bean properties automatically via reflection. If you
 use this component, the properties are entries in a map. This results in JSF only reporting type Object for
 the properties. Some components such as InputText work just fine. For other components such as
 DatePicker, you can explicitly define a converter that converts between the string representation and the
 object (e.g. Date). Alternatively, you can also use a custom IConvertibleMap with getters and setters
 of the correct type.COMPONENT_FAMILY, COMPONENT_TYPE, CONVERSION_MESSAGE_ID, REQUIRED_MESSAGE_ID, UPDATE_MESSAGE_ID, VALIDATE_EMPTY_FIELDS_PARAM_NAME| Constructor and Description | 
|---|
ConvertibleComponent()  | 
| Modifier and Type | Method and Description | 
|---|---|
void | 
encodeBegin(javax.faces.context.FacesContext context)
Set the selected and available values of the day, month and year fields based on the model. 
 | 
void | 
encodeChildren(javax.faces.context.FacesContext context)  | 
protected Object | 
getConvertedValue(javax.faces.context.FacesContext context,
                 Object submittedValue)  | 
String | 
getFamily()  | 
Object | 
getSubmittedValue()  | 
boolean | 
isRequired()  | 
void | 
processDecodes(javax.faces.context.FacesContext context)  | 
void | 
processRestoreState(javax.faces.context.FacesContext context,
                   Object state)  | 
Object | 
processSaveState(javax.faces.context.FacesContext context)  | 
void | 
processUpdates(javax.faces.context.FacesContext context)  | 
void | 
processValidators(javax.faces.context.FacesContext context)  | 
void | 
updateOptions(IConvertibleMap<Object> options)
Sets the options of this convertible to the given value. 
 | 
boolean | 
visitTree(javax.faces.component.visit.VisitContext context,
         javax.faces.component.visit.VisitCallback callback)  | 
addValidator, addValueChangeListener, clearInitialState, compareValues, decode, getConverterMessage, getRequiredMessage, getValidator, getValidatorMessage, getValidators, getValue, getValueChangeListener, getValueChangeListeners, isEmpty, isImmediate, isLocalValueSet, isValid, markInitialState, removeValidator, removeValueChangeListener, resetValue, restoreState, saveState, setConverterMessage, setImmediate, setLocalValueSet, setRequired, setRequiredMessage, setSubmittedValue, setValid, setValidator, setValidatorMessage, setValue, setValueChangeListener, updateModel, validate, validateValuegetConverter, getLocalValue, setConverteraddClientBehavior, addFacesListener, broadcast, encodeEnd, findComponent, getAttributes, getChildCount, getChildren, getClientBehaviors, getClientId, getDefaultEventName, getEventNames, getFacesContext, getFacesListeners, getFacet, getFacetCount, getFacets, getFacetsAndChildren, getId, getListenersForEventClass, getParent, getPassThroughAttributes, getRenderer, getRendererType, getRendersChildren, getValueBinding, invokeOnComponent, isRendered, isTransient, queueEvent, removeFacesListener, restoreAttachedState, saveAttachedState, setId, setParent, setRendered, setRendererType, setTransient, setValueBinding, subscribeToEvent, unsubscribeFromEventencodeAll, getClientId, getCompositeComponentParent, getContainerClientId, getCurrentComponent, getCurrentCompositeComponent, getNamingContainer, getPassThroughAttributes, getResourceBundleMap, getStateHelper, getStateHelper, getTransientStateHelper, getTransientStateHelper, getValueExpression, initialStateMarked, isCompositeComponent, isInView, isVisitable, popComponentFromEL, processEvent, pushComponentToEL, restoreTransientState, saveTransientState, setInView, setValueExpressionpublic void encodeBegin(javax.faces.context.FacesContext context)
                 throws IOException
encodeBegin in class javax.faces.component.UIComponentBaseIOExceptionpublic void encodeChildren(javax.faces.context.FacesContext context)
                    throws IOException
encodeChildren in class javax.faces.component.UIComponentBaseIOExceptionpublic String getFamily()
getFamily in class javax.faces.component.UIInputpublic Object getSubmittedValue()
getSubmittedValue in interface javax.faces.component.EditableValueHoldergetSubmittedValue in class javax.faces.component.UIInputpublic boolean isRequired()
isRequired in interface javax.faces.component.EditableValueHolderisRequired in class javax.faces.component.UIInputpublic void processDecodes(javax.faces.context.FacesContext context)
processDecodes in class javax.faces.component.UIInputpublic void processRestoreState(javax.faces.context.FacesContext context,
                                Object state)
processRestoreState in class javax.faces.component.UIComponentBasepublic Object processSaveState(javax.faces.context.FacesContext context)
processSaveState in class javax.faces.component.UIComponentBasepublic void processUpdates(javax.faces.context.FacesContext context)
processUpdates in class javax.faces.component.UIInputpublic void processValidators(javax.faces.context.FacesContext context)
processValidators in class javax.faces.component.UIInputpublic void updateOptions(IConvertibleMap<Object> options)
options - The new options for this convertible, accessible by the children.public boolean visitTree(javax.faces.component.visit.VisitContext context,
                         javax.faces.component.visit.VisitCallback callback)
visitTree in class javax.faces.component.UIComponentCopyright © 2020 XIMA MEDIA GmbH. All rights reserved.