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/09/09 06:47:57 UTC

[myfaces-tobago] 03/03: Tobago-1999: testing: tokenizer, events

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 88bacade04da386a828aab82df28a2e0972a7119
Author: Volker Weber <v....@inexso.de>
AuthorDate: Tue Sep 3 18:50:22 2019 +0200

    Tobago-1999: testing: tokenizer, events
---
 .../myfaces/tobago/facelets/SelectManyBoxRule.java | 49 ++++++++++++++++++++++
 .../tobago/facelets/TobagoComponentHandler.java    |  4 ++
 .../component/AbstractUISelectManyBox.java         | 23 +++++++---
 .../component/SelectManyBoxTagDeclaration.java     |  2 +-
 .../content/25-select/00-select2/select2.xhtml     | 17 ++++++++
 .../src/main/webapp/script/demo.js                 | 39 +++++++++++++++++
 .../tobago/renderkit/html/Select2Options.java      | 22 ++++++++++
 .../standard/standard/script/tobago-select2.js     | 47 ++++++++++++++++++---
 8 files changed, 192 insertions(+), 11 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
new file mode 100644
index 0000000..0e413a3
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/SelectManyBoxRule.java
@@ -0,0 +1,49 @@
+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;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.MetaRule;
+import javax.faces.view.facelets.Metadata;
+import javax.faces.view.facelets.MetadataTarget;
+import javax.faces.view.facelets.TagAttribute;
+
+public class SelectManyBoxRule extends MetaRule {
+
+  public static final String TOKEN_SEPARATORS = "tokenSeparators";
+
+  public static final SelectManyBoxRule INSTANCE = new SelectManyBoxRule();
+
+  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 null;
+  }
+
+  static final class SelectManyBoxMapper extends Metadata {
+
+    private final TagAttribute attribute;
+
+    public SelectManyBoxMapper(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);
+      } 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/TobagoComponentHandler.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
index 741501c..0848243 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
@@ -32,6 +32,7 @@ import org.apache.myfaces.tobago.event.TabChangeSource;
 import org.apache.myfaces.tobago.internal.component.AbstractUIFlowLayout;
 import org.apache.myfaces.tobago.internal.component.AbstractUIGridLayout;
 import org.apache.myfaces.tobago.internal.component.AbstractUIPopup;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBox;
 import org.apache.myfaces.tobago.internal.config.TobagoConfigImpl;
 
 import javax.faces.component.EditableValueHolder;
