Introducing <tobago-behavior> instead of data-tobago-command attribute.
Renaming command attribute "transition" to NOT "decoupled".
Tests: call events with .dispatchEvent(new Event(..., {bubbles: true}));

issue: TOBAGO-1633: TS refactoring
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
index 5acd280..2e6b5bc 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/CommandRendererBase.java
@@ -32,7 +32,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -95,8 +94,6 @@
         command.setOmit(true);
       }
 
-      writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, command)));
-
       if (label.getAccessKey() != null) {
         writer.writeAttribute(HtmlAttributes.ACCESSKEY, Character.toString(label.getAccessKey()), false);
         AccessKeyLogger.addAccessKey(facesContext, label.getAccessKey(), clientId);
@@ -136,6 +133,10 @@
       }
     }
 
+    if (!disabled) {
+      encodeBehavior(writer, facesContext, command);
+    }
+
     final String image = ComponentUtils.getStringAttribute(command, Attributes.image);
     HtmlRendererUtils.encodeIconOrImage(writer, image);
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingCommandRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingCommandRendererBase.java
index 2c3716c..f5e9144 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingCommandRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingCommandRendererBase.java
@@ -19,7 +19,6 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.slf4j.Logger;
@@ -53,7 +52,7 @@
       commandActivated(component);
     }
 
-    RenderUtils.decodeClientBehaviors(facesContext, component);
+    decodeClientBehaviors(facesContext, component);
 
   }
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingInputRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingInputRendererBase.java
index 8542a3f..c1e61a7 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingInputRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecodingInputRendererBase.java
@@ -20,7 +20,6 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.component.Attributes;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -61,7 +60,7 @@
       setSubmittedValue(facesContext, (EditableValueHolder) component, newValue);
     }
 
-    RenderUtils.decodeClientBehaviors(facesContext, component);
+    decodeClientBehaviors(facesContext, component);
   }
 
   protected void setSubmittedValue(
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
index e29695e..2ae1a24 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
@@ -23,9 +23,7 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUIFile;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.internal.util.HttpPartWrapper;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.PartUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -109,7 +107,7 @@
       LOG.warn("Unsupported request type: " + request.getClass().getName());
     }
 
-    RenderUtils.decodeClientBehaviors(facesContext, component);
+    decodeClientBehaviors(facesContext, component);
   }
 
   @Override
@@ -164,9 +162,10 @@
     if (title != null) {
       writer.writeAttribute(HtmlAttributes.TITLE, title, true);
     }
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, file)));
     writer.endElement(HtmlElements.INPUT);
 
+    encodeBehavior(writer, facesContext, file);
+
     writer.startElement(HtmlElements.LABEL);
     writer.writeClassAttribute(
         BootstrapClass.CUSTOM_FILE_LABEL,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
index 55a48e5..ab26bbc 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
@@ -29,7 +29,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -149,10 +148,10 @@
     HtmlRendererUtils.renderFocus(clientId, input.isFocus(), ComponentUtils.isError(input), facesContext, writer);
     writeAdditionalAttributes(facesContext, writer, input);
 
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, input)));
-
     writer.endElement(HtmlElements.INPUT);
 
+    encodeBehavior(writer, facesContext, input);
+
     encodeGroupAddon(facesContext, writer, after, true);
 
     if (after != null || before != null) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index ba1b9d0..bbb39aa 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -36,8 +36,6 @@
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.CookieUtils;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.ResponseUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.portlet.PortletUtils;
@@ -247,7 +245,7 @@
     writer.writeIdAttribute(clientId);
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, page);
 
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, page)));
+    encodeBehavior(writer, facesContext, page);
 
     writer.startElement(HtmlElements.FORM);
     writer.writeClassAttribute(spread);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
index e20b004..71f3f7d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PanelRenderer.java
@@ -23,8 +23,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUIPanel;
 import org.apache.myfaces.tobago.internal.component.AbstractUIReload;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.model.CollapseMode;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -68,11 +66,11 @@
       writer.writeAttribute(DataAttributes.RELOAD, reload.getFrequency());
     }
 
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, panel)));
-
     if (panel.getCollapsedMode() != CollapseMode.none) {
       encodeHidden(writer, clientId, collapsed);
     }
+
+    encodeBehavior(writer, facesContext, panel);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
index 470a1a7..cd53ee8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/ProgressRenderer.java
@@ -25,8 +25,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUIProgress;
 import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.StyleRenderUtils;
 import org.apache.myfaces.tobago.layout.Measure;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
@@ -79,7 +77,7 @@
     style.setWidth(new Measure(percent * 100, Measure.Unit.PERCENT));
     progress.getChildren().add(style);
 
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, progress)));
+    encodeBehavior(writer, facesContext, progress);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
index 7f542ff..8d2dd4c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanCheckboxRenderer.java
@@ -23,8 +23,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectBoolean;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
@@ -65,7 +63,7 @@
 
     input.setSubmittedValue("true".equals(newValue) ? "true" : "false");
 
-    RenderUtils.decodeClientBehaviors(facesContext, input);
+    decodeClientBehaviors(facesContext, input);
   }
 
   @Override
@@ -120,7 +118,6 @@
     writer.writeAttribute(HtmlAttributes.REQUIRED, select.isRequired());
     HtmlRendererUtils.renderFocus(clientId, select.isFocus(), ComponentUtils.isError(select), facesContext, writer);
     writer.writeAttribute(HtmlAttributes.TABINDEX, select.getTabIndex());
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
     writer.endElement(HtmlElements.INPUT);
 
     writer.startElement(HtmlElements.I);
@@ -139,8 +136,12 @@
   @Override
   protected void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectBoolean select = (AbstractUISelectBoolean) component;
+
     writer.endElement(HtmlElements.LABEL);
     writer.endElement(HtmlElements.DIV);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   protected CssItem[] getOuterCssItems(final FacesContext facesContext, final AbstractUISelectBoolean select) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
index 0fd47dc..ec960f3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyCheckboxRenderer.java
@@ -24,8 +24,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectReference;
 import org.apache.myfaces.tobago.internal.util.ArrayUtils;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -115,9 +113,10 @@
           first = false;
         }
         writer.writeAttribute(HtmlAttributes.TABINDEX, select.getTabIndex());
-        writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
         writer.endElement(HtmlElements.INPUT);
 
+        encodeBehavior(writer, facesContext, select);
+
         writer.startElement(HtmlElements.I);
         writer.writeClassAttribute(TobagoClass.INPUT_PSEUDO);
         writer.endElement(HtmlElements.I);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyListboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyListboxRenderer.java
index 78abbd5..70f4e89 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyListboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyListboxRenderer.java
@@ -22,8 +22,6 @@
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyListbox;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
@@ -80,7 +78,6 @@
     writer.writeAttribute(HtmlAttributes.MULTIPLE, true);
     writer.writeAttribute(HtmlAttributes.SIZE, size);
     writer.writeAttribute(HtmlAttributes.TITLE, title, true);
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
     final Object[] values = select.getSelectedValues();
     final String[] submittedValues = getSubmittedValues(select);
 
@@ -91,7 +88,11 @@
   @Override
   public void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectManyListbox select = (AbstractUISelectManyListbox) component;
+
     writer.endElement(HtmlElements.SELECT);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
index 7da4c41..6286208 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
@@ -21,7 +21,6 @@
 
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBase;
 import org.apache.myfaces.tobago.internal.util.ArrayUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,7 +85,7 @@
     }
     select.setSubmittedValue(newValues);
 
-    RenderUtils.decodeClientBehaviors(facesContext, select);
+    decodeClientBehaviors(facesContext, select);
   }
 
   public String[] getSubmittedValues(final UIInput input) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
index 786ea1e..563a070 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyShuttleRenderer.java
@@ -22,8 +22,6 @@
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyShuttle;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
@@ -142,7 +140,6 @@
     writer.writeNameAttribute(clientId);
     writer.writeAttribute(HtmlAttributes.MULTIPLE, true);
     writer.writeAttribute(HtmlAttributes.REQUIRED, select.isRequired());
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
     HtmlRendererUtils.renderSelectItems(select, TobagoClass.SELECT_MANY_SHUTTLE__OPTION, items, values, submittedValues,
         writer, facesContext);
     writer.endElement(HtmlElements.SELECT);
@@ -151,7 +148,10 @@
   @Override
   public void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectManyShuttle select = (AbstractUISelectManyShuttle) component;
     writer.endElement(HtmlElements.DIV);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   private void createButton(
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
index 1589fc6..779a4a5 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneChoiceRenderer.java
@@ -22,8 +22,6 @@
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
@@ -73,7 +71,6 @@
     if (title != null) {
       writer.writeAttribute(HtmlAttributes.TITLE, title, true);
     }
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
     HtmlRendererUtils.renderFocus(clientId, select.isFocus(), ComponentUtils.isError(select), facesContext, writer);
 
     HtmlRendererUtils.renderSelectItems(select, TobagoClass.SELECT_ONE_CHOICE__OPTION, items, select.getValue(),
@@ -83,7 +80,11 @@
   @Override
   protected void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectOneChoice select = (AbstractUISelectOneChoice) component;
+
     writer.endElement(HtmlElements.SELECT);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListboxRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListboxRenderer.java
index bf4fd08..0773f02 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListboxRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListboxRenderer.java
@@ -22,8 +22,6 @@
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneListbox;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
@@ -79,7 +77,6 @@
     final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, select);
     writer.writeAttribute(HtmlAttributes.TITLE, title, true);
     writer.writeAttribute(HtmlAttributes.SIZE, size);
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
     HtmlRendererUtils.renderSelectItems(select, TobagoClass.SELECT_ONE_LISTBOX__OPTION, items, select.getValue(),
         (String) select.getSubmittedValue(), writer, facesContext);
   }
@@ -87,7 +84,11 @@
   @Override
   protected void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectOneListbox select = (AbstractUISelectOneListbox) component;
+
     writer.endElement(HtmlElements.SELECT);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
index 330f417..9439269 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRadioRenderer.java
@@ -24,9 +24,7 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectReference;
 import org.apache.myfaces.tobago.internal.util.ArrayUtils;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.ObjectUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -117,7 +115,6 @@
           first = false;
         }
         writer.writeAttribute(HtmlAttributes.TABINDEX, select.getTabIndex());
-        writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, select)));
         writer.endElement(HtmlElements.INPUT);
 
         writer.startElement(HtmlElements.I);
@@ -159,7 +156,11 @@
   @Override
   protected void encodeEndField(final FacesContext facesContext, final UIComponent component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final AbstractUISelectOneRadio select = (AbstractUISelectOneRadio) component;
+
     writer.endElement(HtmlElements.DIV);
+
+    encodeBehavior(writer, facesContext, select);
   }
 
   protected boolean renderOuterItem() {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
index f0ef180..a77b1ee 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
@@ -20,7 +20,6 @@
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneBase;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,6 +48,6 @@
     }
     select.setSubmittedValue(newValue);
 
-    RenderUtils.decodeClientBehaviors(facesContext, select);
+    decodeClientBehaviors(facesContext, select);
   }
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
index 2f973cd..af165c7 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
@@ -56,7 +56,6 @@
 import org.apache.myfaces.tobago.renderkit.RendererBase;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
-import org.apache.myfaces.tobago.renderkit.css.CustomClass;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -274,9 +273,6 @@
     if (reload != null && reload.isRendered()) {
       writer.writeAttribute(DataAttributes.RELOAD, reload.getFrequency());
     }
-// todo    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, sheet)));
-    final CommandMap commands = RenderUtils.getBehaviorCommands(facesContext, sheet);
-    writer.writeAttribute(DataAttributes.BEHAVIOR_COMMANDS, JsonUtils.encode(commands), false);
     writer.writeAttribute(DataAttributes.SELECTION_MODE, sheet.getSelectable().name(), false);
     writer.writeAttribute(DataAttributes.FIRST, Integer.toString(sheet.getFirst()), false);
 
@@ -284,6 +280,8 @@
     if (!autoLayout) {
       writer.writeAttribute(DataAttributes.LAYOUT, JsonUtils.encode(sheet.getColumnLayout(), "columns"), true);
     }
+
+    encodeBehavior(writer, facesContext, sheet);
   }
 
   @Override
@@ -656,28 +654,26 @@
         writer.writeAttribute(DataAttributes.TREE_PARENT, parentId, false);
       }
 
-      // the row client id depends from the existence of an UIRow component! TBD: is this good?
-      String rowClientId = sheet.getRowClientId();
-      CustomClass rowClass = null;
+      AbstractUIRow row = null;
       for (final UIColumn column : columns) {
         if (column.isRendered()) {
           if (column instanceof AbstractUIRow) {
-            final AbstractUIRow row = (AbstractUIRow) column;
-            writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, row)));
-            rowClientId = row.getClientId(facesContext);
-            rowClass = row.getCustomClass();
+            row = (AbstractUIRow) column;
             // todo: Markup.CLICKABLE ???
           }
         }
       }
-      writer.writeIdAttribute(rowClientId);
+      // the row client id depends from the existence of an UIRow component! TBD: is this good?
+      writer.writeIdAttribute(row != null ? row.getClientId(facesContext): sheet.getRowClientId());
       writer.writeClassAttribute(
           TobagoClass.SHEET__ROW,
           TobagoClass.SHEET__ROW.createMarkup(rowMarkup),
           selected ? BootstrapClass.TABLE_INFO : null,
-          rowClass,
+          row != null ? row.getCustomClass() : null,
           sheet.isRowVisible() ? null : BootstrapClass.D_NONE);
 
