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 2019/12/02 09:29:41 UTC

[myfaces-tobago] 04/19: Tobago-1999: select2Options

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 5984a76af56b784e1b023e6afa88f9e883d95939
Author: Volker Weber <v....@inexso.de>
AuthorDate: Tue Aug 20 18:13:00 2019 +0200

    Tobago-1999: select2Options
---
 .../component/AbstractUISelectManyBox.java         | 100 ++++++++
 .../component/AbstractUISelectOneBase.java         |  21 --
 .../component/AbstractUISelectOneChoice.java       | 106 ++++++++-
 .../component/SelectManyBoxTagDeclaration.java     |   6 +-
 .../component/SelectOneChoiceTagDeclaration.java   |   4 +-
 .../internal/taglib/declaration/Select2.java       |  34 +++
 .../{IsSelect2.java => Select2One.java}            |  11 +-
 .../myfaces/tobago/model/Select2Options.java       | 142 ------------
 .../myfaces/tobago/renderkit/html/JsonUtils.java   |   2 +-
 .../tobago/renderkit/html/Select2Options.java      | 251 +++++++++++++++++++++
 .../standard/tag/SelectOneChoiceRenderer.java      |  16 +-
 11 files changed, 511 insertions(+), 182 deletions(-)

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
new file mode 100644
index 0000000..6560cf8
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBox.java
@@ -0,0 +1,100 @@
+package org.apache.myfaces.tobago.internal.component;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice.Select2Keys;
+
+public abstract class AbstractUISelectManyBox extends AbstractUISelectMany {
+
+  public boolean isAllowClear() {
+    Boolean allowClear = (Boolean) getStateHelper().eval(Select2Keys.allowClear);
+    if (allowClear != null) {
+      return allowClear;
+    }
+    return false;
+  }
+  public boolean isAllowClearSet() {
+    return getStateHelper().eval(Select2Keys.allowClear) != null;
+  }
+
+  public void setAllowClear(Boolean allowClear) {
+    getStateHelper().put(Select2Keys.allowClear, allowClear);
+  }
+
+
+  public boolean isAllowCustom() {
+    Boolean allowCustom = (Boolean) getStateHelper().eval(Select2Keys.allowCustom);
+    if (allowCustom != null) {
+      return allowCustom;
+    }
+    return false;
+  }
+  public boolean isAllowCustomSet() {
+    return getStateHelper().eval(Select2Keys.allowCustom) != null;
+  }
+
+  public void setAllowCustom(Boolean allowCustom) {
+    getStateHelper().put(Select2Keys.allowCustom, allowCustom);
+  }
+
+  public int getMaximumInputLength() {
+    Integer maximumInputLength = (Integer) getStateHelper().eval(Select2Keys.maximumInputLength);
+    if (maximumInputLength != null) {
+      return maximumInputLength;
+    }
+    return 0;
+  }
+  public boolean isMaximumInputLengthSet() {
+    return getStateHelper().eval(Select2Keys.maximumInputLength) != null;
+  }
+
+  public void setMaximumInputLength(Integer minimumInputLength) {
+    getStateHelper().put(Select2Keys.maximumInputLength, minimumInputLength);
+  }
+
+  public int getMinimumInputLength() {
+    Integer minimumInputLength = (Integer) getStateHelper().eval(Select2Keys.minimumInputLength);
+    if (minimumInputLength != null) {
+      return minimumInputLength;
+    }
+    return 0;
+  }
+  public boolean isMinimumInputLengthSet() {
+    return getStateHelper().eval(Select2Keys.minimumInputLength) != null;
+  }
+
+  public void setMinimumInputLength(Integer minimumInputLength) {
+    getStateHelper().put(Select2Keys.minimumInputLength, minimumInputLength);
+  }
+
+  public int getMaximumSelectionLength() {
+    Integer maximumSelectionLength = (Integer) getStateHelper().eval(Select2Keys.maximumSelectionLength);
+    if (maximumSelectionLength != null) {
+      return maximumSelectionLength;
+    }
+    return 0;
+  }
+  public boolean isMaximumSelectionLengthSet() {
+    return getStateHelper().eval(Select2Keys.maximumSelectionLength) != null;
+  }
+
+  public void setMaximumSelectionLength(Integer maximumSelectionLength) {
+    getStateHelper().put(Select2Keys.maximumSelectionLength, maximumSelectionLength);
+  }
+
+  public void setMinimumResultsForSearch(int minimumResultsForSearch) {
+    getStateHelper().put(Select2Keys.minimumResultsForSearch, minimumResultsForSearch);
+  }
+
+  public int getMinimumResultsForSearch() {
+    Integer minimumResultsForSearch = (Integer) getStateHelper().eval(Select2Keys.minimumResultsForSearch);
+    if (minimumResultsForSearch != null) {
+      return minimumResultsForSearch;
+    }
+    return 20;
+  }
+
+  public boolean isMinimumResultsForSearchSet() {
+    return getStateHelper().eval(Select2Keys.minimumResultsForSearch) != null;
+  }
+
+
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
index 5d644cf..e2eae91 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
@@ -32,11 +32,6 @@ public abstract class AbstractUISelectOneBase extends javax.faces.component.UISe
 
   public static final String MESSAGE_VALUE_REQUIRED = "tobago.SelectOne.MESSAGE_VALUE_REQUIRED";
 
-  enum Select2Keys {
-    allowCustom,
-    isSelect2
-  }
-
   public void validate(final FacesContext facesContext) {
     if (isRequired()  && !isReadonly()) {
       final Object submittedValue = getSubmittedValue();
@@ -55,22 +50,6 @@ public abstract class AbstractUISelectOneBase extends javax.faces.component.UISe
     super.validate(facesContext);
   }
 
-  public boolean isAllowCustom() {
-    Boolean bool = (Boolean) getStateHelper().eval(Select2Keys.allowCustom);
-    if (bool != null) {
-      return bool;
-    }
-    return false;
-  }
-  public boolean isAllowCustomSet() {
-    return getStateHelper().eval(Select2Keys.allowCustom) != null;
-  }
-
-  public void setAllowCustom(Boolean bool) {
-    getStateHelper().put(Select2Keys.allowCustom, bool);
-  }
-
-
 
   public abstract boolean isReadonly();
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneChoice.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneChoice.java
index d42d95e..e032037 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneChoice.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneChoice.java
@@ -21,18 +21,112 @@ package org.apache.myfaces.tobago.internal.component;
 
 public abstract class AbstractUISelectOneChoice extends AbstractUISelectOneBase {
 
+  enum Select2Keys {
+    allowClear,
+    allowCustom,
+    isSelect2,
+    language,
+    matcher,
+    maximumInputLength,
+    minimumInputLength,
+    maximumSelectionLength,
+    minimumResultsForSearch
+  }
+
+
 
 
-  public boolean isSelect2() {
-    Boolean bool = (Boolean) getStateHelper().eval(Select2Keys.isSelect2);
-    if (bool != null) {
-      return bool;
+
+  public boolean isAllowClear() {
+    Boolean allowClear = (Boolean) getStateHelper().eval(Select2Keys.allowClear);
+    if (allowClear != null) {
+      return allowClear;
     }
     return false;
   }
+  public boolean isAllowClearSet() {
+    return getStateHelper().eval(Select2Keys.allowClear) != null;
+  }
+
+  public void setAllowClear(Boolean allowClear) {
+    getStateHelper().put(Select2Keys.allowClear, allowClear);
+  }
+
+
+  public boolean isAllowCustom() {
+    Boolean allowCustom = (Boolean) getStateHelper().eval(Select2Keys.allowCustom);
+    if (allowCustom != null) {
+      return allowCustom;
+    }
+    return false;
+  }
+  public boolean isAllowCustomSet() {
+    return getStateHelper().eval(Select2Keys.allowCustom) != null;
+  }
+
+  public void setAllowCustom(Boolean allowCustom) {
+    getStateHelper().put(Select2Keys.allowCustom, allowCustom);
+  }
+
+  public int getMaximumInputLength() {
+    Integer maximumInputLength = (Integer) getStateHelper().eval(Select2Keys.maximumInputLength);
+    if (maximumInputLength != null) {
+      return maximumInputLength;
+    }
+    return 0;
+  }
+  public boolean isMaximumInputLengthSet() {
+    return getStateHelper().eval(Select2Keys.maximumInputLength) != null;
+  }
+
+  public void setMaximumInputLength(Integer minimumInputLength) {
+    getStateHelper().put(Select2Keys.maximumInputLength, minimumInputLength);
+  }
+
+  public int getMinimumInputLength() {
+    Integer minimumInputLength = (Integer) getStateHelper().eval(Select2Keys.minimumInputLength);
+    if (minimumInputLength != null) {
+      return minimumInputLength;
+    }
+    return 0;
+  }
+  public boolean isMinimumInputLengthSet() {
+    return getStateHelper().eval(Select2Keys.minimumInputLength) != null;
+  }
+
+  public void setMinimumInputLength(Integer minimumInputLength) {
+    getStateHelper().put(Select2Keys.minimumInputLength, minimumInputLength);
+  }
+
+  public int getMaximumSelectionLength() {
+    Integer maximumSelectionLength = (Integer) getStateHelper().eval(Select2Keys.maximumSelectionLength);
+    if (maximumSelectionLength != null) {
+      return maximumSelectionLength;
+    }
+    return 0;
+  }
+  public boolean isMaximumSelectionLengthSet() {
+    return getStateHelper().eval(Select2Keys.maximumSelectionLength) != null;
+  }
+
+  public void setMaximumSelectionLength(Integer maximumSelectionLength) {
+    getStateHelper().put(Select2Keys.maximumSelectionLength, maximumSelectionLength);
+  }
+
+  public void setMinimumResultsForSearch(int minimumResultsForSearch) {
+    getStateHelper().put(Select2Keys.minimumResultsForSearch, minimumResultsForSearch);
+  }
+
+  public int getMinimumResultsForSearch() {
+    Integer minimumResultsForSearch = (Integer) getStateHelper().eval(Select2Keys.minimumResultsForSearch);
+    if (minimumResultsForSearch != null) {
+      return minimumResultsForSearch;
+    }
+    return 20;
+  }
 
-  public void setSelect2(boolean bool) {
-    getStateHelper().put(Select2Keys.isSelect2, bool);
+  public boolean isMinimumResultsForSearchSet() {
+    return getStateHelper().eval(Select2Keys.minimumResultsForSearch) != null;
   }
 
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyBoxTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyBoxTagDeclaration.java
index 7dacfdd..9942487 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyBoxTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyBoxTagDeclaration.java
@@ -44,6 +44,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.IsGridLayoutCompone
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsRequiredForSelect;
+import org.apache.myfaces.tobago.internal.taglib.declaration.Select2;
 
 import javax.faces.component.UISelectMany;
 
@@ -53,7 +54,7 @@ import javax.faces.component.UISelectMany;
 @Tag(name = "selectManyBox")
 @UIComponentTag(
     uiComponent = "org.apache.myfaces.tobago.component.UISelectManyBox",
-    uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUISelectMany",
+    uiComponentBaseClass = "org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBox",
     uiComponentFacesClass = "javax.faces.component.UISelectMany",
     componentFamily = UISelectMany.COMPONENT_FAMILY,
     rendererType = RendererTypes.SELECT_MANY_BOX,
@@ -63,7 +64,8 @@ public interface SelectManyBoxTagDeclaration
     extends HasId, IsDisabled, IsRendered, HasBinding, HasTip,
     IsReadonly, HasConverter, IsRequiredForSelect, HasMarkup, HasCurrentMarkup,
     HasLabel, HasValidator, HasOnchange, HasValueChangeListener,
-    HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsGridLayoutComponent {
+    HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsGridLayoutComponent,
+    Select2 {
 
   /**
    * The value of the multi select.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
index 14b356e..0b9f90a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
@@ -35,7 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsRendered;
-import org.apache.myfaces.tobago.internal.taglib.declaration.IsSelect2;
+import org.apache.myfaces.tobago.internal.taglib.declaration.Select2One;
 import org.apache.myfaces.tobago.internal.taglib.declaration.Select2;
 
 import javax.faces.component.UISelectOne;
@@ -67,7 +67,7 @@ import javax.faces.component.UISelectOne;
         })
 public interface SelectOneChoiceTagDeclaration
     extends SelectOneTagDeclaration, HasId, IsDisabled,
-            IsReadonly, HasLabel, IsRendered, HasConverter, HasBinding, HasTip, IsSelect2, Select2 {
+            IsReadonly, HasLabel, IsRendered, HasConverter, HasBinding, HasTip, Select2One, Select2 {
 
   /**
    * Flag indicating that selecting an Item representing a value is required.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2.java
index 2682d89..adbc3bd 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2.java
@@ -4,6 +4,14 @@ import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 
 public interface Select2 {
+
+  /**
+   * Flag indicating that this select
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
+  void setAllowClear(String allowed);
+
   /**
    * Flag indicating that this select accepts values which are not in option list.
    */
@@ -11,6 +19,32 @@ public interface Select2 {
   @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
   void setAllowCustom(String allowed);
 
+//  /**
+//   * Flag indicating that this select
+//   */
+//  @TagAttribute()
+//  @UIComponentTagAttribute(type = "string", generate = false)
+//  void setMatcher(String allowed);
 
+  /**
+   * Flag indicating that this select
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  void setMaximumInputLength(String allowed);
+
+  /**
+   * Flag indicating that this select
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  void setMinimumInputLength(String allowed);
+
+  /**
+   * Flag indicating that this select
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "0", generate = false)
+  void setMaximumSelectionLength(String allowed);
 
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsSelect2.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2One.java
similarity index 60%
rename from tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsSelect2.java
rename to tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2One.java
index fe96574..569a253 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsSelect2.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/Select2One.java
@@ -3,11 +3,18 @@ package org.apache.myfaces.tobago.internal.taglib.declaration;
 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 
-public interface IsSelect2 {
+public interface Select2One {
   /**
    * Flag indicating that this element is rendered as select2.
    */
   @TagAttribute()
-  @UIComponentTagAttribute(type = "boolean", defaultValue = "false", generate = false)
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setSelect2(String disabled);
+
+  /**
+   * Flag indicating that this element is rendered as select2.
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "int", defaultValue = "20", generate = false)
+  void setMinimumResultsForSearch(String disabled);
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Select2Options.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Select2Options.java
deleted file mode 100644
index 072438d..0000000
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Select2Options.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.myfaces.tobago.model;
-
-
-import org.apache.myfaces.tobago.component.UISelectOneChoice;
-
-public class Select2Options {
-
-  private Boolean tags;
-  private String[] tokenSeparators;
-  private Boolean allowClear;
-  private String language;
-  private String matcher;
-  private Integer maximumInputLength;
-  private Integer minimumInputLength;
-  private Integer maximumSelectionLength;
-  private Integer minimumResultsForSearch;
-  private String placeholder;
-
-  public static Select2Options of(UISelectOneChoice select) {
-    boolean renderSelect2 = select.isSelect2();
-    Select2Options options = new Select2Options();
-    if (select.isAllowCustomSet()) {
-      options.setTags(select.isAllowCustom());
-    }
-    if (renderSelect2 || options.hasAnyOption()) {
-      return options;
-    } else {
-      return null;
-    }
-  }
-
-  private boolean hasAnyOption() {
-    return tags != null
-           || tokenSeparators != null
-           || allowClear != null
-           || matcher != null
-           || maximumInputLength != null
-           || minimumInputLength != null
-           || maximumSelectionLength != null
-           || minimumResultsForSearch != null
-           || placeholder != null;
-  }
-
-  public boolean isTags() {
-    return tags;
-  }
-
-  public void setTags(boolean tags) {
-    this.tags = tags;
-  }
-
-  public String[] getTokenSeparators() {
-    return tokenSeparators;
-  }
-
-  public void setTokenSeparators(String[] tokenSeparators) {
-    this.tokenSeparators = tokenSeparators;
-  }
-
-  public boolean isAllowClear() {
-    return allowClear;
-  }
-
-  public void setAllowClear(boolean allowClear) {
-    this.allowClear = allowClear;
-  }
-
-  public String getLanguage() {
-    return language;
-  }
-
-  public void setLanguage(String language) {
-    this.language = language;
-  }
-
-  public String getMatcher() {
-    return matcher;
-  }
-
-  public void setMatcher(String matcher) {
-    this.matcher = matcher;
-  }
-
-  public int getMaximumInputLength() {
-    return maximumInputLength;
-  }
-
-  public void setMaximumInputLength(int maximumInputLength) {
-    this.maximumInputLength = maximumInputLength;
-  }
-
-  public int getMinimumInputLength() {
-    return minimumInputLength;
-  }
-
-  public void setMinimumInputLength(int minimumInputLength) {
-    this.minimumInputLength = minimumInputLength;
-  }
-
-  public int getMaximumSelectionLength() {
-    return maximumSelectionLength;
-  }
-
-  public void setMaximumSelectionLength(int maximumSelectionLength) {
-    this.maximumSelectionLength = maximumSelectionLength;
-  }
-
-  public int getMinimumResultsForSearch() {
-    return minimumResultsForSearch;
-  }
-
-  public void setMinimumResultsForSearch(int minimumResultsForSearch) {
-    this.minimumResultsForSearch = minimumResultsForSearch;
-  }
-
-  public String getPlaceholder() {
-    return placeholder;
-  }
-
-  public void setPlaceholder(String placeholder) {
-    this.placeholder = placeholder;
-  }
-}
diff --git a/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/JsonUtils.java b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/JsonUtils.java
index 031d611..7bbe028 100644
--- a/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/JsonUtils.java
+++ b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/JsonUtils.java
@@ -28,7 +28,7 @@ public class JsonUtils {
   private JsonUtils() {
   }
 
-  private static void encode(final StringBuilder builder, final String name, final String[] value) {
+  public static void encode(final StringBuilder builder, final String name, final String[] value) {
     builder.append("\"");
     builder.append(name);
     builder.append("\":");
diff --git a/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/Select2Options.java b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/Select2Options.java
new file mode 100644
index 0000000..fabc3d8
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/Select2Options.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.renderkit.html;
+
+
+import org.apache.myfaces.tobago.component.UISelectManyBox;
+import org.apache.myfaces.tobago.component.UISelectOneChoice;
+
+import javax.faces.context.FacesContext;
+
+public class Select2Options {
+
+  private Boolean tags;
+  private String[] tokenSeparators;
+  private Boolean allowClear;
+  private String language;
+  private String matcher;
+  private Integer maximumInputLength;
+  private Integer minimumInputLength;
+  private Integer maximumSelectionLength;
+  private Integer minimumResultsForSearch;
+  private boolean minimumResultsForSearchSet;
+  private String placeholder;
+  private boolean renderSelect2;
+
+  public static Select2Options of(UISelectOneChoice select) {
+    Select2Options options = new Select2Options();
+    options.renderSelect2 = select.isSelect2();
+
+    if (select.isMinimumResultsForSearchSet()) {
+      options.setMinimumResultsForSearch(select.getMinimumResultsForSearch());
+    }
+
+    if (select.isAllowCustomSet()) {
+      options.setTags(select.isAllowCustom());
+    }
+
+    if (select.isAllowClearSet()) {
+      options.setAllowClear(select.isAllowClear());
+    }
+
+    FacesContext facesContext = FacesContext.getCurrentInstance();
+    if (facesContext != null) {
+      options.setLanguage(facesContext.getViewRoot().getLocale().getLanguage());
+    }
+
+    if (select.isMaximumInputLengthSet()) {
+      options.setMaximumInputLength(select.getMaximumInputLength());
+    }
+
+    if (select.isMinimumInputLengthSet()) {
+      options.setMinimumInputLength(select.getMinimumInputLength());
+    }
+
+    if (select.isMaximumSelectionLengthSet()) {
+      options.setMaximumSelectionLength(select.getMaximumSelectionLength());
+    }
+
+    return options;
+  }
+
+  public static Select2Options of(UISelectManyBox select) {
+    Select2Options options = new Select2Options();
+
+    if (select.isMinimumResultsForSearchSet()) {
+      options.setMinimumResultsForSearch(select.getMinimumResultsForSearch());
+    }
+
+    if (select.isAllowCustomSet()) {
+      options.setTags(select.isAllowCustom());
+    }
+
+    if (select.isAllowClearSet()) {
+      options.setAllowClear(select.isAllowClear());
+    }
+
+    FacesContext facesContext = FacesContext.getCurrentInstance();
+    if (facesContext != null) {
+      options.setLanguage(facesContext.getViewRoot().getLocale().getLanguage());
+    }
+
+    if (select.isMaximumInputLengthSet()) {
+      options.setMaximumInputLength(select.getMaximumInputLength());
+    }
+
+    if (select.isMinimumInputLengthSet()) {
+      options.setMinimumInputLength(select.getMinimumInputLength());
+    }
+
+    if (select.isMaximumSelectionLengthSet()) {
+      options.setMaximumSelectionLength(select.getMaximumSelectionLength());
+    }
+
+    return options;
+  }
+
+  public boolean hasAnyOption() {
+    return renderSelect2
+        || tags != null
+        || tokenSeparators != null
+        || allowClear != null
+        || matcher != null
+        || maximumInputLength != null
+        || minimumInputLength != null
+        || maximumSelectionLength != null
+        || minimumResultsForSearchSet
+        || placeholder != null;
+  }
+
+  public Boolean isTags() {
+    return tags;
+  }
+
+  public void setTags(Boolean tags) {
+    this.tags = tags;
+  }
+
+  public String[] getTokenSeparators() {
+    return tokenSeparators;
+  }
+
+  public void setTokenSeparators(String[] tokenSeparators) {
+    this.tokenSeparators = tokenSeparators;
+  }
+
+  public Boolean isAllowClear() {
+    return allowClear;
+  }
+
+  public void setAllowClear(Boolean allowClear) {
+    this.allowClear = allowClear;
+  }
+
+  public String getLanguage() {
+    return language;
+  }
+
+  public void setLanguage(String language) {
+    this.language = language;
+  }
+
+  public String getMatcher() {
+    return matcher;
+  }
+
+  public void setMatcher(String matcher) {
+    this.matcher = matcher;
+  }
+
+  public Integer getMaximumInputLength() {
+    return maximumInputLength;
+  }
+
+  public void setMaximumInputLength(Integer maximumInputLength) {
+    this.maximumInputLength = maximumInputLength;
+  }
+
+  public Integer getMinimumInputLength() {
+    return minimumInputLength;
+  }
+
+  public void setMinimumInputLength(Integer minimumInputLength) {
+    this.minimumInputLength = minimumInputLength;
+  }
+
+  public Integer getMaximumSelectionLength() {
+    return maximumSelectionLength;
+  }
+
+  public void setMaximumSelectionLength(Integer maximumSelectionLength) {
+    this.maximumSelectionLength = maximumSelectionLength;
+  }
+
+  public Integer getMinimumResultsForSearch() {
+    return minimumResultsForSearch;
+  }
+
+  public void setMinimumResultsForSearch(Integer minimumResultsForSearch) {
+    this.minimumResultsForSearch = minimumResultsForSearch;
+    minimumResultsForSearchSet = true;
+  }
+
+  public String getPlaceholder() {
+    return placeholder;
+  }
+
+  public void setPlaceholder(String placeholder) {
+    this.placeholder = placeholder;
+  }
+
+  public String toJson() {
+    final StringBuilder builder = new StringBuilder();
+    builder.append("{");
+
+    if (tags != null) {
+      JsonUtils.encode(builder, "tags", tags);
+    }
+    if (tokenSeparators != null) {
+      JsonUtils.encode(builder, "tokenSeparators", tokenSeparators);
+    }
+    if (allowClear != null) {
+      JsonUtils.encode(builder, "allowClear", allowClear);
+    }
+    if (language != null) {
+      JsonUtils.encode(builder, "language", language);
+    }
+    if (matcher != null) {
+      JsonUtils.encode(builder, "matcher", matcher);
+    }
+    if (maximumInputLength != null) {
+      JsonUtils.encode(builder, "maximumInputLength", maximumInputLength);
+    }
+    if (minimumInputLength != null) {
+      JsonUtils.encode(builder, "minimumInputLength", minimumInputLength);
+    }
+    if (maximumSelectionLength != null) {
+      JsonUtils.encode(builder, "maximumSelectionLength", maximumSelectionLength);
+    }
+    if (minimumResultsForSearch != null) {
+      JsonUtils.encode(builder, "minimumResultsForSearch", minimumResultsForSearch);
+    }
+    if (placeholder != null) {
+      JsonUtils.encode(builder, "placeholder", placeholder);
+    }
+
+
+    if (builder.length() > 0 && builder.charAt(builder.length() - 1) == ',') {
+      builder.deleteCharAt(builder.length() - 1);
+    }
+    builder.append("}");
+    return builder.toString();
+  }
+
+}
diff --git a/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneChoiceRenderer.java b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneChoiceRenderer.java
index 8727d30..6894df1 100644
--- a/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneChoiceRenderer.java
+++ b/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/SelectOneChoiceRenderer.java
@@ -21,12 +21,14 @@ package org.apache.myfaces.tobago.renderkit.html.standard.standard.tag;
 
 import org.apache.myfaces.tobago.component.UISelectOneChoice;
 import org.apache.myfaces.tobago.layout.Measure;
+import org.apache.myfaces.tobago.renderkit.html.Select2Options;
 import org.apache.myfaces.tobago.renderkit.HtmlUtils;
 import org.apache.myfaces.tobago.renderkit.SelectOneRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.renderkit.util.SelectItemUtils;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -57,17 +59,19 @@ public class SelectOneChoiceRenderer extends SelectOneRendererBase {
     final UISelectOneChoice select = (UISelectOneChoice) component;
     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
 
-    if (select.isSelect2()) {
-      ComponentUtils.putDataAttribute(select, "tobago-select2", "{}");
-    }
-
     final String id = select.getClientId(facesContext);
     final Iterable<SelectItem> items = SelectItemUtils.getItemIterator(facesContext, select);
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, select);
     final boolean disabled = !items.iterator().hasNext() || select.isDisabled() || select.isReadonly();
     final Style style = new Style(facesContext, select);
+    final Select2Options select2Options = Select2Options.of(select);
+    final boolean renderAsSelect2 = select2Options.hasAnyOption();
+
+    if (renderAsSelect2) {
+      String json = select2Options.toJson();
+      LOG.warn("Select2 json = \"{}\"", json);
+      ComponentUtils.putDataAttribute(select, "tobago-select2", json);
 
-    if (select.isSelect2()) {
       writer.startElement(HtmlElements.DIV, select);
       writer.writeStyleAttribute(style);
       style.setTop(Measure.ZERO);
@@ -100,7 +104,7 @@ public class SelectOneChoiceRenderer extends SelectOneRendererBase {
         facesContext);
 
     writer.endElement(HtmlElements.SELECT);
-    if (select.isSelect2()) {
+    if (renderAsSelect2) {
       writer.endElement(HtmlElements.DIV);
     }