You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2020/12/11 07:54:31 UTC

[myfaces-tobago] 16/22: TOBAGO-703 - sheet paging should adjust scroll position

This is an automated email from the ASF dual-hosted git repository.

weber pushed a commit to branch TOBAGO-1999_Select2
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 5cfaa12e74295ac2852f45b1c4e69e37955b5b8c
Author: Volker Weber <v....@inexso.de>
AuthorDate: Wed Sep 16 10:43:46 2020 +0200

    TOBAGO-703 - sheet paging should adjust scroll position
---
 .../myfaces/tobago/facelets/SelectManyBoxRule.java |  13 +-
 .../extension/TobagoLabelExtensionHandler.java     |   5 +
 .../component/AbstractUISelectManyBox.java         |   6 +-
 .../extension/SelectManyBoxExtensionTag.java       | 507 ++++++++++++++-------
 4 files changed, 348 insertions(+), 183 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/SelectManyBoxRule.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/SelectManyBoxRule.java
index 0e413a3..c1e1427 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/SelectManyBoxRule.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/SelectManyBoxRule.java
@@ -1,9 +1,6 @@
 package org.apache.myfaces.tobago.facelets;
 
-import org.apache.myfaces.tobago.component.Attributes;
-import org.apache.myfaces.tobago.component.SupportsRenderedPartially;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBox;
-import org.apache.myfaces.tobago.util.ComponentUtils;
 
 import javax.el.ValueExpression;
 import javax.faces.component.UIComponent;
@@ -22,24 +19,24 @@ public class SelectManyBoxRule extends MetaRule {
   public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget metadataTarget) {
     if (metadataTarget.isTargetInstanceOf(AbstractUISelectManyBox.class)) {
       if (TOKEN_SEPARATORS.equals(name)) {
-        return new SelectManyBoxRule.SelectManyBoxMapper(attribute);
+        return new SelectManyBoxRule.TokenSeparatorsMapper(attribute);
       }
     }
     return null;
   }
 