@@ -85,6 +86,9 @@ public class TobagoComponentHandler extends ComponentHandler {
     if (SupportsRenderedPartially.class.isAssignableFrom(aClass)) {
       metaRuleset.addRule(SupportsRenderedPartiallyRule.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 21b7c9a..56c657d 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
@@ -8,6 +8,9 @@ package org.apache.myfaces.tobago.internal.component;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice.Select2Keys;
 
 import javax.faces.context.FacesContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
 
 public abstract class AbstractUISelectManyBox extends AbstractUISelectMany {
 
@@ -154,19 +157,29 @@ public abstract class AbstractUISelectManyBox extends AbstractUISelectMany {
     getStateHelper().put(Select2Keys.tokenizer, tokenizer);
   }
 
-  public String getTokenSeparators() {
-    String tokenSeparators = (String) getStateHelper().eval(Select2Keys.tokenSeparators);
-    if (tokenSeparators != null) {
-      return tokenSeparators;
+  public String[] getTokenSeparators() {
+    Object tokenSeparators = getStateHelper().eval(Select2Keys.tokenSeparators);
+    if (tokenSeparators instanceof String[]) {
+      return  (String[]) tokenSeparators;
+    } else if (tokenSeparators instanceof String) {
+      return parseTokenSeparators((String) tokenSeparators);
     }
     return null;
   }
 
+  public static String[] parseTokenSeparators(String tokenSeparators) {
+    Set<String> tokens = new HashSet<String>();
+    for (int i = 0; i < tokenSeparators.length(); i++) {
+      tokens.add(tokenSeparators.substring(i, i + 1));
+    }
+    return tokens.toArray(new String[0]);
+  }
+
   public boolean isTokenSeparatorsSet() {
     return getStateHelper().eval(Select2Keys.tokenSeparators) != null;
   }
 
-  public void setTokenSeparators(String tokenSeparators) {
+  public void setTokenSeparators(String[] tokenSeparators) {
     getStateHelper().put(Select2Keys.tokenSeparators, tokenSeparators);
   }
 
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 3ea22c0..4d8aef5 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
@@ -88,7 +88,7 @@ public interface SelectManyBoxTagDeclaration
    * The list of characters that should be used as token separators.
    */
   @TagAttribute()
-  @UIComponentTagAttribute(generate = false)
+  @UIComponentTagAttribute(type = "java.lang.String[]", generate = false)
   void setTokenSeparators(String tokenSeparators);
 
   /**
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/25-select/00-select2/select2.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/25-select/00-select2/select2.xhtml
index e728e3a..47746cb 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/25-select/00-select2/select2.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/25-select/00-select2/select2.xhtml
@@ -156,6 +156,23 @@
         </tc:selectManyBox>
 
       </tc:panel>
+      <tc:panel>
+        <f:facet name="layout">
+          <tc:gridLayout columns="400px;1*" rows="45px"/>
+        </f:facet>
+
+        <tc:label value="Tokenizer" for="many_5"/>
+        <tc:selectManyBox id="many_5"
+                          placeholder="tokenizer test"
+                          tokenSeparators=", -"
+                          allowCustom="true">
+          <!--tokenizer="TBG_DEMO.Select2.Tokenizer"-->
+          <f:facet name="select2:select">
+            <tc:command onclick="TBG_DEMO.Select2.doOnSelect;"/>
+          </f:facet>
+        </tc:selectManyBox>
+
+      </tc:panel>
     </tc:panel>
 
 
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/script/demo.js b/tobago-example/tobago-example-demo/src/main/webapp/script/demo.js
index bfa6653..5163424 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/script/demo.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/script/demo.js
@@ -34,3 +34,42 @@ var initAlert = function () {
 
 Tobago.registerListener(initAlert, Tobago.Phase.DOCUMENT_READY);
 Tobago.registerListener(initAlert, Tobago.Phase.AFTER_UPDATE);
+
+jQuery.fn.select2.amd.define("CustomTokenizerAdapter", [
+      "select2/utils",
+      "select2/data/tokenizer"
+    ],
+    function(Utils, Tokenizer) {
+      var emptyFunc = function (params) {
+
+      };
+      emptyFunc.tokenizer = function (params) {
+        var result = Tokenizer.prototype.tokenizer.call(this, params);
+        console.info("tokenizer result: " + result);
+        return result;
+      };
+     return function(params) {emptyFunc.tokenizer(params)};
+    });
+
+var TBG_DEMO = {
+  Select2: {
+    Tokenizer: function (params) {
+      console.info("params: " + params);
+      var tokenizer = jQuery.fn.select2.amd.require("Tokenizer");
+      var results = tokenizer.call(this, params);
+      console.info("results: " + results);
+      return results;
+    },
+
+    doOnSelect: function (event) {
+      var element = jQuery(this);
+      var data = element.select2("data");
+      var newData = event.params.data;
+      console.info("doOnSelect id     : " +  element.attr("id"));
+      console.info("doOnSelect tagName: " +  element.prop("tagName"));
+      console.info("doOnSelect newData: " +  newData);
+      console.info("doOnSelect data   : " +  data);
+      // console.info("doOnSelect : " +  element);
+    }
+  }
+};
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
index 2dfdc7e..09e5c18 100644
--- 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
@@ -129,6 +129,14 @@ public class Select2Options {
       options.setMaximumSelectionLength(select.getMaximumSelectionLength());
     }
 
+    if (select.isTokenizerSet()) {
+      options.setTokenizer(select.getTokenizer());
+    }
+
+    if (select.isTokenSeparatorsSet()) {
+      options.setTokenSeparators(select.getTokenSeparators());
+    }
+
     String placeholder = select.getPlaceholder();
     if (placeholder != null && placeholder.length() > 0) {
       options.setPlaceholder(placeholder);
@@ -159,6 +167,14 @@ public class Select2Options {
     this.tags = tags;
   }
 
+  public String getTokenizer() {
+    return tokenizer;
+  }
+
+  public void setTokenizer(String tokenizer) {
+    this.tokenizer = tokenizer;
+  }
+
   public String[] getTokenSeparators() {
     return tokenSeparators;
   }
@@ -247,9 +263,15 @@ public class Select2Options {
     if (tags != null) {
       JsonUtils.encode(builder, "tags", tags);
     }
+    if (tokenizer != null) {
+      JsonUtils.encode(builder, "tokenizer", tokenizer);
+    }
     if (tokenSeparators != null) {
       JsonUtils.encode(builder, "tokenSeparators", tokenSeparators);
     }
+    if (dropdownAutoWidth != null) {
+      JsonUtils.encode(builder, "dropdownAutoWidth", dropdownAutoWidth);
+    }
     if (allowClear != null) {
       JsonUtils.encode(builder, "allowClear", allowClear);
     }
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
index 82f23dd..6fb052b 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
@@ -18,18 +18,55 @@
 Tobago.Select2 = {
 
   init: function (elements) {
-    console.info("Tobago.Select2.init"); // @DEV_ONLY
+    console.info("Tobago.Select2.init");                                    // @DEV_ONLY
     Tobago.Utils.selectWithJQuery(elements, "[data-tobago-select2]")
         .each( function () {
           var element = jQuery(this);
           var options = element.data("tobago-select2");
-          console.info("typeof options: " + typeof options);
+          var extend = element.data("tobago-select2-extend");
+          var select2Options = jQuery.extend({}, options, extend);
 
           if (element.hasClass("tobago-selectManyBox")) {
-            options.containerCss = {height: element.data("tobago-style").height};
+            select2Options.containerCss = {height: element.data("tobago-style").height};
           }
-          console.info("Select2.init" + element.attr("id") + " with data: " + JSON.stringify(options)); // @DEV_ONLY
-          element.select2(options);
+          console.info("Select2.init" + element.attr("id") + " with data: " // @DEV_ONLY
+              + JSON.stringify(select2Options));                            // @DEV_ONLY
+          if (typeof select2Options.tokenizer === "string" && typeof eval(select2Options.tokenizer) === "function") {
+            console.info("select2Options.tokenizer: " + typeof select2Options.tokenizer);
+            console.info("select2Options.tokenizer: " + typeof eval(select2Options.tokenizer));
+            select2Options.tokenizer = eval(select2Options.tokenizer)
+          }
+          var commands = element.data("tobago-commands");
+
+          if (commands) {
+            for (var name in commands) {
+              if (name.indexOf("select2:") === 0) {
+                var command = commands[name];
+                var actionId = command.action;
+                if (command.script) {
+                  // not allowed with Content Security Policy (CSP)
+                  var func = eval(command.script);
+                  element.on("select2:select", func);
+                } else if (command.partially) {
+                  var partially = command.partially;
+                  element.on("select2:select", function () {
+                    if (actionId !== undefined) {
+                      console.info("select2:select reloadComponent(" + partially + ", " + actionId + ")");
+                      Tobago.reloadComponent(this, partially, actionId);
+                    }
+                  });
+                } else {
+                  var actionId = command.action;
+                  element.on("select2:select", function () {
+                    console.info("select2:select submitAction(" + actionId + ")");
+                    Tobago.submitAction(this, actionId);
+                  });
+                }
+              }
+            }
+
+          }
+          element.select2(select2Options);
         });
   }