+      encodeBehavior(writer, facesContext, row);
+
       for (final AbstractUIColumnBase column : columns) {
         if (column.isRendered()) {
           if (column instanceof AbstractUIColumn || column instanceof AbstractUIColumnSelector
@@ -906,6 +902,7 @@
             Markup markup = Markup.NULL;
             String tip = ComponentUtils.getStringAttribute(column, Attributes.tip);
             // sorter icons should only displayed when there is only 1 column and not input
+            CommandMap behaviorCommands = null;
             if (cell.getColumnSpan() == 1 && cellComponent instanceof AbstractUIOut) {
               final boolean sortable = ComponentUtils.getBooleanAttribute(column, Attributes.sortable);
               if (sortable) {
@@ -922,8 +919,7 @@
                   ComponentUtils.setFacet(column, Facets.sorter, sortCommand);
                 }
                 writer.writeIdAttribute(sortCommand.getClientId(facesContext));
-                writer.writeCommandMapAttribute(
-                    JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, sortCommand)));
+                behaviorCommands = getBehaviorCommands(facesContext, sortCommand);
                 ComponentUtils.removeFacet(column, Facets.sorter);
                 if (tip == null) {
                   tip = "";
@@ -944,9 +940,7 @@
                     sortTitle = ResourceUtils.getString(facesContext, "sheet.descending");
                     markup = markup.add(Markup.DESCENDING);
                   }
-                  if (sortTitle != null) {
-                    tip += " - " + sortTitle;
-                  }
+                  tip += " - " + sortTitle;
                 }
               }
             }
@@ -954,6 +948,8 @@
             writer.writeClassAttribute(TobagoClass.SHEET__HEADER, TobagoClass.SHEET__HEADER.createMarkup(markup));
             writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
 
+            encodeBehavior(writer, behaviorCommands);
+
             if (column instanceof AbstractUIColumnSelector && selectable.isMulti()) {
               writer.startElement(HtmlElements.INPUT);
               writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.CHECKBOX);
@@ -1083,9 +1079,6 @@
     writer.writeClassAttribute(BootstrapClass.PAGE_LINK);
     writer.writeIdAttribute(command.getClientId(facesContext));
     writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
-    if (!disabled) {
-      writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, command)));
-    }
     writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
     if (icon != null) {
       writer.startElement(HtmlElements.I);
@@ -1094,6 +1087,9 @@
     } else {
       writer.writeText(String.valueOf(target));
     }
+    if (!disabled) {
+      encodeBehavior(writer, facesContext, command);
+    }
     data.getFacets().remove(facet);
     writer.endElement(HtmlElements.BUTTON);
     writer.endElement(HtmlElements.LI);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
index 700a46b..7c127de 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
@@ -21,8 +21,6 @@
 
 import org.apache.myfaces.tobago.internal.component.AbstractUIStars;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
@@ -87,7 +85,6 @@
     writer.writeAttribute(HtmlAttributes.MIN, required ? 1 : 0);
     writer.writeAttribute(HtmlAttributes.MAX, max);
     writer.writeAttribute(HtmlAttributes.VALUE, sliderValue, true);
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, stars)));
     if (placeholder != null) {
       writer.writeAttribute(HtmlAttributes.PLACEHOLDER, placeholder.toString(), true);
     }
@@ -99,6 +96,8 @@
     writer.writeAttribute(HtmlAttributes.TITLE, title, true);
     writer.endElement(HtmlElements.INPUT);
 
+    encodeBehavior(writer, facesContext, stars);
+
     writer.startElement(HtmlElements.DIV);
     writer.writeClassAttribute(TobagoClass.STARS__FOCUS_BOX);
     writer.endElement(HtmlElements.DIV);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
index a37dfc3..407631d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
@@ -31,11 +31,8 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUIPanelBase;
 import org.apache.myfaces.tobago.internal.component.AbstractUITab;
 import org.apache.myfaces.tobago.internal.component.AbstractUITabGroup;
-import org.apache.myfaces.tobago.internal.renderkit.CommandMap;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.model.SwitchType;
 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
@@ -141,9 +138,7 @@
   public void encodeEnd(final FacesContext facesContext, final UIComponent uiComponent) throws IOException {
 
     final AbstractUITabGroup tabGroup = (AbstractUITabGroup) uiComponent;
-
     final int selectedIndex = ensureRenderedSelectedIndex(facesContext, tabGroup);
-
     final String clientId = tabGroup.getClientId(facesContext);
     final String hiddenId = clientId + TabGroupRenderer.INDEX_POSTFIX;
     final SwitchType switchType = tabGroup.getSwitchType();
@@ -160,6 +155,8 @@
     HtmlRendererUtils.writeDataAttributes(facesContext, writer, tabGroup);
     writer.writeAttribute(CustomAttributes.SWITCH_TYPE, switchType.name(), false);
 
+    encodeBehavior(writer, facesContext, tabGroup);
+
     writer.startElement(HtmlElements.INPUT);
     writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
     writer.writeAttribute(HtmlAttributes.VALUE, selectedIndex);
@@ -227,7 +224,6 @@
         BootstrapClass.NAV_TABS,
         BootstrapClass.CARD_HEADER_TABS);
     writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.TABLIST.toString(), false);
-    final CommandMap tabGroupMap = RenderUtils.getBehaviorCommands(facesContext, tabGroup);
 
     int index = 0;
     for (final UIComponent child : tabGroup.getChildren()) {
@@ -279,20 +275,16 @@
                 DataAttributes.TARGET, '#' + getTabPanelId(facesContext, tab).replaceAll(":", "\\\\:"), false);
           }
 
-          if (!disabled) {
-            final CommandMap map = RenderUtils.getBehaviorCommands(facesContext, tab);
-            CommandMap.merge(map, tabGroupMap);
-            if (false) { // TBD
-              writer.writeAttribute(DataAttributes.COMMANDS, JsonUtils.encode(map), false);
-            }
-          }
-
           if (!disabled && label.getAccessKey() != null) {
             writer.writeAttribute(HtmlAttributes.ACCESSKEY, Character.toString(label.getAccessKey()), false);
             AccessKeyLogger.addAccessKey(facesContext, label.getAccessKey(), tabId);
           }
           writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.TAB.toString(), false);
 
+          if (!disabled) {
+            encodeBehavior(writer, facesContext, tab);
+          }
+
           boolean labelEmpty = true;
           final String image = tab.getImage();
           // tab.getImage() resolves to empty string if el-expression resolves to null
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
index d420837..360b7f2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
@@ -24,7 +24,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUITextarea;
 import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
 import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -136,8 +135,6 @@
       writer.writeAttribute(HtmlAttributes.PATTERN, pattern, true);
     }
 
-    writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, input)));
-
     HtmlRendererUtils.renderFocus(clientId, input.isFocus(), ComponentUtils.isError(input), facesContext, writer);
 
     final String placeholder = input.getPlaceholder();
@@ -163,6 +160,7 @@
     }
 
     writer.endElement(HtmlElements.TEXTAREA);
+    encodeBehavior(writer, facesContext, input);
   }
 
   @Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
index 1c442cc..54b7dfd 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRenderer.java
@@ -25,8 +25,6 @@
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeNodeBase;
 import org.apache.myfaces.tobago.internal.component.AbstractUITreeSelect;
 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
-import org.apache.myfaces.tobago.internal.util.JsonUtils;
-import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 import org.apache.myfaces.tobago.model.Selectable;
 import org.apache.myfaces.tobago.renderkit.RendererBase;
@@ -132,9 +130,9 @@
       writer.writeIdAttribute(id);
       writer.writeAttribute(HtmlAttributes.CHECKED, checked);
 
-      writer.writeCommandMapAttribute(JsonUtils.encode(RenderUtils.getBehaviorCommands(facesContext, treeSelect)));
-
       writer.endElement(HtmlElements.INPUT);
+
+      encodeBehavior(writer, facesContext, treeSelect);
     }
 
     // label
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/RenderUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/RenderUtils.java
index 95d0df2..56feb91 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/RenderUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/RenderUtils.java
@@ -293,6 +293,10 @@
     return url;
   }
 
+  /**
+   * @deprecated since 5.0.0
+   */
+  @Deprecated
   public static CommandMap getBehaviorCommands(final FacesContext facesContext,
       final ClientBehaviorHolder clientBehaviorHolder) {
     CommandMap commandMap = null;
@@ -333,6 +337,10 @@
     return commandMap;
   }
 
+  /**
+   * @deprecated since 5.0.0
+   */
+  @Deprecated
   private static ClientBehaviorContext getClientBehaviorContext(final FacesContext facesContext,
       final ClientBehaviorHolder clientBehaviorHolder, final String eventName) {
     UIComponent component = (UIComponent) clientBehaviorHolder;
@@ -348,6 +356,10 @@
         .findFirst().orElse(null);
   }
 