-  static final class SelectManyBoxMapper extends Metadata {
+  static final class TokenSeparatorsMapper extends Metadata {
 
     private final TagAttribute attribute;
 
-    public SelectManyBoxMapper(TagAttribute attribute) {
+    public TokenSeparatorsMapper(TagAttribute attribute) {
       this.attribute = attribute;
     }
 
     public void applyMetadata(FaceletContext faceletContext, Object instance) {
       if (attribute.isLiteral()) {
-        final String[] components = AbstractUISelectManyBox.parseTokenSeparators(attribute.getValue());
-        ((AbstractUISelectManyBox) instance).setTokenSeparators(components);
+        final String[] tokenSeparators = AbstractUISelectManyBox.parseTokenSeparators(attribute.getValue());
+        ((AbstractUISelectManyBox) instance).setTokenSeparators(tokenSeparators);
       } else {
         final ValueExpression expression = attribute.getValueExpression(faceletContext, Object.class);
         ((UIComponent) instance).setValueExpression(TOKEN_SEPARATORS, expression);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/extension/TobagoLabelExtensionHandler.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/extension/TobagoLabelExtensionHandler.java
index 7c5e753..cbd2ca3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/extension/TobagoLabelExtensionHandler.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/extension/TobagoLabelExtensionHandler.java
@@ -30,9 +30,11 @@ import org.apache.myfaces.tobago.component.UIGridLayout;
 import org.apache.myfaces.tobago.component.UILabel;
 import org.apache.myfaces.tobago.component.UIPanel;
 import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.facelets.SelectManyBoxRule;
 import org.apache.myfaces.tobago.facelets.SuggestMethodRule;
 import org.apache.myfaces.tobago.facelets.SupportsMarkupRule;
 import org.apache.myfaces.tobago.facelets.TobagoComponentHandler;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBox;
 import org.apache.myfaces.tobago.internal.layout.LayoutUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -260,6 +262,9 @@ public abstract class TobagoLabelExtensionHandler extends ComponentHandler {
     if (InputSuggest.class.isAssignableFrom(aClass)) {
       metaRuleset.addRule(SuggestMethodRule.INSTANCE);
     }
+    if (AbstractUISelectManyBox.class.isAssignableFrom(aClass)) {
+      metaRuleset.addRule(SelectManyBoxRule.INSTANCE);
+    }
     return metaRuleset;
   }
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBox.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBox.java
index f6ecc6b..d365469 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBox.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBox.java
@@ -191,11 +191,11 @@ public abstract class AbstractUISelectManyBox extends AbstractUISelectMany imple
   }
 
   public static String[] parseTokenSeparators(String tokenSeparators) {
-    Set<String> tokens = new HashSet<String>();
+    String[] tokens = new String[tokenSeparators.length()];
     for (int i = 0; i < tokenSeparators.length(); i++) {
-      tokens.add(tokenSeparators.substring(i, i + 1));
+      tokens[i] = tokenSeparators.substring(i, i + 1);
     }
-    return tokens.toArray(new String[0]);
+    return tokens;
   }
 
   public boolean isTokenSeparatorsSet() {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/extension/SelectManyBoxExtensionTag.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/extension/SelectManyBoxExtensionTag.java
index d23448f..51a0931 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/extension/SelectManyBoxExtensionTag.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/extension/SelectManyBoxExtensionTag.java
@@ -24,7 +24,7 @@ import org.apache.myfaces.tobago.apt.annotation.ExtensionTag;
 import org.apache.myfaces.tobago.apt.annotation.Tag;
 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
-import org.apache.myfaces.tobago.internal.taglib.SelectManyListboxTag;
+import org.apache.myfaces.tobago.internal.taglib.SelectManyBoxTag;
 
 import javax.el.MethodExpression;
 import javax.el.ValueExpression;
@@ -39,30 +39,40 @@ import javax.servlet.jsp.JspException;
     faceletHandler = "org.apache.myfaces.tobago.facelets.extension.SelectManyBoxExtensionHandler")
 public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
 
-  private ValueExpression required;
-  private ValueExpression value;
-  private MethodExpression valueChangeListener;
-  private ValueExpression disabled;
-  private ValueExpression readonly;
-  private ValueExpression onchange;
-  private ValueExpression label;
   private ValueExpression accessKey;
-  private ValueExpression rendered;
+  private ValueExpression allowClear;
+  private ValueExpression allowCustom;
   private ValueExpression binding;
-  private ValueExpression tip;
   private ValueExpression converter;
-  private MethodExpression validator;
+  private ValueExpression converterMessage;
+  private ValueExpression disabled;
+  private ValueExpression focus;
+  private ValueExpression hideDropdown;
+  private ValueExpression label;
   private ValueExpression labelWidth;
   private ValueExpression markup;
+  private ValueExpression  matcher;
+  private ValueExpression  maximumInputLength;
+  private ValueExpression  maximumSelectionLength;
+  private ValueExpression  minimumInputLength;
+  private ValueExpression onchange;
+  private ValueExpression placeholder;
+  private ValueExpression readonly;
+  private ValueExpression rendered;
+  private ValueExpression required;
+  private ValueExpression requiredMessage;
   private ValueExpression tabIndex;
-  private ValueExpression focus;
+  private ValueExpression tip;
+  private ValueExpression tokenizer;
+  private ValueExpression tokenSeparators;
+  private MethodExpression validator;
   private ValueExpression validatorMessage;
-  private ValueExpression converterMessage;
-  private ValueExpression requiredMessage;
+  private ValueExpression value;
+  private MethodExpression valueChangeListener;
   private String fieldId;
 
   private LabelExtensionTag labelTag;
-  private SelectManyListboxTag selectManyListboxTag;
+  private SelectManyBoxTag selectManyBoxTag;
 
   @Override
   public int doStartTag() throws JspException {
@@ -95,69 +105,104 @@ public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
     labelTag.setJspId(nextJspId());
     labelTag.doStartTag();
 
-    selectManyListboxTag = new SelectManyListboxTag();
-    selectManyListboxTag.setPageContext(pageContext);
-    if (value != null) {
-      selectManyListboxTag.setValue(value);
+    selectManyBoxTag = new SelectManyBoxTag();
+    selectManyBoxTag.setPageContext(pageContext);
+    if (allowClear != null) {
+      selectManyBoxTag.setAllowClear(allowClear);
     }
-    if (valueChangeListener != null) {
-      selectManyListboxTag.setValueChangeListener(valueChangeListener);
+    if (allowCustom != null) {
+      selectManyBoxTag.setAllowCustom(allowCustom);
     }
     if (binding != null) {
-      selectManyListboxTag.setBinding(binding);
-    }
-    if (onchange != null) {
-      selectManyListboxTag.setOnchange(onchange);
-    }
-    if (validator != null) {
-      selectManyListboxTag.setValidator(validator);
+      selectManyBoxTag.setBinding(binding);
     }
     if (converter != null) {
-      selectManyListboxTag.setConverter(converter);
+      selectManyBoxTag.setConverter(converter);
+    }
+    if (converterMessage != null) {
+      selectManyBoxTag.setConverterMessage(converterMessage);
     }
     if (disabled != null) {
-      selectManyListboxTag.setDisabled(disabled);
+      selectManyBoxTag.setDisabled(disabled);
+    }
+    if (fieldId != null) {
+      selectManyBoxTag.setId(fieldId);
     }
     if (focus != null) {
-      selectManyListboxTag.setFocus(focus);
+      selectManyBoxTag.setFocus(focus);
     }
-    if (fieldId != null) {
-      selectManyListboxTag.setId(fieldId);
+    if (hideDropdown != null) {
+      selectManyBoxTag.setHideDropdown(hideDropdown);
     }
     if (label != null) {
-      selectManyListboxTag.setLabel(label);
+      selectManyBoxTag.setLabel(label);
+    }
+    if (markup != null) {
+      selectManyBoxTag.setMarkup(markup);
+    }
+    if (matcher != null) {
+      selectManyBoxTag.setMatcher(matcher);
+    }
+    if (maximumInputLength != null) {
+      selectManyBoxTag.setMaximumInputLength(maximumInputLength);
+    }
+    if (maximumSelectionLength != null) {
+      selectManyBoxTag.setMaximumSelectionLength(maximumSelectionLength);
+    }
+    if (minimumInputLength != null) {
+      selectManyBoxTag.setMinimumInputLength(minimumInputLength);
+    }
+    if (onchange != null) {
+      selectManyBoxTag.setOnchange(onchange);
+    }
+    if (placeholder != null) {
+      selectManyBoxTag.setPlaceholder(placeholder);
     }
     if (readonly != null) {
-      selectManyListboxTag.setReadonly(readonly);
+      selectManyBoxTag.setReadonly(readonly);
     }
     if (required != null) {
-      selectManyListboxTag.setRequired(required);
+      selectManyBoxTag.setRequired(required);
     }
-    if (markup != null) {
-      selectManyListboxTag.setMarkup(markup);
+    if (requiredMessage != null) {
+      selectManyBoxTag.setRequiredMessage(requiredMessage);
     }
     if (tabIndex != null) {
-      selectManyListboxTag.setTabIndex(tabIndex);
+      selectManyBoxTag.setTabIndex(tabIndex);
+    }
+    if (tokenizer != null) {
+      selectManyBoxTag.setTokenizer(tokenizer);
+    }
+    if (tokenSeparators != null) {
+      if (!tokenSeparators.isLiteralText()) {
+        selectManyBoxTag.setTokenSeparators(tokenSeparators);
+      } else {
+        selectManyBoxTag.setTokenSeparators(tokenSeparators);
+      }
+    }
+    if (validator != null) {
+      selectManyBoxTag.setValidator(validator);
     }
     if (validatorMessage != null) {
-      selectManyListboxTag.setValidatorMessage(validatorMessage);
+      selectManyBoxTag.setValidatorMessage(validatorMessage);
     }
-    if (converterMessage != null) {
-      selectManyListboxTag.setConverterMessage(converterMessage);
+    if (value != null) {
+      selectManyBoxTag.setValue(value);
     }
-    if (requiredMessage != null) {
-      selectManyListboxTag.setRequiredMessage(requiredMessage);
+    if (valueChangeListener != null) {
+      selectManyBoxTag.setValueChangeListener(valueChangeListener);
     }
-    selectManyListboxTag.setParent(labelTag);
-    selectManyListboxTag.setJspId(nextJspId());
-    selectManyListboxTag.doStartTag();
+
+    selectManyBoxTag.setParent(labelTag);
+    selectManyBoxTag.setJspId(nextJspId());
+    selectManyBoxTag.doStartTag();
 
     return super.doStartTag();
   }
 
   @Override
   public int doEndTag() throws JspException {
-    selectManyListboxTag.doEndTag();
+    selectManyBoxTag.doEndTag();
     labelTag.doEndTag();
     return super.doEndTag();
   }
@@ -165,66 +210,106 @@ public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
   @Override
   public void release() {
     super.release();
+    accessKey = null;
+    allowClear = null;
+    allowCustom = null;
     binding = null;
-    onchange = null;
+    converter = null;
+    converterMessage = null;
     disabled = null;
+    fieldId = null;
+    focus = null;
+    hideDropdown = null;
     label = null;
-    accessKey = null;
+    labelTag = null;
     labelWidth = null;
+    markup = null;
+    matcher = null;
+    maximumInputLength = null;
+    maximumSelectionLength = null;
+    minimumInputLength = null;
+    onchange = null;
+    placeholder = null;
     readonly = null;
     rendered = null;
-    converter = null;
-    validator = null;
     required = null;
-    tip = null;
-    value = null;
-    valueChangeListener = null;
-    markup = null;
+    requiredMessage = null;
+    selectManyBoxTag = null;
     tabIndex = null;
-    selectManyListboxTag = null;
-    labelTag = null;
-    focus = null;
+    tip = null;
+    tokenizer = null;
+    tokenSeparators = null;
+    validator = null;
     validatorMessage = null;
-    converterMessage = null;
-    requiredMessage = null;
-    fieldId = null;
+    valueChangeListener = null;
+    value = null;
+
   }
 
   /**
-   * Flag indicating that a value is required.
-   * If the value is an empty string a
-   * ValidationError occurs and a Error Message is rendered.
+   * The accessKey of this component.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
-  public void setRequired(final ValueExpression required) {
-    this.required = required;
+  @UIComponentTagAttribute(type = "java.lang.Character")
+  public void setAccessKey(final ValueExpression accessKey) {
+    this.accessKey = accessKey;
   }
 
   /**
-   * The current value of this component.
+   * Flag indicating that this select provides support for clearable selections.
+   *
+   * This is a select2 feature and will force select2=true
    */
-  @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Object")
-  public void setValue(final ValueExpression value) {
-    this.value = value;
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
+  public void setAllowClear(ValueExpression allowClear) {
+    this.allowClear = allowClear;
   }
 
   /**
-   * MethodBinding representing a value change listener method
-   * that will be notified when a new value has been set for this input component.
-   * The expression must evaluate to a public method that takes a ValueChangeEvent
-   * parameter, with a return type of void.
+   * Flag indicating that this select enables free text responses.
    *
-   * @param valueChangeListener
+   * This is a select2 feature and will force select2=true
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
+  public void setAllowCustom(ValueExpression allowCustom) {
+    this.allowCustom = allowCustom;
+  }
+
+  /**
+   * The value binding expression linking this
+   * component to a property in a backing bean.
    */
   @TagAttribute
-  @UIComponentTagAttribute(
-          type = {},
-          expression = DynamicExpression.METHOD_EXPRESSION_REQUIRED,
-          methodSignature = "javax.faces.event.ValueChangeEvent")
-  public void setValueChangeListener(final MethodExpression valueChangeListener) {
-    this.valueChangeListener = valueChangeListener;
+  @UIComponentTagAttribute(type = "javax.faces.component.UIComponent")
+  public void setBinding(final ValueExpression binding) {
+    this.binding = binding;
+  }
+
+  /**
+   * An expression that specifies the Converter for this component.
+   * If the value binding expression is a String,
+   * the String is used as an ID to look up a Converter.
+   * If the value binding expression is a Converter,
+   * uses that instance as the converter.
+   * The value can either be a static value (ID case only)
+   * or an EL expression.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "javax.faces.convert.Converter",
+      expression = DynamicExpression.VALUE_EXPRESSION)
+  public void setConverter(final ValueExpression converter) {
+    this.converter = converter;
+  }
+
+  /**
+   * An expression that specifies the converter message
+   */
+  @TagAttribute
+  @UIComponentTagAttribute()
+  public void setConverterMessage(final ValueExpression converterMessage) {
+    this.converterMessage = converterMessage;
   }
 
   /**
@@ -237,21 +322,43 @@ public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
   }
 
   /**
-   * Flag indicating that this component will prohibit changes by the user.
+   * The component identifier for the input field component inside of the container.
+   * This value must be unique within the closest parent component that is a naming container.
+   */
+  @TagAttribute(rtexprvalue = true)
+  @UIComponentTagAttribute
+  public void setFieldId(final String fieldId) {
+    this.fieldId = fieldId;
+  }
+
+  /**
+   * Flag indicating this component should receive the focus.
    */
   @TagAttribute
   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
-  public void setReadonly(final ValueExpression readonly) {
-    this.readonly = readonly;
+  public void setFocus(final ValueExpression focus) {
+    this.focus = focus;
   }
 
   /**
-   * Clientside script function to add to this component's onchange handler.
+   * Hide the dropdown, this is only useful with allowCustom=true
    */
-  @TagAttribute
-  @UIComponentTagAttribute()
-  public void setOnchange(final ValueExpression onchange) {
-    this.onchange = onchange;
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
+  public void setHideDropdown(ValueExpression hideDropdown) {
+    this.hideDropdown = hideDropdown;
+  }
+
+  /**
+   * The component identifier for this component.
+   * This value must be unique within the closest parent component that is a naming container.
+   * For tx components the id will be set to the container (e. g. the panel).
+   * To set the id of the input field, you have to use the attribute "fieldId".
+   */
+  @TagAttribute(rtexprvalue = true)
+  @UIComponentTagAttribute
+  public void setId(final String id) {
+    super.setId(id);
   }
 
   /**
@@ -265,92 +372,130 @@ public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
   }
 
   /**
-   * The accessKey of this component.
+   * The width for the label component. Default: 'auto'.
+   * This value is used in the gridLayouts columns attribute.
+   * See gridLayout tag for valid values.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Character")
-  public void setAccessKey(final ValueExpression accessKey) {
-    this.accessKey = accessKey;
+  @UIComponentTagAttribute()
+  public void setLabelWidth(final ValueExpression labelWidth) {
+    this.labelWidth = labelWidth;
   }
 
   /**
-   * A method binding EL expression,
-   * accepting FacesContext, UIComponent,
-   * and Object parameters, and returning void, that validates
-   * the component's local value.
+   * Indicate markup of this component.
+   * Possible value is 'none'. But this can be overridden in the theme.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = {},
-      expression = DynamicExpression.METHOD_EXPRESSION,
-      methodSignature = { "javax.faces.context.FacesContext", "javax.faces.component.UIComponent", "java.lang.Object" })
-  public void setValidator(final MethodExpression validator) {
-    this.validator = validator;
+  @UIComponentTagAttribute(defaultValue = "none", type = "java.lang.String[]")
+  public void setMarkup(final ValueExpression markup) {
+    this.markup = markup;
   }
 
   /**
-   * An expression that specifies the Converter for this component.
-   * If the value binding expression is a String,
-   * the String is used as an ID to look up a Converter.
-   * If the value binding expression is a Converter,
-   * uses that instance as the converter.
-   * The value can either be a static value (ID case only)
-   * or an EL expression.
+   * Javascript callback to handle custom search matching
+   *
+   * This is a select2 feature and will force select2=true
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(generate = false)
+  public void setMatcher(ValueExpression matcher) {
+    this.matcher = matcher;
+  }
+
+  /**
+   * Maximum number of characters that may be provided for a search term.
+   *
+   * This is a select2 feature and will force select2=true
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  public void setMaximumInputLength(ValueExpression maximumInputLength) {
+    this.maximumInputLength = maximumInputLength;
+  }
+
+  /**
+   * The maximum number of items that may be selected in a multi-select control.
+   * If the value of this option is less than 1, the number of selected items will not be limited.
+   *
+   * This is a select2 feature and will force select2=true
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  public void setMaximumSelectionLength(ValueExpression maximumSelectionLength) {
+    this.maximumSelectionLength = maximumSelectionLength;
+  }
+
+  /**
+   * Minimum number of characters required to start a search.
+   *
+   * This is a select2 feature and will force select2=true
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  public void setMinimumInputLength(ValueExpression minimumInputLength) {
+    this.minimumInputLength = minimumInputLength;
+  }
+
+  /**
+   * Clientside script function to add to this component's onchange handler.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "javax.faces.convert.Converter",
-      expression = DynamicExpression.VALUE_EXPRESSION)
-  public void setConverter(final ValueExpression converter) {
-    this.converter = converter;
+  @UIComponentTagAttribute()
+  public void setOnchange(final ValueExpression onchange) {
+    this.onchange = onchange;
   }
 
   /**
-   * Flag indicating whether or not this component should be rendered
-   * (during Render Response Phase), or processed on any subsequent form submit.
+   * Displays a short text in the input field, that describes the meaning of this field.
+   * This is part of HTML 5, the theme should emulate the behaviour, when the browser doesn't support it.
+   * <p/>
+   * The text will not be displayed, when the input field is readonly or disabled.
+   * @param placeholder The text to display
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "boolean", defaultValue = "true")
-  public void setRendered(final ValueExpression rendered) {
-    this.rendered = rendered;
+  @UIComponentTagAttribute
+  public void setPlaceholder(ValueExpression placeholder) {
+    this.placeholder = placeholder;
   }
 
   /**
-   * The value binding expression linking this
-   * component to a property in a backing bean.
+   * Flag indicating that this component will prohibit changes by the user.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "javax.faces.component.UIComponent")
-  public void setBinding(final ValueExpression binding) {
-    this.binding = binding;
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
+  public void setReadonly(final ValueExpression readonly) {
+    this.readonly = readonly;
   }
 
   /**
-   * Text value to display as tooltip.
+   * Flag indicating whether or not this component should be rendered
+   * (during Render Response Phase), or processed on any subsequent form submit.
    */
   @TagAttribute
-  @UIComponentTagAttribute()
-  public void setTip(final ValueExpression tip) {
-    this.tip = tip;
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "true")
+  public void setRendered(final ValueExpression rendered) {
+    this.rendered = rendered;
   }
 
   /**
-   * The width for the label component. Default: 'auto'.
-   * This value is used in the gridLayouts columns attribute.
-   * See gridLayout tag for valid values.
+   * Flag indicating that a value is required.
+   * If the value is an empty string a
+   * ValidationError occurs and a Error Message is rendered.
    */
   @TagAttribute
-  @UIComponentTagAttribute()
-  public void setLabelWidth(final ValueExpression labelWidth) {
-    this.labelWidth = labelWidth;
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
+  public void setRequired(final ValueExpression required) {
+    this.required = required;
   }
 
   /**
-   * Indicate markup of this component.
-   * Possible value is 'none'. But this can be overridden in the theme.
+   * An expression that specifies the required message
    */
   @TagAttribute
-  @UIComponentTagAttribute(defaultValue = "none", type = "java.lang.String[]")
-  public void setMarkup(final ValueExpression markup) {
-    this.markup = markup;
+  @UIComponentTagAttribute()
+  public void setRequiredMessage(final ValueExpression requiredMessage) {
+    this.requiredMessage = requiredMessage;
   }
 
   @TagAttribute
@@ -360,60 +505,78 @@ public class SelectManyBoxExtensionTag extends TobagoExtensionBodyTagSupport {
   }
 
   /**
-   * Flag indicating this component should receive the focus.
+   * Text value to display as tooltip.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
-  public void setFocus(final ValueExpression focus) {
-    this.focus = focus;
+  @UIComponentTagAttribute()
+  public void setTip(final ValueExpression tip) {
+    this.tip = tip;
   }
 
   /**
-   * An expression that specifies the validator message
+   * A javascript callback that handles automatic tokenization of free-text entry.
    */
-  @TagAttribute
-  @UIComponentTagAttribute()
-  public void setValidatorMessage(final ValueExpression validatorMessage) {
-    this.validatorMessage = validatorMessage;
+  @TagAttribute()
+  @UIComponentTagAttribute(generate = false)
+  public void setTokenizer(ValueExpression tokenizer) {
+    this.tokenizer = tokenizer;
   }
 
   /**
-   * An expression that specifies the converter message
+   * The list of characters that should be used as token separators.
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "java.lang.String[]", generate = false)
+  public void setTokenSeparators(ValueExpression tokenSeparators) {
+    this.tokenSeparators = tokenSeparators;
+  }
+
+  /**
+   * A method binding EL expression,
+   * accepting FacesContext, UIComponent,
+   * and Object parameters, and returning void, that validates
+   * the component's local value.
    */
   @TagAttribute
-  @UIComponentTagAttribute()
-  public void setConverterMessage(final ValueExpression converterMessage) {
-    this.converterMessage = converterMessage;
+  @UIComponentTagAttribute(type = {},
+      expression = DynamicExpression.METHOD_EXPRESSION,
+      methodSignature = { "javax.faces.context.FacesContext", "javax.faces.component.UIComponent", "java.lang.Object" })
+  public void setValidator(final MethodExpression validator) {
+    this.validator = validator;
   }
 
   /**
-   * An expression that specifies the required message
+   * An expression that specifies the validator message
    */
   @TagAttribute
   @UIComponentTagAttribute()
-  public void setRequiredMessage(final ValueExpression requiredMessage) {
-    this.requiredMessage = requiredMessage;
+  public void setValidatorMessage(final ValueExpression validatorMessage) {
+    this.validatorMessage = validatorMessage;
   }
-  
+
   /**
-   * The component identifier for the input field component inside of the container.
-   * This value must be unique within the closest parent component that is a naming container.
+   * The current value of this component.
    */
-  @TagAttribute(rtexprvalue = true)
-  @UIComponentTagAttribute
-  public void setFieldId(final String fieldId) {
-    this.fieldId = fieldId;
+  @TagAttribute
+  @UIComponentTagAttribute(type = {"java.lang.Object[]", "java.util.List"})
+  public void setValue(final ValueExpression value) {
+    this.value = value;
   }
 
   /**
-   * The component identifier for this component.
-   * This value must be unique within the closest parent component that is a naming container.
-   * For tx components the id will be set to the container (e. g. the panel).
-   * To set the id of the input field, you have to use the attribute "fieldId".
+   * MethodBinding representing a value change listener method
+   * that will be notified when a new value has been set for this input component.
+   * The expression must evaluate to a public method that takes a ValueChangeEvent
+   * parameter, with a return type of void.
+   *
+   * @param valueChangeListener
    */
-  @TagAttribute(rtexprvalue = true)
-  @UIComponentTagAttribute
-  public void setId(final String id) {
-    super.setId(id);
+  @TagAttribute
+  @UIComponentTagAttribute(
+      type = {},
+      expression = DynamicExpression.METHOD_EXPRESSION_REQUIRED,
+      methodSignature = "javax.faces.event.ValueChangeEvent")
+  public void setValueChangeListener(final MethodExpression valueChangeListener) {
+    this.valueChangeListener = valueChangeListener;
   }
 }