+  /**
+   * @deprecated since 5.0.0
+   */
+  @Deprecated
   private static CommandMap getCommandMap(final FacesContext facesContext,
       final ClientBehaviorContext clientBehaviorContext, final ClientBehavior clientBehavior) {
     if (clientBehavior instanceof ClientBehaviorBase) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
index 08ea7e4..4e7568b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
@@ -19,23 +19,47 @@
 
 package org.apache.myfaces.tobago.renderkit;
 
+import org.apache.myfaces.tobago.component.ClientBehaviors;
+import org.apache.myfaces.tobago.internal.behavior.EventBehavior;
+import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
+import org.apache.myfaces.tobago.internal.component.AbstractUIEvent;
 import org.apache.myfaces.tobago.internal.component.AbstractUIReload;
+import org.apache.myfaces.tobago.internal.renderkit.Collapse;
+import org.apache.myfaces.tobago.internal.renderkit.Command;
+import org.apache.myfaces.tobago.internal.renderkit.CommandMap;
+import org.apache.myfaces.tobago.internal.util.RenderUtils;
 import org.apache.myfaces.tobago.internal.webapp.TobagoResponseWriterWrapper;
+import org.apache.myfaces.tobago.renderkit.html.CustomAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.faces.component.EditableValueHolder;
 import javax.faces.component.UIComponent;
 import javax.faces.component.ValueHolder;
+import javax.faces.component.behavior.AjaxBehavior;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorBase;
+import javax.faces.component.behavior.ClientBehaviorContext;
+import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.convert.Converter;
 import javax.faces.convert.ConverterException;
+import javax.faces.render.ClientBehaviorRenderer;
 import javax.faces.render.Renderer;
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+import java.util.Map;
 
 public class RendererBase extends Renderer {
 
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   protected String getCurrentValue(final FacesContext facesContext, final UIComponent component) {
 
     if (component instanceof ValueHolder) {
@@ -92,4 +116,155 @@
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
     writer.write("{\"reload\":{\"frequency\":" + reload.getFrequency() + "}}");
   }
+
+  /**
+   * Renders the tobago-behavior tag.
+   *
+   * @since 5.0
+   */
+  protected void encodeBehavior(
+      final TobagoResponseWriter writer, final FacesContext facesContext, final ClientBehaviorHolder holder)
+      throws IOException {
+    if (holder != null) {
+      final CommandMap behaviorCommands = getBehaviorCommands(facesContext, holder);
+      encodeBehavior(writer, behaviorCommands);
+    }
+  }
+
+  /**
+   * Renders the tobago-behavior tag.
+   *
+   * @since 5.0
+   */
+  protected void encodeBehavior(
+      final TobagoResponseWriter writer, final CommandMap behaviorCommands)
+      throws IOException {
+    if (behaviorCommands != null) {
+      final Command click = behaviorCommands.getClick();
+      if (click != null) {
+        encodeBehavior(writer, ClientBehaviors.click, click);
+      }
+      final Map<ClientBehaviors, Command> other = behaviorCommands.getOther();
+      if (other != null) {
+        for (Map.Entry<ClientBehaviors, Command> entry : other.entrySet()) {
+          encodeBehavior(writer, entry.getKey(), entry.getValue());
+        }
+      }
+    }
+  }
+
+  private void encodeBehavior(
+      final TobagoResponseWriter writer, final ClientBehaviors behaviors, final Command command)
+      throws IOException {
+    writer.startElement(HtmlElements.TOBAGO_BEHAVIOR);
+    writer.writeAttribute(CustomAttributes.EVENT, behaviors.name(), false);
+    writer.writeAttribute(HtmlAttributes.ACTION, command.getAction(), false); // tbd: rename to actionId?
+    writer.writeAttribute(CustomAttributes.EXECUTE, command.getExecute(), false);
+    writer.writeAttribute(CustomAttributes.RENDER, command.getRender(), false);
+    writer.writeAttribute(CustomAttributes.OMIT, command.getOmit());
+    writer.writeAttribute(CustomAttributes.CONFIRMATION, command.getConfirmation(), true);
+    writer.writeAttribute(CustomAttributes.DECOUPLED, command.getTransition() != null ? command.getTransition() : false);
+    final Collapse collapse = command.getCollapse();
+    if (collapse != null) {
+      writer.writeAttribute(CustomAttributes.COLLAPSE_ACTION, collapse.getAction().name(), false);
+      writer.writeAttribute(CustomAttributes.COLLAPSE_TARGET, collapse.getFor(), false);
+    }
+    writer.writeAttribute(CustomAttributes.DELAY, command.getDelay());
+    writer.writeAttribute(CustomAttributes.FOCUS_ID, command.getFocus(), false);
+    writer.writeAttribute(HtmlAttributes.TARGET, command.getTarget(), true);
+
+    // todo: all the other attributes
+    writer.endElement(HtmlElements.TOBAGO_BEHAVIOR);
+  }
+
+  protected CommandMap getBehaviorCommands(final FacesContext facesContext,
+                                               final ClientBehaviorHolder clientBehaviorHolder) {
+    CommandMap commandMap = null;
+
+    for (final Map.Entry<String, List<ClientBehavior>> entry : clientBehaviorHolder.getClientBehaviors().entrySet()) {
+      final String eventName = entry.getKey();
+      final ClientBehaviorContext clientBehaviorContext
+          = getClientBehaviorContext(facesContext, clientBehaviorHolder, eventName);
+
+      for (final ClientBehavior clientBehavior : entry.getValue()) {
+        if (clientBehavior instanceof EventBehavior) {
+          final EventBehavior eventBehavior = (EventBehavior) clientBehavior;
+          final AbstractUIEvent abstractUIEvent
+              = RenderUtils.getAbstractUIEvent((UIComponent) clientBehaviorHolder, eventBehavior);
+
+          if (abstractUIEvent != null && abstractUIEvent.isRendered() && !abstractUIEvent.isDisabled()) {
+            for (List<ClientBehavior> children : abstractUIEvent.getClientBehaviors().values()) {
+              for (ClientBehavior child : children) {
+                final CommandMap childMap = getCommandMap(facesContext, clientBehaviorContext, child);
+                commandMap = CommandMap.merge(commandMap, childMap);
+              }
+            }
+          }
+        }
+
+        final CommandMap map = getCommandMap(facesContext, clientBehaviorContext, clientBehavior);
+        commandMap = CommandMap.merge(commandMap, map);
+      }
+    }
+
+    // if there is no explicit behavior (with f:ajax or tc:event), use the command properties as default.
+    if ((commandMap == null || commandMap.isEmpty()) && clientBehaviorHolder instanceof AbstractUICommand) {
+      if (commandMap == null) {
+        commandMap = new CommandMap();
+      }
+      commandMap.addCommand(ClientBehaviors.click, new Command(facesContext, (AbstractUICommand) clientBehaviorHolder));
+    }
+
+    return commandMap;
+  }
+
+  private static ClientBehaviorContext getClientBehaviorContext(final FacesContext facesContext,
+                                                                final ClientBehaviorHolder clientBehaviorHolder, final String eventName) {
+    UIComponent component = (UIComponent) clientBehaviorHolder;
+    return ClientBehaviorContext.createClientBehaviorContext(facesContext, component, eventName,
+        component.getClientId(facesContext), null);
+  }
+
+  private static CommandMap getCommandMap(final FacesContext facesContext,
+                                          final ClientBehaviorContext clientBehaviorContext, final ClientBehavior clientBehavior) {
+    if (clientBehavior instanceof ClientBehaviorBase) {
+      String type = ((ClientBehaviorBase) clientBehavior).getRendererType();
+
+      // this is to use a different renderer for Tobago components and other components.
+      if (type.equals(AjaxBehavior.BEHAVIOR_ID)) {
+        type = "org.apache.myfaces.tobago.behavior.Ajax";
+      }
+      final ClientBehaviorRenderer renderer = facesContext.getRenderKit().getClientBehaviorRenderer(type);
+      final String dummy = renderer.getScript(clientBehaviorContext, clientBehavior);
+      if (dummy != null) {
+        return CommandMap.restoreCommandMap(facesContext);
+      }
+    } else {
+      LOG.warn("Ignoring: '{}'", clientBehavior);
+    }
+    return null;
+  }
+
+  protected void decodeClientBehaviors(final FacesContext facesContext, final UIComponent component) {
+    if (component instanceof ClientBehaviorHolder) {
+      final ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+      final Map<String, List<ClientBehavior>> clientBehaviors = clientBehaviorHolder.getClientBehaviors();
+      if (clientBehaviors != null && !clientBehaviors.isEmpty()) {
+        final Map<String, String> paramMap = facesContext.getExternalContext().getRequestParameterMap();
+        final String behaviorEventName = paramMap.get("javax.faces.behavior.event");
+        if (behaviorEventName != null) {
+          final List<ClientBehavior> clientBehaviorList = clientBehaviors.get(behaviorEventName);
+          if (clientBehaviorList != null && !clientBehaviorList.isEmpty()) {
+            final String clientId = paramMap.get("javax.faces.source");
+            if (component.getClientId(facesContext).equals(clientId)) {
+              for (final ClientBehavior clientBehavior : clientBehaviorList) {
+                clientBehavior.decode(facesContext, component);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/CustomAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/CustomAttributes.java
index 2e49e66..af6aade 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/CustomAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/CustomAttributes.java
@@ -21,8 +21,17 @@
 
 public enum CustomAttributes implements MarkupLanguageAttributes {
 
+  COLLAPSE_ACTION("collapse-action"),
+  COLLAPSE_TARGET("collapse-target"),
+  CONFIRMATION("confirmation"),
   DATA("data"),
   DELAY("delay"),
+  EVENT("event"),
+  /**
+   * &lt;f:ajax&gt; attribute
+   */
+  EXECUTE("execute"),
+  FOCUS_ID("focus-id"),
   /**
    * The index of the tab inside the tab group.
    */
@@ -30,15 +39,20 @@
   LOCAL_MENU("local-menu"),
   MAX_ITEMS("max-items"),
   MIN_CHARS("min-chars"),
+  OMIT("omit"),
   ORIENTATION("orientation"),
   /**
+   * &lt;f:ajax&gt; attribute
+   */
+  RENDER("render"),
+  /**
    * The mode of the tab switch: client, reloadTab, reloadPage.
    */
   SWITCH_TYPE("switch-type"),
   TOTAL_COUNT("total-count"),
+  DECOUPLED("decoupled"),
   UPDATE("update");
 
-
   private final String value;
 
   CustomAttributes(final String value) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
index 175737f..bb8cdb6 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
@@ -44,17 +44,6 @@
    */
   COLUMN_INDEX("data-tobago-column-index"),
 
-  /**
-   * Custom command attribute. Is used to mark different client side JavaScript buttons.
-   * Should only contain the command name as a keyword, for security reasons.
-   */
-  COMMAND("data-tobago-command"),
-
-  /**
-   * The list of commands attached to an element.
-   */
-  COMMANDS("data-tobago-commands"),
-
   CONTENT("data-content"),
 
   /**
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
index fd2dc46..5394f3c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
@@ -133,6 +133,7 @@
   VIDEO("video"),
   WBR("wbr", Qualifier.VOID),
 
+  TOBAGO_BEHAVIOR("tobago-behavior"),
   TOBAGO_FILE("tobago-file"),
   TOBAGO_IN("tobago-in"),
   TOBAGO_PANEL("tobago-panel"),
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java
index c00b4a4..9e9bfe5 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoResponseWriter.java
@@ -19,11 +19,11 @@
 
 package org.apache.myfaces.tobago.webapp;
 
+import org.apache.myfaces.tobago.internal.util.Deprecation;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.FontAwesomeIconEncoder;
 import org.apache.myfaces.tobago.renderkit.css.IconEncoder;
 import org.apache.myfaces.tobago.renderkit.css.Icons;
-import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlTypes;
@@ -147,12 +147,13 @@
 
   /**
    * Write the command map data attribute.
+   *
+   * @deprecated since 5.0, use {@link
+   * org.apache.myfaces.tobago.renderkit.RendererBase#encodeBehavior} instead.
    */
-  public void writeCommandMapAttribute(final String map) throws IOException { // XXX use CommandMap instead of String
-    if (map != null) {
-      // XXX
-      writeAttribute(DataAttributes.COMMANDS, map, true);
-    }
+  @Deprecated
+  public void writeCommandMapAttribute(final String map) throws IOException {
+    Deprecation.LOG.error("No longer supported. Data: {}", map);
   }
 
   /**
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TextareaController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TextareaController.java
index 1a26d6e..3df98c7 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TextareaController.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/TextareaController.java
@@ -19,15 +19,22 @@
 
 package org.apache.myfaces.tobago.example.demo;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import javax.enterprise.context.RequestScoped;
 import javax.inject.Named;
 import java.io.Serializable;
+import java.lang.invoke.MethodHandles;
 
 @RequestScoped
 @Named
 public class TextareaController implements Serializable {
 
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   private String longText;
+  private String ajaxValue;
 
   public TextareaController() {
     longText = "The goal of Apache Tobago™ is to provide the community with a well designed set of user interface "
@@ -47,6 +54,11 @@
         + "The development of Tobago started in 2002.";
   }
 
+  public String submit() {
+    LOG.info("Submit Textarea");
+    return null;
+  }
+
   public String getLongText() {
     return longText;
   }
@@ -54,4 +66,12 @@
   public void setLongText(final String longText) {
     this.longText = longText;
   }
+
+  public String getAjaxValue() {
+    return ajaxValue;
+  }
+
+  public void setAjaxValue(String ajaxValue) {
+    this.ajaxValue = ajaxValue;
+  }
 }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.test.js
index 0d4568b..16a31ad 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.test.js
@@ -47,7 +47,7 @@
   });
   TTT.action(function () {
     inputFieldFn().value = "qwe";
-    inputFieldFn().dispatchEvent(new Event('change'));
+    inputFieldFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.xhtml
index d9f32b1..3640356 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/10-in/In.xhtml
@@ -81,6 +81,8 @@
       Additional, the <code>listener</code> attribute is set. The given method is called after the inputfield
       loose focus.</p>
     <tc:in id="inputAjax" label="On Change" value="#{inController.changeValue}">
+      <f:facet name="before">AJAX</f:facet>
+      <f:facet name="after">on change</f:facet>
       <f:ajax render="outputAjax" listener="#{inController.update}"/>
     </tc:in>
     <tc:out id="outputAjax" label="On Server" value="#{inController.changeValue}"/>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/20-suggest/Suggest.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/20-suggest/Suggest.test.js
index 5054d6a..f22cab7 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/20-suggest/Suggest.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/20-suggest/Suggest.test.js
@@ -53,7 +53,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = inputString;
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(expectedLength + 1, function () {
@@ -72,7 +72,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "eus";
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
@@ -83,7 +83,7 @@
     assert.equal(suggestionsFn().item(2).querySelector("strong").textContent, "eus");
   });
   TTT.action(function () {
-    suggestionsFn().item(0).click();
+    suggestionsFn().item(0).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(inFn().value, "Prometheus");
@@ -100,7 +100,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "C";
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitMs(suggestionDelay);
   TTT.asserts(1, function () {
@@ -118,7 +118,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "Ca";
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitMs(200); // default suggestion delay
   TTT.asserts(1, function () {
@@ -143,7 +143,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "Ju";
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.asserts(3, function () {
     assert.equal(suggestionsFn().length, 2);
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/30-textarea/Textarea.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/30-textarea/Textarea.xhtml
index 1d36d52..2e5b249 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/30-textarea/Textarea.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/30-textarea/Textarea.xhtml
@@ -20,7 +20,8 @@
 <ui:composition template="/main.xhtml"
                 xmlns="http://www.w3.org/1999/xhtml"
                 xmlns:tc="http://myfaces.apache.org/tobago/component"
-                xmlns:ui="http://java.sun.com/jsf/facelets">
+                xmlns:ui="http://java.sun.com/jsf/facelets"
+                xmlns:f="http://java.sun.com/jsf/core">
 
   <p>The <code class="language-markup">&lt;tc:textarea/&gt;</code> tag, creates a textfield with one or more rows.
     The textarea becomes scrollable if the containing text could not displayed in the current size.</p>
@@ -50,7 +51,15 @@
       Leave the field blank and press 'submit' to see the errormessage.</p>
     <pre><code class="language-markup">&lt;tc:textarea id="treq" label="Text Area" required="true"/></code></pre>
     <tc:textarea id="treq" label="Text Area" required="true"/>
-    <tc:button label="Submit"/>
+    <tc:button label="Submit" action="#{textareaController.submit}"/>
+  </tc:section>
+
+  <tc:section label="Ajax">
+    <p>Ajax update by the change event:</p>
+    <tc:textarea id="tajax" label="Text Area" value="#{textareaController.ajaxValue}">
+      <f:ajax render="outputAjax" />
+    </tc:textarea>
+    <tc:out id="outputAjax" label="On Server" value="#{textareaController.ajaxValue}"/>
   </tc:section>
 
   <tc:section label="Rows">
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/40-date/Date.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/40-date/Date.test.js
index a0eae35..d2afd34 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/40-date/Date.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/40-date/Date.test.js
@@ -37,7 +37,7 @@
   assert.equal(dateFieldFn().value, today);
 
   dateFieldFn().value = "32.05.2016";
-  dateButtonFn().click();
+  dateButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
 
   assert.equal(dateFieldFn().value, today);
   assert.notOk(dayTodayFn().classList.contains("past"));
@@ -47,7 +47,7 @@
     assert.notOk(dayTodayFn().nextElementSibling.classList.contains("past"));
   }
 
-  dateButtonFn().click(); // IE11: close datetimepicker for next test
+  dateButtonFn().dispatchEvent(new Event("click", {bubbles: true})); // IE11: close datetimepicker for next test
 });
 
 QUnit.test("date+time pattern", function (assert) {
@@ -59,7 +59,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    dateButtonFn().click();
+    dateButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(3, function () {
     assert.ok(datepickerFn() !== null);
@@ -67,7 +67,7 @@
     assert.equal(getComputedStyle(lastLiFn()).display, "none");
   });
   TTT.action(function () {
-    togglePickerButtonFn().click();
+    togglePickerButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(2, function () {
@@ -75,7 +75,7 @@
     assert.notEqual(getComputedStyle(lastLiFn()).display, "none"); //block
   });
   TTT.action(function () {
-    dateButtonFn().click(); // IE11: close datetimepicker for next test
+    dateButtonFn().dispatchEvent(new Event("click", {bubbles: true})); // IE11: close datetimepicker for next test
   });
   TTT.startTest();
 });
@@ -95,7 +95,7 @@
     assert.equal(outFieldFn().textContent, "22.05.2016");
   });
   TTT.action(function () {
-    dateButtonFn().click();
+    dateButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.ok(widgetFn().item(0), ".bootstrap-datetimepicker-widget should be available");
@@ -109,13 +109,13 @@
     assert.ok(daysFn().item(day22 + 10));
   });
   TTT.action(function () {
-    daysFn().item(day22 + 10).click(); // Choose '01.06.2016'.
+    daysFn().item(day22 + 10).dispatchEvent(new Event("click", {bubbles: true})); // Choose '01.06.2016'.
   });
   TTT.asserts(1, function () {
     assert.equal(dateFieldFn().value, "01.06.2016");
   });
   TTT.action(function () {
-    submitButtonFn().click();
+    submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -137,7 +137,7 @@
     assert.equal(outFieldFn().textContent, "");
   });
   TTT.action(function () {
-    dateButtonFn().click();
+    dateButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/50-input-group/Group.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/50-input-group/Group.test.js
index be24022..dc68d8c 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/50-input-group/Group.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/010-input/50-input-group/Group.test.js
@@ -26,7 +26,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inputFn().value = "delete chat";
-    sendButtonFn().click();
+    sendButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -34,7 +34,7 @@
   });
   TTT.action(function () {
     inputFn().value = "Hi Peter, how are you?";
-    sendButtonFn().click();
+    sendButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -52,24 +52,24 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    buttonFn().click();
-    sendToPeterFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
+    sendToPeterFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(buttonLabelFn().textContent, "SendTo: Peter");
   });
   TTT.action(function () {
-    buttonFn().click();
-    sendToBobFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
+    sendToBobFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(buttonLabelFn().textContent, "SendTo: Bob");
   });
   TTT.action(function () {
-    buttonFn().click();
-    sendToAllFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
+    sendToAllFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -91,7 +91,7 @@
     currencyOptionFn().item(2).selected = false;
     currencyOptionFn().item(3).selected = false;
     currencyOptionFn().item(0).selected = true; // Yen
-    currencyFn().dispatchEvent(new Event('change'));
+    currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -103,7 +103,7 @@
     currencyOptionFn().item(2).selected = false;
     currencyOptionFn().item(3).selected = false;
     currencyOptionFn().item(1).selected = true; // Trinidad-Tobago Dollar
-    currencyFn().dispatchEvent(new Event('change'));
+    currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -115,7 +115,7 @@
     currencyOptionFn().item(1).selected = false;
     currencyOptionFn().item(3).selected = false;
     currencyOptionFn().item(2).selected = true; // US Dollar
-    currencyFn().dispatchEvent(new Event('change'));
+    currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
index 94f1905..994ce61 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
@@ -67,7 +67,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectDFn().checked = true;
-    selectDFn().dispatchEvent(new Event('change'));
+    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -83,7 +83,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectDFn().checked = false;
-    selectDFn().dispatchEvent(new Event('change'));
+    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -99,7 +99,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectEFn().checked = true;
-    selectEFn().dispatchEvent(new Event('change'));
+    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -115,7 +115,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectEFn().checked = false;
-    selectEFn().dispatchEvent(new Event('change'));
+    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -131,7 +131,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectFFn().checked = true;
-    selectFFn().dispatchEvent(new Event('change'));
+    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -147,7 +147,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectFFn().checked = false;
-    selectFFn().dispatchEvent(new Event('change'));
+    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
index 94f1905..994ce61 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
@@ -67,7 +67,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectDFn().checked = true;
-    selectDFn().dispatchEvent(new Event('change'));
+    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -83,7 +83,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectDFn().checked = false;
-    selectDFn().dispatchEvent(new Event('change'));
+    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -99,7 +99,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectEFn().checked = true;
-    selectEFn().dispatchEvent(new Event('change'));
+    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -115,7 +115,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectEFn().checked = false;
-    selectEFn().dispatchEvent(new Event('change'));
+    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -131,7 +131,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectFFn().checked = true;
-    selectFFn().dispatchEvent(new Event('change'));
+    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -147,7 +147,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectFFn().checked = false;
-    selectFFn().dispatchEvent(new Event('change'));
+    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
index f0e335b..9297334 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
@@ -28,7 +28,7 @@
   TTT.action(function () {
     aliceFn().selected = true;
     bobFn().selected = false;
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -47,7 +47,7 @@
   TTT.action(function () {
     aliceFn().selected = false;
     bobFn().selected = true;
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -66,7 +66,7 @@
   TTT.action(function () {
     jupiterOptionFn().selected = false;
     marsOptionFn().selected = true;
-    planetFn().dispatchEvent(new Event('change'));
+    planetFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -86,7 +86,7 @@
   TTT.action(function () {
     marsOptionFn().selected = false;
     jupiterOptionFn().selected = true;
-    planetFn().dispatchEvent(new Event('change'));
+    planetFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
index b88361e..00e7a39 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
@@ -32,7 +32,7 @@
     number2Fn().item(0).checked = false;
     number2Fn().item(1).checked = false;
     number2Fn().item(2).checked = true; // Select 4
-    submitAddFn().click();
+    submitAddFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -55,7 +55,7 @@
     number2Fn().item(0).checked = true; // Select 1
     number2Fn().item(1).checked = false;
     number2Fn().item(2).checked = false;
-    submitSubFn().click();
+    submitSubFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -73,7 +73,7 @@
     planetFn().item(0).checked = false;
     planetFn().item(2).checked = false;
     planetFn().item(1).checked = true; // Mars.
-    planetFn().item(1).dispatchEvent(new Event('change'));
+    planetFn().item(1).dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -92,7 +92,7 @@
     planetFn().item(0).checked = false;
     planetFn().item(1).checked = false;
     planetFn().item(2).checked = true; // Jupiter.
-    planetFn().item(2).dispatchEvent(new Event('change'));
+    planetFn().item(2).dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
index 1dd4d64..6e72010 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
@@ -30,7 +30,7 @@
     riversFn().item(2).selected = false; // Yangtze
     riversFn().item(3).selected = false; // Yellow River
     riversFn().item(4).selected = false; // Paraná River
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -51,7 +51,7 @@
     riversFn().item(2).selected = true; // Yangtze
     riversFn().item(3).selected = false; // Yellow River
     riversFn().item(4).selected = false; // Paraná River
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -73,7 +73,7 @@
     mountainsFn().item(3).selected = false;
     mountainsFn().item(4).selected = false;
     mountainsFn().item(0).selected = true; // Everest
-    mountainListFn().dispatchEvent(new Event('change')); // Everest
+    mountainListFn().dispatchEvent(new Event("change", {bubbles: true})); // Everest
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -94,7 +94,7 @@
     mountainsFn().item(2).selected = false;
     mountainsFn().item(3).selected = false;
     mountainsFn().item(4).selected = true; // Everest
-    mountainListFn().dispatchEvent(new Event('change')); // Everest
+    mountainListFn().dispatchEvent(new Event("change", {bubbles: true})); // Everest
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
index e41bc5f..19a864f 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
@@ -29,7 +29,7 @@
     animalsFn().item(1).checked = false;
     animalsFn().item(2).checked = false;
     animalsFn().item(3).checked = false;
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -49,7 +49,7 @@
     animalsFn().item(1).checked = false;
     animalsFn().item(2).checked = true;
     animalsFn().item(3).checked = true;
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -68,11 +68,11 @@
     if (number2Fn().checked) {
       newOutputValue = parseInt(outputFn().textContent) - 2;
       number2Fn().checked = false;
-      number2Fn().dispatchEvent(new Event('change'));
+      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
     } else {
       newOutputValue = parseInt(outputFn().textContent) + 2;
       number2Fn().checked = true;
-      number2Fn().dispatchEvent(new Event('change'));
+      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
     }
   });
   TTT.waitForResponse();
@@ -92,11 +92,11 @@
     if (number3Fn().checked) {
       newOutputValue = parseInt(outputFn().textContent) - 3;
       number3Fn().checked = false;
-      number3Fn().dispatchEvent(new Event('change'));
+      number3Fn().dispatchEvent(new Event("change", {bubbles: true}));
     } else {
       newOutputValue = parseInt(outputFn().textContent) + 3;
       number3Fn().checked = true;
-      number3Fn().dispatchEvent(new Event('change'));
+      number3Fn().dispatchEvent(new Event("change", {bubbles: true}));
     }
   });
   TTT.waitForResponse();
@@ -116,11 +116,11 @@
     if (number2Fn().checked) {
       newOutputValue = parseInt(outputFn().textContent) - 2;
       number2Fn().checked = false;
-      number2Fn().dispatchEvent(new Event('change'));
+      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
     } else {
       newOutputValue = parseInt(outputFn().textContent) + 2;
       number2Fn().checked = true;
-      number2Fn().dispatchEvent(new Event('change'));
+      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
     }
   });
   TTT.waitForResponse();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/060-popup/Popup.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/060-popup/Popup.test.js
index 1659bd0..fbbea0e 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/060-popup/Popup.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/060-popup/Popup.test.js
@@ -26,9 +26,9 @@
   let cancelButtonFn = testFrameQuerySelectorFn("#page\\:mainForm\\:form2\\:clientPopup\\:cancel2");
 
   assert.equal(popupFn().getAttribute("value"), "true");
-  openButtonFn().click();
+  openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   assert.equal(popupFn().getAttribute("value"), "false");
-  cancelButtonFn().click();
+  cancelButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   assert.equal(popupFn().getAttribute("value"), "true");
 });
 
@@ -47,21 +47,21 @@
     assert.equal(popupFn().getAttribute("value"), "true");
   });
   TTT.action(function () {
-    openButtonFn().click();
+    openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupFn().getAttribute("value"), "false");
   });
   TTT.action(function () {
     inputFieldFn().value = "";
-    submitButtonFn().click();
+    submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(messagesFn().length, 1);
   });
   TTT.action(function () {
-    cancelButtonFn().click();
+    cancelButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.equal(popupFn().getAttribute("value"), "true");
@@ -84,21 +84,21 @@
     assert.equal(popupFn().getAttribute("value"), "true");
   });
   TTT.action(function () {
-    openButtonFn().click();
+    openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupFn().getAttribute("value"), "false");
   });
   TTT.action(function () {
     inputFieldFn().value = "test client popup - submit button";
-    submitButtonFn().click();
+    submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(messagesFn().length, 0);
   });
   TTT.action(function () {
-    cancelButtonFn().click();
+    cancelButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.equal(popupFn().getAttribute("value"), "true");
@@ -120,14 +120,14 @@
     assert.equal(popupFn().getAttribute("value"), "true");
   });
   TTT.action(function () {
-    openButtonFn().click();
+    openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupFn().getAttribute("value"), "false");
   });
   TTT.action(function () {
     inputFieldFn().value = "";
-    submitCloseButtonFn().click();
+    submitCloseButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -149,14 +149,14 @@
     assert.equal(popupFn().getAttribute("value"), "true");
   });
   TTT.action(function () {
-    openButtonFn().click();
+    openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupFn().getAttribute("value"), "false");
   });
   TTT.action(function () {
     inputFieldFn().value = "test client popup - submit and close button";
-    submitCloseButtonFn().click();
+    submitCloseButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -176,10 +176,10 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     if (popupFn().classList.contains("show")) {
-      closeButtonFn().click();
+      closeButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
     }
     if (dropdownContainerFn().classList.contains("show")) {
-      dropdownButtonFn().click();
+      dropdownButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
     }
   });
   TTT.asserts(2, function () {
@@ -187,14 +187,14 @@
     assert.equal(popupFn().classList.contains("show"), false);
   });
   TTT.action(function () {
-    dropdownButtonFn().click();
+    dropdownButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.equal(dropdownContainerFn().classList.contains("show"), true);
     assert.equal(popupFn().classList.contains("show"), false);
   });
   TTT.action(function () {
-    openButtonFn().click();
+    openButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(2, function () {
@@ -202,7 +202,7 @@
     assert.equal(popupFn().classList.contains("show"), true);
   });
   TTT.action(function () {
-    closeButtonFn().click();
+    closeButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(2, function () {
@@ -222,7 +222,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     if (popupFn().classList.contains("show")) {
-      closeButtonFn().click();
+      closeButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
     }
     if (dropdownContainerFn().classList.contains("show")) {
       dropdownButtonFn().click();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/070-tab/Tab_Group.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/070-tab/Tab_Group.test.js
index 97d9081..d9bf8af 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/070-tab/Tab_Group.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/070-tab/Tab_Group.test.js
@@ -32,7 +32,7 @@
     assert.ok(tab3Fn().classList.contains("tobago-tab-markup-three"));
   });
   TTT.action(function () {
-    tab3Fn().querySelector(".nav-link").click();
+    tab3Fn().querySelector(".nav-link").dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(5, function () {
     assert.equal(tabGroupFn().hiddenInput.value, 3);
@@ -58,7 +58,7 @@
     assert.ok(tab3Fn().classList.contains("tobago-tab-markup-three"));
   });
   TTT.action(function () {
-    tab3Fn().querySelector(".nav-link").click();
+    tab3Fn().querySelector(".nav-link").dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
@@ -85,7 +85,7 @@
     assert.ok(tab3Fn().classList.contains("tobago-tab-markup-three"));
   });
   TTT.action(function () {
-    tab3Fn().querySelector(".nav-link").click();
+    tab3Fn().querySelector(".nav-link").dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
index f8d99d2..e4eeba2 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
@@ -26,7 +26,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -37,7 +37,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -48,7 +48,7 @@
         "Epimetheus", "0.69", "1980");
   });
   TTT.action(function () {
-    colNameFn().click();
+    colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -59,7 +59,7 @@
         "Praxidike", "625.3", "2000");
   });
   TTT.action(function () {
-    colNameFn().click();
+    colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -80,7 +80,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colPeriodFn().click();
+      colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -91,7 +91,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "29";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -102,7 +102,7 @@
         "Prometheus", "0.61", "1980");
   });
   TTT.action(function () {
-    colPeriodFn().click();
+    colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -113,7 +113,7 @@
         "Titania", "8.71", "1787");
   });
   TTT.action(function () {
-    colPeriodFn().click();
+    colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -134,7 +134,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colYearFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colYearFn().click();
+      colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -145,7 +145,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -155,7 +155,7 @@
     assert.equal(rowsFn().item(3).querySelectorAll(".tobago-sheet-cell").item(2).textContent.trim(), "1905", "row3col2");
   });
   TTT.action(function () {
-    colYearFn().click();
+    colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -165,7 +165,7 @@
     assert.equal(rowsFn().item(3).querySelectorAll(".tobago-sheet-cell").item(2).textContent.trim(), "1997", "row3col2");
   });
   TTT.action(function () {
-    colYearFn().click();
+    colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -189,7 +189,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -200,7 +200,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "8";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -212,7 +212,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "9";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -239,7 +239,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -250,7 +250,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "1";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -261,7 +261,7 @@
         "Ananke", "-629.77", "1951");
   });
   TTT.action(function () {
-    centerPagingFn().item(6).click();
+    centerPagingFn().item(6).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -272,7 +272,7 @@
         "Galatea", "0.43", "1989");
   });
   TTT.action(function () {
-    centerPagingFn().item(10).click();
+    centerPagingFn().item(10).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -283,7 +283,7 @@
         "Praxidike", "625.3", "2000");
   });
   TTT.action(function () {
-    centerPagingFn().item(3).click();
+    centerPagingFn().item(3).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -313,7 +313,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -324,7 +324,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -335,7 +335,7 @@
         "Epimetheus", "0.69", "1980");
   });
   TTT.action(function () {
-    rightPagingFn().item(0).click();
+    rightPagingFn().item(0).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -346,7 +346,7 @@
         "Ananke", "-629.77", "1951");
   });
   TTT.action(function () {
-    rightPagingFn().item(3).click();
+    rightPagingFn().item(3).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -357,7 +357,7 @@
         "Bianca", "0.43", "1986");
   });
   TTT.action(function () {
-    rightPagingFn().item(4).click();
+    rightPagingFn().item(4).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -368,7 +368,7 @@
         "Venus", "224.7", "");
   });
   TTT.action(function () {
-    rightPagingFn().item(1).click();
+    rightPagingFn().item(1).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -380,7 +380,7 @@
   });
   TTT.action(function () {
     jumpToPageFn().value = "14";
-    jumpToPageFn().dispatchEvent(new Event('blur'));
+    jumpToPageFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -401,7 +401,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -412,7 +412,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -423,7 +423,7 @@
         "Epimetheus", "0.69", "1980");
   });
   TTT.action(function () {
-    colNameFn().click();
+    colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -434,7 +434,7 @@
         "Praxidike", "625.3", "2000");
   });
   TTT.action(function () {
-    colNameFn().click();
+    colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -455,7 +455,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colPeriodFn().click();
+      colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -466,7 +466,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "29";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -477,7 +477,7 @@
         "Enceladus", "1.37", "1789");
   });
   TTT.action(function () {
-    colPeriodFn().click();
+    colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -488,7 +488,7 @@
         "Leda", "238.72", "1974");
   });
   TTT.action(function () {
-    colPeriodFn().click();
+    colPeriodFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -509,7 +509,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colYearFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colYearFn().click();
+      colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -520,7 +520,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -530,7 +530,7 @@
     assert.equal(rowsFn().item(3).querySelectorAll(".tobago-sheet-cell").item(2).textContent.trim(), "1848", "row3col2");
   });
   TTT.action(function () {
-    colYearFn().click();
+    colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -540,7 +540,7 @@
     assert.equal(rowsFn().item(3).querySelectorAll(".tobago-sheet-cell").item(2).textContent.trim(), "1986", "row3col2");
   });
   TTT.action(function () {
-    colYearFn().click();
+    colYearFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -564,7 +564,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -575,7 +575,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "8";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -587,7 +587,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "9";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -614,7 +614,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -625,7 +625,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "1";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -636,7 +636,7 @@
         "Ananke", "-629.77", "1951");
   });
   TTT.action(function () {
-    centerPagingFn().item(6).click();
+    centerPagingFn().item(6).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -647,7 +647,7 @@
         "Galatea", "0.43", "1989");
   });
   TTT.action(function () {
-    centerPagingFn().item(10).click();
+    centerPagingFn().item(10).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -658,7 +658,7 @@
         "Praxidike", "625.3", "2000");
   });
   TTT.action(function () {
-    centerPagingFn().item(3).click();
+    centerPagingFn().item(3).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -688,7 +688,7 @@
   let TTT = new TobagoTestTool(assert);
   if (!colNameFn().classList.contains("tobago-sheet-header-markup-ascending")) {
     TTT.action(function () {
-      colNameFn().click();
+      colNameFn().dispatchEvent(new Event("click", {bubbles: true}));
     });
     TTT.waitForResponse();
   }
@@ -699,7 +699,7 @@
   });
   TTT.action(function () {
     leftPagingFn().value = "22";
-    leftPagingFn().dispatchEvent(new Event('blur'));
+    leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -710,7 +710,7 @@
         "Epimetheus", "0.69", "1980");
   });
   TTT.action(function () {
-    rightPagingFn().item(0).click();
+    rightPagingFn().item(0).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -721,7 +721,7 @@
         "Ananke", "-629.77", "1951");
   });
   TTT.action(function () {
-    rightPagingFn().item(3).click();
+    rightPagingFn().item(3).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -732,7 +732,7 @@
         "Bianca", "0.43", "1986");
   });
   TTT.action(function () {
-    rightPagingFn().item(4).click();
+    rightPagingFn().item(4).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -743,7 +743,7 @@
         "Venus", "224.7", "");
   });
   TTT.action(function () {
-    rightPagingFn().item(1).click();
+    rightPagingFn().item(1).dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
@@ -755,7 +755,7 @@
   });
   TTT.action(function () {
     rightPagingInputFn().value = "14";
-    rightPagingInputFn().dispatchEvent(new Event('blur'));
+    rightPagingInputFn().dispatchEvent(new Event("blur", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(12, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
index cef2c6c..1f28ea9 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
@@ -28,7 +28,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     oneClickAjaxFn().checked = true;
-    oneClickAjaxFn().dispatchEvent(new Event('change'));
+    oneClickAjaxFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -37,21 +37,21 @@
     assert.ok(saturnFn());
   });
   TTT.action(function () {
-    venusFn().click();
+    venusFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Venus");
   });
   TTT.action(function () {
-    jupiterFn().click();
+    jupiterFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Jupiter");
   });
   TTT.action(function () {
-    saturnFn().click();
+    saturnFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -70,7 +70,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     oneClickFullRequestFn().checked = true;
-    oneClickFullRequestFn().dispatchEvent(new Event('change'));
+    oneClickFullRequestFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -79,21 +79,21 @@
     assert.ok(saturnFn());
   });
   TTT.action(function () {
-    venusFn().click();
+    venusFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Venus");
   });
   TTT.action(function () {
-    jupiterFn().click();
+    jupiterFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Jupiter");
   });
   TTT.action(function () {
-    saturnFn().click();
+    saturnFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -112,7 +112,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     doubleClickFullRequestFn().checked = true;
-    doubleClickFullRequestFn().dispatchEvent(new Event('change'));
+    doubleClickFullRequestFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -121,21 +121,21 @@
     assert.ok(saturnFn());
   });
   TTT.action(function () {
-    venusFn().dispatchEvent(new Event('dblclick'));
+    venusFn().dispatchEvent(new Event("dblclick", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Venus");
   });
   TTT.action(function () {
-    jupiterFn().dispatchEvent(new Event('dblclick'));
+    jupiterFn().dispatchEvent(new Event("dblclick", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(namefieldFn().value, "Jupiter");
   });
   TTT.action(function () {
-    saturnFn().dispatchEvent(new Event('dblclick'));
+    saturnFn().dispatchEvent(new Event("dblclick", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -156,7 +156,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     radioButtonFn().checked = true;
-    radioButtonFn().dispatchEvent(new Event('change'));
+    radioButtonFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -165,7 +165,7 @@
     assert.ok(saturnFn());
   });
   TTT.action(function () {
-    venusFn().click();
+    venusFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.waitMs(1000); // wait for animation
@@ -174,14 +174,14 @@
     assert.equal(nameFn().value, "Venus");
   });
   TTT.action(function () {
-    cancelFn().click();
+    cancelFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(1, function () {
     assert.notOk(popupFn().classList.contains("show"));
   });
   TTT.action(function () {
-    jupiterFn().click();
+    jupiterFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.waitMs(1000); // wait for animation
@@ -190,14 +190,14 @@
     assert.equal(nameFn().value, "Jupiter");
   });
   TTT.action(function () {
-    cancelFn().click();
+    cancelFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(1, function () {
     assert.notOk(popupFn().classList.contains("show"));
   });
   TTT.action(function () {
-    saturnFn().click();
+    saturnFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.waitMs(1000); // wait for animation
@@ -206,7 +206,7 @@
     assert.equal(nameFn().value, "Saturn");
   });
   TTT.action(function () {
-    cancelFn().click();
+    cancelFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000); // wait for animation
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
index 52d5e9a..6161cb5 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
@@ -53,7 +53,7 @@
     assert.notEqual(getComputedStyle(sheetRow).display, "none");
   });
   TTT.action(function () {
-    rootTreeButtonFn().click();
+    rootTreeButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(1000);
   TTT.asserts(8, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/01-select/Tree_Select.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/01-select/Tree_Select.test.js
index 6ae2232..7b638ed 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/01-select/Tree_Select.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/01-select/Tree_Select.test.js
@@ -29,7 +29,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectableNoneFn().checked = true;
-    selectableNoneFn().dispatchEvent(new Event('change'));
+    selectableNoneFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -37,7 +37,7 @@
   });
   TTT.action(function () {
     selectableSingleFn().checked = true;
-    selectableSingleFn().dispatchEvent(new Event('change'));
+    selectableSingleFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -45,7 +45,7 @@
   });
   TTT.action(function () {
     musicFn().checked = true;
-    musicFn().dispatchEvent(new Event('change'));
+    musicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -53,7 +53,7 @@
   });
   TTT.action(function () {
     mathematicsFn().checked = true;
-    mathematicsFn().dispatchEvent(new Event('change'));
+    mathematicsFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -73,7 +73,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectableNoneFn().checked = true;
-    selectableNoneFn().dispatchEvent(new Event('change'));
+    selectableNoneFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -81,7 +81,7 @@
   });
   TTT.action(function () {
     selectableSingleLeafOnlyFn().checked = true;
-    selectableSingleLeafOnlyFn().dispatchEvent(new Event('change'));
+    selectableSingleLeafOnlyFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -89,7 +89,7 @@
   });
   TTT.action(function () {
     classicFn().checked = true;
-    classicFn().dispatchEvent(new Event('change'));
+    classicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -97,7 +97,7 @@
   });
   TTT.action(function () {
     mathematicsFn().checked = true;
-    mathematicsFn().dispatchEvent(new Event('change'));
+    mathematicsFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -117,7 +117,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectableNoneFn().checked = true;
-    selectableNoneFn().dispatchEvent(new Event('change'));
+    selectableNoneFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -125,7 +125,7 @@
   });
   TTT.action(function () {
     selectableMultiFn().checked = true;
-    selectableMultiFn().dispatchEvent(new Event('change'));
+    selectableMultiFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -133,7 +133,7 @@
   });
   TTT.action(function () {
     musicFn().checked = true;
-    musicFn().dispatchEvent(new Event('change'));
+    musicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -141,7 +141,7 @@
   });
   TTT.action(function () {
     mathematicsFn().checked = true;
-    mathematicsFn().dispatchEvent(new Event('change'));
+    mathematicsFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -149,7 +149,7 @@
   });
   TTT.action(function () {
     musicFn().checked = false;
-    musicFn().dispatchEvent(new Event('change'));
+    musicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -169,7 +169,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectableNoneFn().checked = true;
-    selectableNoneFn().dispatchEvent(new Event('change'));
+    selectableNoneFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -177,7 +177,7 @@
   });
   TTT.action(function () {
     selectableMultiLeafOnlyFn().checked = true;
-    selectableMultiLeafOnlyFn().dispatchEvent(new Event('change'));
+    selectableMultiLeafOnlyFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -185,7 +185,7 @@
   });
   TTT.action(function () {
     classicFn().checked = true;
-    classicFn().dispatchEvent(new Event('change'));
+    classicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -193,7 +193,7 @@
   });
   TTT.action(function () {
     mathematicsFn().checked = true;
-    mathematicsFn().dispatchEvent(new Event('change'));
+    mathematicsFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -201,7 +201,7 @@
   });
   TTT.action(function () {
     classicFn().checked = false;
-    classicFn().dispatchEvent(new Event('change'));
+    classicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -222,7 +222,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     selectableNoneFn().checked = true;
-    selectableNoneFn().dispatchEvent(new Event('change'));
+    selectableNoneFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -230,7 +230,7 @@
   });
   TTT.action(function () {
     selectableMultiCascadeFn().checked = true;
-    selectableMultiCascadeFn().dispatchEvent(new Event('change'));
+    selectableMultiCascadeFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -238,7 +238,7 @@
   });
   TTT.action(function () {
     musicFn().checked = true;
-    musicFn().dispatchEvent(new Event('change'));
+    musicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse(); // an ajax request is send for every leaf (Music, Classic, Pop, World)
   TTT.waitMs(2000); // wait for the last ajax
@@ -247,7 +247,7 @@
   });
   TTT.action(function () {
     mathematicsFn().checked = true;
-    mathematicsFn().dispatchEvent(new Event('change'));
+    mathematicsFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -255,7 +255,7 @@
   });
   TTT.action(function () {
     classicFn().checked = false;
-    classicFn().dispatchEvent(new Event('change'));
+    classicFn().dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
index f3fd1ad..fe976fb 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
@@ -27,7 +27,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     textareaFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -45,7 +45,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     textareaFn().value = "some content";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -63,7 +63,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "a";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -80,7 +80,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "ab";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -97,7 +97,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "no number";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -114,7 +114,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "2";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -131,7 +131,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "78";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -148,7 +148,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "64";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -165,7 +165,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "T";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -182,7 +182,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "3";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -199,7 +199,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "T3";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -216,7 +216,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "java";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -233,7 +233,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "tobago";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
index 9e01a0e..029b4f2 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
@@ -26,7 +26,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -43,7 +43,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "some content";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -60,7 +60,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "a";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -77,7 +77,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "abc";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -94,7 +94,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = "abcde";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
index c884783..0221f0b 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
@@ -27,7 +27,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     form1InputFieldFn().value = "Alice";
-    form1SubmitButtonFn().click();
+    form1SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -53,7 +53,7 @@
     assert.equal(form2InputFieldFn().value, "");
   });
   TTT.action(function () {
-    form2SubmitButtonFn().click();
+    form2SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -78,7 +78,7 @@
     assert.equal(form2InputFieldFn().value, "Bob");
   });
   TTT.action(function () {
-    form2SubmitButtonFn().click();
+    form2SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -104,7 +104,7 @@
   TTT.action(function () {
     form2InputFieldFn().value = "";
     outerFormInputFieldFn().value = "";
-    outerFormSubmitButtonFn().click();
+    outerFormSubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
@@ -132,7 +132,7 @@
   TTT.action(function () {
     form2InputFieldFn().value = "";
     outerFormInputFieldFn().value = "Charlie";
-    outerFormSubmitButtonFn().click();
+    outerFormSubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
@@ -160,7 +160,7 @@
   TTT.action(function () {
     form2InputFieldFn().value = "Dave";
     outerFormInputFieldFn().value = "";
-    outerFormSubmitButtonFn().click();
+    outerFormSubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(5, function () {
@@ -188,7 +188,7 @@
     form1InputFieldFn().value = "Eve";
     form2InputFieldFn().value = "Frank";
     outerFormInputFieldFn().value = "Grace";
-    outerFormSubmitButtonFn().click();
+    outerFormSubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
index 308043a..cae9837 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
@@ -27,7 +27,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     form1InputFieldFn().value = "Alice";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -49,7 +49,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     form2InputFieldFn().value = "";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -69,7 +69,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     form2InputFieldFn().value = "Bob";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -99,7 +99,7 @@
     form1InputFieldFn().value = "Charlie";
     form2InputFieldFn().value = "";
     outerFormInputFieldFn().value = "";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -133,7 +133,7 @@
     form1InputFieldFn().value = "Dave";
     form2InputFieldFn().value = "";
     outerFormInputFieldFn().value = "Eve";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -167,7 +167,7 @@
     form1InputFieldFn().value = "Frank";
     form2InputFieldFn().value = "Grace";
     outerFormInputFieldFn().value = "";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -197,7 +197,7 @@
     form1InputFieldFn().value = "Hank";
     form2InputFieldFn().value = "Irene";
     outerFormInputFieldFn().value = "John";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -231,7 +231,7 @@
     form1InputFieldFn().value = "Kate";
     form2InputFieldFn().value = "";
     outerFormInputFieldFn().value = "Leonard";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -263,7 +263,7 @@
     form1InputFieldFn().value = "Mike";
     form2InputFieldFn().value = "Neil";
     outerFormInputFieldFn().value = "";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -297,7 +297,7 @@
     form1InputFieldFn().value = "Oscar";
     form2InputFieldFn().value = "Penny";
     outerFormInputFieldFn().value = "";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
@@ -330,7 +330,7 @@
     form1InputFieldFn().value = "Quin";
     form2InputFieldFn().value = "Sue";
     outerFormInputFieldFn().value = "Ted";
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(7, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
index 139c006..70af523 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
@@ -30,7 +30,7 @@
   TTT.action(function () {
     form1InputFieldFn().value = "Oliver";
     form2InputFieldFn().value = "Peter";
-    form1SubmitButtonFn().click();
+    form1SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -54,7 +54,7 @@
   TTT.action(function () {
     form1InputFieldFn().value = "Oliver";
     form2InputFieldFn().value = "Peter";
-    form2SubmitButtonFn().click();
+    form2SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
index 1e2ead6..fc6e743 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
@@ -29,7 +29,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    resetFn().click();
+    resetFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -40,7 +40,7 @@
     nameFn().value = "Mississippi";
     lengthFn().value = "6275";
     dischargeFn().value = "16200";
-    addFn().click();
+    addFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -48,7 +48,7 @@
     assert.equal(uiRepeatSectionsFn().length, 4);
   });
   TTT.action(function () {
-    resetFn().click();
+    resetFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
index 3fa4388..f6c59fb 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
@@ -25,14 +25,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.ok(contentFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -48,14 +48,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(contentFn(), null);
   });
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -73,7 +73,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    show1Fn().click();
+    show1Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -81,7 +81,7 @@
     assert.equal(content2Fn().length, content2Length);
   });
   TTT.action(function () {
-    show2Fn().click();
+    show2Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -100,7 +100,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    show1Fn().click();
+    show1Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -108,7 +108,7 @@
     assert.equal(content2Fn().length, content2Length);
   });
   TTT.action(function () {
-    hide2Fn().click();
+    hide2Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -127,7 +127,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hide1Fn().click();
+    hide1Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -135,7 +135,7 @@
     assert.equal(content2Fn() !== null, existContent2);
   });
   TTT.action(function () {
-    show2Fn().click();
+    show2Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -154,7 +154,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hide1Fn().click();
+    hide1Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -162,7 +162,7 @@
     assert.equal(content2Fn() !== null, existContent2);
   });
   TTT.action(function () {
-    hide2Fn().click();
+    hide2Fn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -179,13 +179,13 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(boxFn().classList.contains("tobago-collapsed"), false);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(boxFn().classList.contains("tobago-collapsed"), true);
@@ -200,13 +200,13 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(boxFn().classList.contains("tobago-collapsed"), true);
   });
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(boxFn().classList.contains("tobago-collapsed"), false);
@@ -224,14 +224,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(boxFn().classList.contains("tobago-collapsed"), true);
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -247,14 +247,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -270,14 +270,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -295,7 +295,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -303,14 +303,14 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/10-collapsible-popup/Collapsible_Popup.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/10-collapsible-popup/Collapsible_Popup.test.js
index e5b3d3c..bf85409 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/10-collapsible-popup/Collapsible_Popup.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/10-collapsible-popup/Collapsible_Popup.test.js
@@ -28,7 +28,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    openFn().click();
+    openFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -36,7 +36,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -46,7 +46,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -55,14 +55,14 @@
     assert.equal(inFn().value, "");
   });
   TTT.action(function () {
-    closeFn().click();
+    closeFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitOnPageFn().click();
+    submitOnPageFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -81,7 +81,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    openFn().click();
+    openFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -89,7 +89,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -99,7 +99,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -108,14 +108,14 @@
     assert.equal(inFn().value, "");
   });
   TTT.action(function () {
-    closeFn().click();
+    closeFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitOnPageFn().click();
+    submitOnPageFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -135,26 +135,26 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    openFn().click();
+    openFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupCollapsedFn().value, "false");
   });
   TTT.action(function () {
-    closeFn().click();
+    closeFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupCollapsedFn().value, "true");
   });
   TTT.action(function () {
-    openFn().click();
+    openFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupCollapsedFn().value, "false");
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -162,14 +162,14 @@
     assert.equal(popupCollapsedFn().value, "true");
   });
   TTT.action(function () {
-    openFn().click();
+    openFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.equal(popupCollapsedFn().value, "false");
   });
   TTT.action(function () {
     inFn().value = "";
-    submitOnPopupFn().click();
+    submitOnPopupFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -177,7 +177,7 @@
     assert.equal(popupCollapsedFn().value, "true");
   });
   TTT.action(function () {
-    submitOnPageFn().click();
+    submitOnPageFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
index cdd3275..b5d2d57 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
@@ -28,7 +28,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -37,7 +37,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -47,7 +47,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -56,7 +56,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -65,7 +65,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -86,7 +86,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -95,7 +95,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -105,7 +105,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -114,7 +114,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -123,7 +123,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -144,7 +144,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.equal(panelCollapsedFn().value, "false");
@@ -152,7 +152,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -162,7 +162,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -171,7 +171,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(3, function () {
     assert.equal(messagesFn().length, 1);
@@ -179,7 +179,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -200,7 +200,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -209,7 +209,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -219,7 +219,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -228,7 +228,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -236,7 +236,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
index 629f67f..8682f1f 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
@@ -28,7 +28,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -37,7 +37,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -47,7 +47,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -56,7 +56,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -65,7 +65,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -86,7 +86,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -95,7 +95,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -105,7 +105,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -114,7 +114,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -123,7 +123,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -144,7 +144,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(2, function () {
     assert.equal(sectionCollapsedFn().value, "false");
@@ -152,7 +152,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -162,7 +162,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -171,7 +171,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(3, function () {
     assert.equal(messagesFn().length, 1);
@@ -179,7 +179,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -200,7 +200,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    showFn().click();
+    showFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -209,7 +209,7 @@
   });
   TTT.action(function () {
     inFn().value = "some text";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -219,7 +219,7 @@
   });
   TTT.action(function () {
     inFn().value = "";
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
@@ -228,7 +228,7 @@
     assert.ok(inFn() !== null);
   });
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
@@ -236,7 +236,7 @@
     assert.equal(inFn(), null);
   });
   TTT.action(function () {
-    submitFn().click();
+    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/75-resize/Resize.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/75-resize/Resize.xhtml
index d8471f8..b4d9b4c 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/75-resize/Resize.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/75-resize/Resize.xhtml
@@ -27,10 +27,19 @@
     <tc:link id="resize" action="#{resizeController.resize}"/>
   </f:facet>
 
-  <!--todo-->
-  Todo: make nicer example
-  <br/>
+  <tc:panel>
+    <tc:event event="click" action="#{resizeController.resize}">
+      <f:ajax/>
+    </tc:event>
 
-  Resizing demo. Resizing the window will call a command (from the resize facet).
+    Please to a resize of the browser window and look in the server logs to check the resize actions...
+    <br/>
+
+    <!--todo-->
+    Todo: make nicer example
+    <br/>
+
+    Resizing demo. Resizing the window will call a command (from the resize facet).
+  </tc:panel>
 
 </ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/35-deprecated/15-suggest-method/Suggest_Method.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/35-deprecated/15-suggest-method/Suggest_Method.test.js
index 69baf98..c3d87da 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/35-deprecated/15-suggest-method/Suggest_Method.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/35-deprecated/15-suggest-method/Suggest_Method.test.js
@@ -28,7 +28,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = inputString;
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(expectedLength + 1, function () {
@@ -50,7 +50,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = inputString;
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(expectedLength + 1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1020-suggest-quotMark/Suggest_QuotMark.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1020-suggest-quotMark/Suggest_QuotMark.test.js
index eab97ce..2cfeae4 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1020-suggest-quotMark/Suggest_QuotMark.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1020-suggest-quotMark/Suggest_QuotMark.test.js
@@ -53,7 +53,7 @@
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
     inFn().value = inputString;
-    inFn().dispatchEvent(new Event('input'));
+    inFn().dispatchEvent(new Event("input", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(expectedLength + 1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1040-date/Date.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1040-date/Date.test.js
index 209081a..dd0f42a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1040-date/Date.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1040-date/Date.test.js
@@ -26,7 +26,7 @@
   let datepickerFn = testFrameQuerySelectorAllFn(".bootstrap-datetimepicker-widget");
   assert.notOk(datepickerFn().item(0));
 
-  dateButtonFn().click();
+  dateButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
 
   datepickerFn = testFrameQuerySelectorAllFn(".bootstrap-datetimepicker-widget");
   assert.ok(datepickerFn().item(0));
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1041-date-tobagoConverter/Date_TobagoConverter.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1041-date-tobagoConverter/Date_TobagoConverter.test.js
index 856aac8..d3907d8 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1041-date-tobagoConverter/Date_TobagoConverter.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/1041-date-tobagoConverter/Date_TobagoConverter.test.js
@@ -220,7 +220,7 @@
   });
   TTT.action(function () {
         inputFn().value = inputValue;
-        submitButtonFn().click();
+        submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
       }
   );
   TTT.waitForResponse();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/4050-ajax-dropdown/Ajax_Dropdown.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/4050-ajax-dropdown/Ajax_Dropdown.test.js
index fa01e57..bf4502f 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/4050-ajax-dropdown/Ajax_Dropdown.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/4050-ajax-dropdown/Ajax_Dropdown.test.js
@@ -31,7 +31,7 @@
     assert.ok(tobagoPageMenuStoreFn().querySelector(ajaxEntryId) === null, "Dropdown menu should be closed.");
   });
   TTT.action(function () {
-    dropdownMenuButtonFn().click();
+    dropdownMenuButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.asserts(1, function () {
     assert.ok(tobagoPageMenuStoreFn().querySelector(ajaxEntryId) !== null, "Dropdown menu should be opened.");
@@ -43,7 +43,7 @@
     assert.equal(outputFn().textContent, "", "Output should be empty.");
   });
   TTT.action(function () {
-    ajaxEntryFn().click();
+    ajaxEntryFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/Button_Link.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/Button_Link.test.js
index 3dedd25..356946d 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/Button_Link.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4000-button-link/Button_Link.test.js
@@ -47,14 +47,14 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    commandFn().click();
+    commandFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
     assert.ok(destinationSectionFn() !== null);
   });
   TTT.action(function () {
-    backFn().click();
+    backFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -98,7 +98,7 @@
 function testTargetCommands(commandFn, expectedText, assert) {
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    commandFn().click();
+    commandFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitMs(2000); //TobagoTestTools.waitForResponse() didn't recognize responses on a target frame, so we just wait
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
index 3fd6803..b572d5a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
@@ -83,7 +83,7 @@
     assert.ok(section2HeaderFn() !== null);
   });
   TTT.action(function () {
-    reloadButtonFn().click();
+    reloadButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(2, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4600-gridLayout/90-style-tag/Style_Tag.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4600-gridLayout/90-style-tag/Style_Tag.test.js
index 361a35a..1dbdd57 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4600-gridLayout/90-style-tag/Style_Tag.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4600-gridLayout/90-style-tag/Style_Tag.test.js
@@ -27,7 +27,7 @@
     assert.ok(outputFn().classList.contains("text-warning"));
   });
   TTT.action(function () {
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4950-severity/Severity.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4950-severity/Severity.test.js
index 5e9409e..68443fa 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4950-severity/Severity.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/4950-severity/Severity.test.js
@@ -31,7 +31,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    submitButtonFn().click();
+    submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(8, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/20-ajax-execute/Ajax_Execute.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/20-ajax-execute/Ajax_Execute.test.js
index 9178dab..c3245fc 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/20-ajax-execute/Ajax_Execute.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/20-ajax-execute/Ajax_Execute.test.js
@@ -33,7 +33,7 @@
     in2Fn().value = "b";
     in3Fn().value = "c";
     in4Fn().value = "d";
-    clearButtonFn().click();
+    clearButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -47,7 +47,7 @@
     in2Fn().value = "b";
     in3Fn().value = "c";
     in4Fn().value = "d";
-    submitButtonFn().click();
+    submitButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
@@ -57,7 +57,7 @@
     assert.equal(in4Fn().value, "");
   });
   TTT.action(function () {
-    reloadButtonFn().click();
+    reloadButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(4, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
index a02891d..227248c 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
@@ -30,7 +30,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(3, function () {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/Event.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/Event.test.js
index afa7a5c..66c9eab 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/Event.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6000-event/Event.test.js
@@ -151,7 +151,7 @@
       Array.prototype.forEach.call(buttons, function (element, i) {
         let id = element.getAttribute("id");
         if (id !== undefined && id.indexOf(eventName + "Behavior") >= 0) {
-          element.click();
+          element.dispatchEvent(new Event("click", {bubbles: true}));
         }
       });
     }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6500-behavior/Behavior.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6500-behavior/Behavior.test.js
index 56833c4..dfb4c79 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6500-behavior/Behavior.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/6500-behavior/Behavior.test.js
@@ -24,7 +24,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(11, function () {
@@ -39,7 +39,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(11, function () {
@@ -54,7 +54,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    buttonFn().click();
+    buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(11, function () {
@@ -116,7 +116,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -127,7 +127,7 @@
     optionsFn().item(1).checked = false;
     optionsFn().item(2).checked = false;
     optionsFn().item(optionId).checked = true;
-    optionsFn().item(optionId).dispatchEvent(new Event('change'));
+    optionsFn().item(optionId).dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.action(function () {
@@ -158,7 +158,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
@@ -169,7 +169,7 @@
     optionsFn().item(1).checked = false;
     optionsFn().item(2).checked = false;
     optionsFn().item(optionId).checked = true;
-    optionsFn().item(optionId).dispatchEvent(new Event('change'));
+    optionsFn().item(optionId).dispatchEvent(new Event("change", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.action(function () {
@@ -194,7 +194,7 @@
 
   let TTT = new TobagoTestTool(assert);
   TTT.action(function () {
-    hideFn().click();
+    hideFn().dispatchEvent(new Event("click", {bubbles: true}));
   });
   TTT.waitForResponse();
   TTT.asserts(1, function () {
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-calendar.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-calendar.ts
index b5dfa36..a3d896a 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-calendar.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-calendar.ts
@@ -17,7 +17,7 @@
 
 import {Listener, Phase} from "./tobago-listener";
 import {DomUtils} from "./tobago-utils";
-import {Command} from "./tobago-command";
+import {CommandHelper} from "./tobago-command";
 
 class DateTime {
 
@@ -169,7 +169,9 @@
                   render: commands.change.render
                 });
           } else if (commands.change.action) {
-            Command.submitAction(this.firstElementChild, commands.change.action, commands.change);
+            CommandHelper.submitAction(
+                this.firstElementChild as HTMLElement,
+                commands.change.action, commands.change.transition, commands.change.target);
           }
         }
       });
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.test.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.test.ts
deleted file mode 100644
index 7de9ada..0000000
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.test.ts
+++ /dev/null
@@ -1,40 +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.
- */
-
-import {Command, CommandMap} from "./tobago-command";
-
-test('class Command: string', () => {
-  let command = new Command('{"omit":false,"execute":"execute-id"}');
-  expect(command.omit).toBe(false);
-  expect(command.stringify()).toBe('{"omit":false,"execute":"execute-id"}');
-});
-
-test('class Command: object', () => {
-  let command = new Command({"omit": false, "execute": "execute-id"});
-  expect(command.omit).toBe(false);
-  expect(command.stringify()).toBe('{"omit":false,"execute":"execute-id"}');
-});
-
-test('class CommandMap: click', () => {
-  let commands = new CommandMap('{"click":{"omit":false}}');
-  expect(commands.stringify()).toBe('{"commands":{"click":{"omit":false}}}');
-});
-
-test('class CommandMap: change', () => {
-  let commands = new CommandMap('{"change":{"action":"page:header:j_id_k"}}');
-  expect(commands.stringify()).toBe('{"commands":{"change":{"action":"page:header:j_id_k"}}}');
-});
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
index 94dcca6..409b182 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
@@ -15,196 +15,232 @@
  * limitations under the License.
  */
 
-import {Listener, Order, Phase} from "./tobago-listener";
+import {Listener, Phase} from "./tobago-listener";
 import {Overlay} from "./tobago-overlay";
 import {DomUtils, Tobago4Utils} from "./tobago-utils";
-import {Collapse, Popup} from "./tobago-popup";
+import {Collapse} from "./tobago-popup";
 import {Setup} from "./tobago-core";
 
-export class CommandMap {
+class Behavior extends HTMLElement {
 
-  commands: Map<string, Command>;
-
-  // XXX remove me later... may be, if using "Custom Elements"
-  /** @deprecated */
-  public static getData(element: HTMLElement, eventType: string): Command {
-    const commandMap: CommandMap = new CommandMap(element.dataset["tobagoCommands"]);
-    return commandMap.commands.get(eventType);
+  constructor() {
+    super();
   }
 
-  static change(event: TextEvent) {
-    const element = event.currentTarget as HTMLElement;
-    const change = CommandMap.getData(element, "change");
+  connectedCallback() {
+    switch (this.event) {
+      case "load": // this is a special case, because the "load" is too late now.
+        this.callback();
+        break;
+      case "resize":
+        document.body.addEventListener(this.event, this.callback.bind(this));
+        break;
+      default:
+        this.parentElement.addEventListener(this.event, this.callback.bind(this));
+    }
+  }
 
-    if (change.execute || change.render) {
+  callback(event?: Event) {
+
+    if (this.collapseAction && this.collapseTarget) {
+      const target = this.getRootNode() as ShadowRoot | Document;
+      Collapse.execute(this.collapseAction, target.getElementById(this.collapseTarget));
+    }
+
+    if (this.execute || this.render) { // this means: AJAX case?
+      if (this.render) {
+        // prepare overlay for all by AJAX reloaded elements
+        let partialIds = this.render.split(" ");
+        for (let i = 0; i < partialIds.length; i++) {
+          new Overlay(document.getElementById(partialIds[i]), true);
+        }
+      }
       jsf.ajax.request(
-          element.getAttribute("name"),
-          event,
-          {
-            "javax.faces.behavior.event": "change",
-            execute: change.execute,
-            render: change.render
+          this.parentElement,
+          event, {
+            //"javax.faces.behavior.event": this.event,
+            execute: this.execute,
+            render: this.render
           });
     } else {
-      Command.submitAction(this, change.action, change);
-    }
-  }
-
-  static resize(event: Event) { // TBD MouseEvent?
-    const element = event.currentTarget as HTMLElement;
-    const resize = CommandMap.getData(element, "resize");
-    console.debug("window resize event: " + resize);
-    Command.submitAction(this, resize.action, resize);
-  }
-
-  static otherEvent(event: Event) {
-    const element = event.currentTarget as HTMLElement;
-    const command = CommandMap.getData(element, event.type);
-
-    const confirmation = command.confirmation;
-    if (confirmation) {
-      if (!confirm(confirmation)) {
-        event.preventDefault();
-        return;
-      }
-    }
-    const collapse = command.collapse;
-    if (collapse) {
-      Collapse.execute(collapse);
-    }
-
-    if (!command.omit) {
-      const popup = command.popup;
-      if (popup && popup.command === "close" && popup.immediate) {
-        Popup.close(element);
-      } else {
-        const action = command.action ? command.action : element.id;
-        if (command.execute || command.render) {
-          Command.preparePartialOverlay(command);
-          jsf.ajax.request(
-              action,
-              event,
-              {
-                "javax.faces.behavior.event": event.type,
-                execute: command.execute,
-                render: command.render
-              });
-        } else {
-          Command.submitAction(this, action, command);
-        }
-        if (popup && popup.command === "close") {
-          Popup.close(element);
-        }
+      if (!this.omit) {
+        setTimeout(this.submit.bind(this), this.delay);
       }
     }
   }
 
-  constructor(data: string) {
-    this.commands = new Map<string, Command>();
-    const object = JSON.parse(data);
-    for (let key of Object.keys(object)) {
-      const command5 = new Command(object[key]);
-      this.commands.set(key, command5);
+  submit() {
+    const actionId = this.action != null ? this.action : this.element.id;
+    CommandHelper.submitAction(this, actionId, !this.decoupled, this.target);
+  }
+
+  get event(): string {
+    return this.getAttribute("event");
+  }
+
+  set event(event: string) {
+    this.setAttribute("event", event);
+  }
+
+  get action(): string {
+    return this.getAttribute("action");
+  }
+
+  set action(action: string) {
+    this.setAttribute("action", action);
+  }
+
+  get execute(): string {
+    return this.getAttribute("execute");
+  }
+
+  set execute(execute: string) {
+    this.setAttribute("execute", execute);
+  }
+
+  get render(): string {
+    return this.getAttribute("render");
+  }
+
+  set render(render: string) {
+    this.setAttribute("render", render);
+  }
+
+  get delay(): number {
+    return parseInt(this.getAttribute("delay")) || 0;
+  }
+
+  set delay(delay: number) {
+    this.setAttribute("delay", String(delay));
+  }
+
+  get omit(): boolean {
+    return this.hasAttribute("omit");
+  }
+
+  set omit(omit: boolean) {
+    if (omit) {
+      this.setAttribute("omit", "");
+    } else {
+      this.removeAttribute("omit");
     }
   }
 
-  get change() {
-    return this.commands.get("change");
+  get target(): string {
+    return this.getAttribute("target");
   }
 
-  get complete() {
-    return this.commands.get("complete");
+  set target(target: string) {
+    this.setAttribute("target", target);
   }
 
-  get load() {
-    return this.commands.get("load");
+  get confirmation(): string {
+    return this.getAttribute("confirmation");
   }
 
-  get resize() {
-    return this.commands.get("resize");
+  set confirmation(confirmation: string) {
+    this.setAttribute("confirmation", confirmation);
   }
 
-  public stringify(): string {
-    let object = Object.create(null);
-    for (let [k, v] of this.commands) {
-      object[k] = v;
+  get collapseAction(): string {
+    return this.getAttribute("collapse-action");
+  }
+
+  set collapseAction(collapseAction: string) {
+    this.setAttribute("collapse-action", collapseAction);
+  }
+
+  get collapseTarget(): string {
+    return this.getAttribute("collapse-target");
+  }
+
+  set collapseTarget(collapseTarget: string) {
+    this.setAttribute("collapse-target", collapseTarget);
+  }
+
+  get decoupled(): boolean {
+    return this.hasAttribute("decoupled");
+  }
+
+  set decoupled(decoupled: boolean) {
+    if (decoupled) {
+      this.setAttribute("decoupled", "");
+    } else {
+      this.removeAttribute("decoupled");
     }
-    const outer = JSON.stringify(this);
-    // remove {} and replace with object-JSON
-    return outer.substring(0, outer.length - 3) + JSON.stringify(object) + "}";
+  }
+
+  get focusId(): string {
+    return this.getAttribute("focus-id");
+  }
+
+  set focusId(focusId: string) {
+    this.setAttribute("focus-id", focusId);
+  }
+
+  get element(): HTMLElement {
+    return this.parentElement;
   }
 }
 
-export class Command {
+document.addEventListener("DOMContentLoaded", function (event) {
+  window.customElements.define('tobago-behavior', Behavior);
+});
 
-  // XXX this is a state of the page
+export class CommandHelper {
   static isSubmit: boolean = false;
 
-  confirmation: string;
-  collapse: boolean; // XXX is boolean okay??? Should this be not an element or a structure?
-  omit: boolean;
-  popup; // todo: type
-  action: string;
-  execute: string;
-  render: string;
-  transition: boolean;
-  delay: number;
-  target: string;
-
   /**
    * Submitting the page with specified actionId.
-   * options.transition
-   * options.target
+   * @param source
+   * @param actionId
+   * @param decoupled
+   * @param target
    */
-  public static submitAction = function (source: any, actionId: string, command: Command = new Command()) {
-
-    let transition = command.transition === undefined || command.transition;
+  public static submitAction = function (source: HTMLElement, actionId: string, decoupled: boolean = true, target?: string) {
 
     Transport.request(function () {
-      if (!Command.isSubmit) {
-        Command.isSubmit = true;
+      if (!CommandHelper.isSubmit) {
+        CommandHelper.isSubmit = true;
         const form = document.getElementsByTagName("form")[0] as HTMLFormElement;
-        var oldTarget = form.getAttribute("target");
+        const oldTarget = form.getAttribute("target");
         const sourceHidden = document.getElementById("javax.faces.source") as HTMLInputElement;
         sourceHidden.disabled = false;
         sourceHidden.value = actionId;
-        if (command.target) {
-          form.setAttribute("target", command.target);
+        if (target) {
+          form.setAttribute("target", target);
         }
-        this.oldTransition = this.transition;
-        this.transition = transition && !command.target;
-
         var listenerOptions = {
           source: source,
-          actionId: actionId,
-          options: command
+          actionId: actionId/*,
+          options: commandHelper*/
         };
-        var onSubmitResult = Command.onSubmit(listenerOptions);
+        var onSubmitResult = CommandHelper.onSubmit(listenerOptions);
         if (onSubmitResult) {
           try {
             form.submit();
-            // reset the source field after submit, to be prepared for possible next AJAX with transition=false
+            // reset the source field after submit, to be prepared for possible next AJAX with decoupled=true
             sourceHidden.disabled = true;
             sourceHidden.value = "";
           } catch (e) {
             Overlay.destroy(DomUtils.page().id);
-            Command.isSubmit = false;
+            CommandHelper.isSubmit = false;
             alert('Submit failed: ' + e); // XXX localization, better error handling
           }
         }
-        if (command.target) {
+        if (target) {
           if (oldTarget) {
             form.setAttribute("target", oldTarget);
           } else {
             form.removeAttribute("target");
           }
         }
-        if (command.target || !transition || !onSubmitResult) {
-          Command.isSubmit = false;
+        if (target || decoupled || !onSubmitResult) {
+          CommandHelper.isSubmit = false;
           Transport.pageSubmitted = false;
         }
       }
-      if (!Command.isSubmit) {
+      if (!CommandHelper.isSubmit) {
         Transport.requestComplete(); // remove this from queue
       }
     }, true);
@@ -243,52 +279,6 @@
     }
   }
 
-  static init = function (element: HTMLElement) {
-
-    for (const commandElement of DomUtils.selfOrQuerySelectorAll(element, "[data-tobago-commands]")) {
-
-      const commandMap = new CommandMap(commandElement.dataset["tobagoCommands"]);
-
-      for (const entry of commandMap.commands.entries()) {
-        const key: string = entry[0];
-        const value: Command = entry[1];
-
-        switch (key) {
-          case "change":
-            commandElement.addEventListener("change", CommandMap.change);
-            break;
-          case "complete":
-            if (parseFloat(commandElement.getAttribute("value")) >= parseFloat(commandElement.getAttribute("max"))) {
-              if (commandMap.complete.execute || commandMap.complete.render) {
-                jsf.ajax.request(
-                    this.id,
-                    null,
-                    {
-                      "javax.faces.behavior.event": "complete",
-                      execute: commandMap.complete.execute,
-                      render: commandMap.complete.render
-                    });
-              } else {
-                Command.submitAction(this, commandMap.complete.action, commandMap.complete);
-              }
-            }
-            break;
-          case "load":
-            setTimeout(function () {
-                  Command.submitAction(this, commandMap.load.action, commandMap.load);
-                },
-                commandMap.load.delay || 100);
-            break;
-          case "resize":
-            window.addEventListener("resize", CommandMap.resize);
-            break;
-          default:
-            commandElement.addEventListener(key, CommandMap.otherEvent);
-        }
-      }
-    }
-  };
-
   static onSubmit = function (listenerOptions) {
     Listener.executeBeforeSubmit();
     /*
@@ -311,48 +301,16 @@
           return false;
         }
     */
-    Command.isSubmit = true;
+    CommandHelper.isSubmit = true;
 
     Setup.onBeforeUnload();
 
     return true;
   };
 
-  static preparePartialOverlay = function (command: Command) {
-    if (command.transition === undefined || command.transition == null || command.transition) {
-      console.debug("[tobago-command] render: '" + command.render + "'");
-      if (command.render) {
-        let partialIds = command.render.split(" ");
-        for (let i = 0; i < partialIds.length; i++) {
-          new Overlay(document.getElementById(partialIds[i]), true);
-        }
-      }
-    }
-  };
-
-  constructor(data?: string | object) {
-    let object;
-    if (data) {
-      if (typeof data === "string") {
-        object = JSON.parse(data);
-      } else {
-        object = data;
-      }
-      for (let key of Object.keys(object)) {
-        this[key] = object[key];
-      }
-    }
-  }
-
-  public stringify(): string {
-    return JSON.stringify(this);
-  }
 }
 
-Listener.register(Command.initEnter, Phase.DOCUMENT_READY);
-
-Listener.register(Command.init, Phase.DOCUMENT_READY, Order.LATER);
-Listener.register(Command.init, Phase.AFTER_UPDATE, Order.LATER);
+Listener.register(CommandHelper.initEnter, Phase.DOCUMENT_READY);
 
 class Transport {
   static requests = [];
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-core.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-core.ts
index a81648d..bf5953c 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-core.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-core.ts
@@ -18,7 +18,7 @@
 import {Listener} from "./tobago-listener";
 import {Overlay} from "./tobago-overlay";
 import {DomUtils} from "./tobago-utils";
-import {Command} from "./tobago-command";
+import {CommandHelper} from "./tobago-command";
 
 /**
  * @deprecated since 5.0.0
@@ -44,7 +44,7 @@
 
   static init = function() {
     console.time("[tobago] init");
-    document.querySelector("form").addEventListener('submit', Command.onSubmit);
+    document.querySelector("form").addEventListener('submit', CommandHelper.onSubmit);
     window.addEventListener('unload', Setup.onUnload);
     Listener.executeDocumentReady(document.documentElement);
     console.timeEnd("[tobago] init");
@@ -62,7 +62,7 @@
    */
   static onUnload = function () {
     console.info('on onload');
-    if (Command.isSubmit) {
+    if (CommandHelper.isSubmit) {
       if (Setup.transition) {
         new Overlay(DomUtils.page());
       }
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-popup.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-popup.ts
index be593f4..d72f611 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-popup.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-popup.ts
@@ -53,13 +53,11 @@
     return document.getElementById(element.id + "::collapse") as HTMLInputElement;
   }
 
-  static execute = function (collapse) {
-    const transition = collapse.transition;
-    const forElement = document.getElementById(collapse.forId);
-    const hidden = Collapse.findHidden(forElement);
-    const isPopup = forElement.tagName === "TOBAGO-POPUP";
+  static execute = function (action: string, target: HTMLElement) {
+    const hidden = Collapse.findHidden(target);
+    const isPopup = target.tagName === "TOBAGO-POPUP";
     let newCollapsed;
-    switch (transition) {
+    switch (action) {
       case "hide":
         newCollapsed = true;
         break;
@@ -67,19 +65,19 @@
         newCollapsed = false;
         break;
       default:
-        console.error("unknown transition: '" + transition + "'");
+        console.error("unknown action: '" + action + "'");
     }
     if (newCollapsed) {
       if (isPopup) {
-        BootstrapUtils.modal(forElement, "hide");
+        BootstrapUtils.modal(target, "hide");
       } else {
-        forElement.classList.add("tobago-collapsed");
+        target.classList.add("tobago-collapsed");
       }
     } else {
       if (isPopup) {
-        BootstrapUtils.modal(forElement, "show");
+        BootstrapUtils.modal(target, "show");
       } else {
-        forElement.classList.remove("tobago-collapsed");
+        target.classList.remove("tobago-collapsed");
       }
     }
     hidden.value = newCollapsed;
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-scroll.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-scroll.ts
index 974f68e..9a440f0 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-scroll.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-scroll.ts
@@ -15,10 +15,8 @@
  * limitations under the License.
  */
 
-import {Listener, Phase, Order} from "./tobago-listener";
-import {Overlay} from "./tobago-overlay";
-import {DomUtils, Tobago4Utils} from "./tobago-utils";
-import {Command} from "./tobago-command";
+import {Listener, Order, Phase} from "./tobago-listener";
+import {DomUtils} from "./tobago-utils";
 
 class Scroll {
 
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-sheet.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-sheet.ts
index 6a252b8..2ed1b61 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-sheet.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-sheet.ts
@@ -17,7 +17,7 @@
 
 import {Listener, Phase} from "./tobago-listener";
 import {DomUtils} from "./tobago-utils";
-import {Command} from "./tobago-command";
+import {CommandHelper} from "./tobago-command";
 
 class Sheet {
 
@@ -436,7 +436,7 @@
                 render: clickRenderIds
               });
         } else {
-          Command.submitAction(row, action);
+          CommandHelper.submitAction(row, action);
         }
       }
     }
@@ -536,7 +536,7 @@
               render: this.dblClickReloadComponentId
             });
       } else {
-        Command.submitAction(row, action);
+        CommandHelper.submitAction(row, action);
       }
     }
   }
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
index 47a1606..8a164b2 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
@@ -15,8 +15,6 @@
  * limitations under the License.
  */
 
-import {Command} from "./tobago-command";
-
 class TabGroup extends HTMLElement {
 
   private hiddenInput: HTMLInputElement;
@@ -88,16 +86,10 @@
         this.content.classList.add("active");
         break;
       case "reloadTab":
-        jsf.ajax.request(
-            this.navLink,
-            event, {
-              //"javax.faces.behavior.event": "click",
-              execute: tabGroup.id,
-              render: tabGroup.id
-            });
+        // will be done by <tobago-behavior>
         break;
       case "reloadPage":
-        Command.submitAction(this.navLink, this.id);
+        // will be done by <tobago-behavior>
         break;
       case "none": // todo
         console.error("Not implemented yet: %s", tabGroup.switchType);