You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2021/01/22 12:19:38 UTC
[myfaces-tobago] 01/02: fix: SelectOneChoice inside input group
This is an automated email from the ASF dual-hosted git repository.
hnoeth pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
commit 08b8dc3a743b78d07d6d15669b7280d71d1bf3dc
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Mon Jan 18 15:28:30 2021 +0100
fix: SelectOneChoice inside input group
* add a getComponentCss() method for LabelLayoutRendererBase
* selectOneChoice is now rendered with surrounding container (tobago-select-one-choice) inside input group
* fix styling
* adjust unit test
* implement jasmine test
---
tobago-core/npm/scss/_tobago.scss | 21 ++++
.../renderer/LabelLayoutRendererBase.java | 10 +-
.../renderer/SelectOneChoiceRenderer.java | 22 ++--
.../renderer/in/input-group-choice-after.html | 14 ++-
.../010-input/50-input-group/Group.test.js | 134 +++++++++------------
5 files changed, 103 insertions(+), 98 deletions(-)
diff --git a/tobago-core/npm/scss/_tobago.scss b/tobago-core/npm/scss/_tobago.scss
index 10ad37d..12e9da7 100644
--- a/tobago-core/npm/scss/_tobago.scss
+++ b/tobago-core/npm/scss/_tobago.scss
@@ -452,6 +452,27 @@ tobago-header {
/* in ----------------------------------------------------------- */
tobago-in {
display: block;
+
+ .input-group {
+
+ tobago-select-one-choice {
+ /* fix style for surrounding container (tobago-select-one-choice).
+ According to bootstrap docs, <select class=.form-select> should be rendered directly to .input-group. But tobago
+ renders the tobago-select-one-choice custom tag (which contain the select component) inside an input group. */
+
+ &.tobago-margin-bottom {
+ margin-bottom: 0;
+ }
+
+ &.form-select {
+ padding: 0;
+
+ > .form-select {
+ border: 0;
+ }
+ }
+ }
+ }
}
.tobago-in {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
index 1ce106f..33ed746 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
@@ -29,6 +29,7 @@ import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.internal.util.StringUtils;
import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
@@ -49,6 +50,10 @@ public abstract class LabelLayoutRendererBase<T extends UIComponent & SupportsLa
public abstract HtmlElements getComponentTag();
+ protected CssItem[] getComponentCss(final FacesContext facesContext, final T command) {
+ return null;
+ }
+
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
@@ -152,7 +157,8 @@ public abstract class LabelLayoutRendererBase<T extends UIComponent & SupportsLa
writer.startElement(getComponentTag());
writer.writeIdAttribute(clientId);
writer.writeClassAttribute(
- flex ? TobagoClass.LABEL__CONTAINER : null,
+ flex ? TobagoClass.LABEL__CONTAINER : null,
+ getComponentCss(facesContext, component),
TobagoClass.MARGIN__BOTTOM,
ComponentUtils.getBooleanAttribute(component, Attributes.required) ? TobagoClass.REQUIRED : null,
markup != null && markup.contains(Markup.SPREAD) ? TobagoClass.SPREAD : null);
@@ -224,7 +230,7 @@ public abstract class LabelLayoutRendererBase<T extends UIComponent & SupportsLa
}
protected void encodeLabel(final FacesContext facesContext, final T component,
- final TobagoResponseWriter writer, final LabelLayout labelLayout)
+ final TobagoResponseWriter writer, final LabelLayout labelLayout)
throws IOException {
// TBD: maybe use an interface for getLabel()
final String label = ComponentUtils.getStringAttribute(component, Attributes.label);
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 d839dd8..6804e79 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
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneChoice;
import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -41,21 +42,18 @@ public class SelectOneChoiceRenderer<T extends AbstractUISelectOneChoice> extend
}
@Override
+ protected CssItem[] getComponentCss(final FacesContext facesContext, final T command) {
+ return isInside(facesContext, HtmlElements.TOBAGO_IN) ? new CssItem[]{BootstrapClass.FORM_SELECT} : null;
+ }
+
+ @Override
public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
- if (isInside(facesContext, HtmlElements.TOBAGO_IN)) {
- encodeBeginField(facesContext, component);
- } else {
- super.encodeBeginInternal(facesContext, component);
- }
+ super.encodeBeginInternal(facesContext, component);
}
@Override
public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
- if (isInside(facesContext, HtmlElements.TOBAGO_IN)) {
- encodeEndField(facesContext, component);
- } else {
- super.encodeEndInternal(facesContext, component);
- }
+ super.encodeEndInternal(facesContext, component);
}
@Override
@@ -105,8 +103,6 @@ public class SelectOneChoiceRenderer<T extends AbstractUISelectOneChoice> extend
@Override
protected String getFieldId(final FacesContext facesContext, final T component) {
- return isInside(facesContext, HtmlElements.TOBAGO_IN)
- ? component.getClientId(facesContext)
- : component.getFieldId(facesContext);
+ return component.getFieldId(facesContext);
}
}
diff --git a/tobago-core/src/test/resources/renderer/in/input-group-choice-after.html b/tobago-core/src/test/resources/renderer/in/input-group-choice-after.html
index ee030ff..d85c6e7 100644
--- a/tobago-core/src/test/resources/renderer/in/input-group-choice-after.html
+++ b/tobago-core/src/test/resources/renderer/in/input-group-choice-after.html
@@ -19,11 +19,13 @@
<div class='tobago-input-group-outer'>
<div class='input-group'>
<input type='text' name='id' id='id::field' class='tobago-in form-control'>
- <select id='choice' name='choice' class='form-select'>
- <option value=''>Stratocaster
- </option>
- <option value=''>Telecaster
- </option></select>
+ <tobago-select-one-choice id='choice' class='form-select tobago-margin-bottom'>
+ <select id='choice::field' name='choice' class='form-select'>
+ <option value=''>Stratocaster
+ </option>
+ <option value=''>Telecaster
+ </option></select>
+ </tobago-select-one-choice>
</div>
</div>
-</tobago-in>
\ No newline at end of file
+</tobago-in>
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 10e7fad..851b425 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
@@ -16,51 +16,34 @@
*/
import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
- let test = new JasmineTestTool(done);
- test.do(() => fail("not implemented yet"));
- test.start();
-});
-
-/*
import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
-QUnit.test("ajax: chat send button", function (assert) {
+it("ajax: chat send button", function (done) {
let chatlogFn = querySelectorFn("#page\\:mainForm\\:tachatlog\\:\\:field");
let inputFn = querySelectorFn("#page\\:mainForm\\:inewmessage\\:\\:field");
let sendButtonFn = querySelectorFn("#page\\:mainForm\\:sendButton");
- let TTT = new TobagoTestTool(assert);
- TTT.action(function () {
- inputFn().value = "delete chat";
- sendButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
- });
- TTT.waitForResponse();
- TTT.asserts(1, function () {
- assert.equal(chatlogFn().textContent, "");
- });
- TTT.action(function () {
- inputFn().value = "Hi Peter, how are you?";
- sendButtonFn().dispatchEvent(new Event("click", {bubbles: true}));
- });
- TTT.waitForResponse();
- TTT.asserts(1, function () {
- assert.equal(chatlogFn().textContent, "User Two: Hi Peter, how are you?");
- });
- TTT.startTest();
+ const test = new JasmineTestTool(done);
+ test.setup(() => chatlogFn().textContent === "",
+ () => inputFn().value = "delete chat",
+ "click", sendButtonFn);
+ test.do(() => expect(chatlogFn().textContent).toBe(""));
+ test.do(() => inputFn().value = "Hi Peter, how are you?");
+ test.event("click", sendButtonFn, () => chatlogFn().textContent === "User Two: Hi Peter, how are you?");
+ test.do(() => expect(chatlogFn().textContent).toBe("User Two: Hi Peter, how are you?"));
+ test.start();
});
-QUnit.test("ajax: dropdown button", function (assert) {
+it("ajax: dropdown button", function (done) {
let buttonFn = querySelectorFn("#page\\:mainForm\\:lsendtoc\\:\\:command");
let buttonLabelFn = querySelectorFn("#page\\:mainForm\\:lsendtoc\\:\\:command span");
let sendToPeterFn = querySelectorFn("#page\\:mainForm\\:sendToPeter");
let sendToBobFn = querySelectorFn("#page\\:mainForm\\:sendToBob");
let sendToAllFn = querySelectorFn("#page\\:mainForm\\:sendToAll");
- let TTT = new TobagoTestTool(assert);
- TTT.action(function () {
+ const test = new JasmineTestTool(done);
+ test.do(() => fail("not implemented yet; fix dropdown first"));
+ /*TTT.action(function () {
buttonFn().dispatchEvent(new Event("click", {bubbles: true}));
sendToPeterFn().dispatchEvent(new Event("click", {bubbles: true}));
});
@@ -83,53 +66,50 @@ QUnit.test("ajax: dropdown button", function (assert) {
TTT.waitForResponse();
TTT.asserts(1, function () {
assert.equal(buttonLabelFn().textContent, "SendTo: All");
- });
- TTT.startTest();
+ });*/
+ test.start();
});
-QUnit.test("ajax: currency change event", function (assert) {
- let currencyInputFn = querySelectorFn("#page\\:mainForm\\:value\\:\\:field");
- let currencyFn = querySelectorFn("#page\\:mainForm\\:currency");
- let currencyOptionFn = querySelectorAllFn("#page\\:mainForm\\:currency option");
- let outputFieldFn = querySelectorFn("#page\\:mainForm\\:valueInEuro .tobago-out");
+it("ajax: currency change event", function (done) {
+ let inputFn = querySelectorFn("#page\\:mainForm\\:value\\:\\:field");
+ let selectFn = querySelectorFn("#page\\:mainForm\\:currency\\:\\:field");
+ let optionsFn = querySelectorAllFn("#page\\:mainForm\\:currency option");
+ let outputFn = querySelectorFn("#page\\:mainForm\\:valueInEuro tobago-out");
- let TTT = new TobagoTestTool(assert);
- TTT.action(function () {
- currencyInputFn().value = "1000";
- currencyOptionFn().item(1).selected = false;
- currencyOptionFn().item(2).selected = false;
- currencyOptionFn().item(3).selected = false;
- currencyOptionFn().item(0).selected = true; // Yen
- currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
- });
- TTT.waitForResponse();
- TTT.asserts(1, function () {
- assert.equal(outputFieldFn().textContent, "8,85");
- });
- TTT.action(function () {
- currencyInputFn().value = "2000";
- currencyOptionFn().item(0).selected = false;
- currencyOptionFn().item(2).selected = false;
- currencyOptionFn().item(3).selected = false;
- currencyOptionFn().item(1).selected = true; // Trinidad-Tobago Dollar
- currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
- });
- TTT.waitForResponse();
- TTT.asserts(1, function () {
- assert.equal(outputFieldFn().textContent, "267,50");
- });
- TTT.action(function () {
- currencyInputFn().value = "3000";
- currencyOptionFn().item(0).selected = false;
- currencyOptionFn().item(1).selected = false;
- currencyOptionFn().item(3).selected = false;
- currencyOptionFn().item(2).selected = true; // US Dollar
- currencyFn().dispatchEvent(new Event("change", {bubbles: true}));
- });
- TTT.waitForResponse();
- TTT.asserts(1, function () {
- assert.equal(outputFieldFn().textContent, "2.688,29");
- });
- TTT.startTest();
+ const test = new JasmineTestTool(done);
+ test.setup(() => parseInt(inputFn().value.replaceAll(".", "")) === 1000
+ && outputFn().textContent === "1.000,00",
+ () => {
+ inputFn().value = "1000";
+ optionsFn().item(0).selected = false; // Yen
+ optionsFn().item(1).selected = false; // Trinidad-Tobago Dollar
+ optionsFn().item(2).selected = false; // US Dollar
+ optionsFn().item(3).selected = true; // Euro
+ },
+ "change", selectFn);
+
+ test.do(() => inputFn().value = "1000");
+ test.do(() => optionsFn().item(0).selected = true); // Yen
+ test.do(() => optionsFn().item(1).selected = false); // Trinidad-Tobago Dollar
+ test.do(() => optionsFn().item(2).selected = false); // US Dollar
+ test.do(() => optionsFn().item(3).selected = false); // Euro
+ test.event("change", selectFn, () => outputFn().textContent === "8,85");
+ test.do(() => expect(outputFn().textContent).toBe("8,85"));
+
+ test.do(() => inputFn().value = "2000");
+ test.do(() => optionsFn().item(0).selected = false); // Yen
+ test.do(() => optionsFn().item(1).selected = true); // Trinidad-Tobago Dollar
+ test.do(() => optionsFn().item(2).selected = false); // US Dollar
+ test.do(() => optionsFn().item(3).selected = false); // Euro
+ test.event("change", selectFn, () => outputFn().textContent === "267,50");
+ test.do(() => expect(outputFn().textContent).toBe("267,50"));
+
+ test.do(() => inputFn().value = "3000");
+ test.do(() => optionsFn().item(0).selected = false); // Yen
+ test.do(() => optionsFn().item(1).selected = false); // Trinidad-Tobago Dollar
+ test.do(() => optionsFn().item(2).selected = true); // US Dollar
+ test.do(() => optionsFn().item(3).selected = false); // Euro
+ test.event("change", selectFn, () => outputFn().textContent === "2.688,29");
+ test.do(() => expect(outputFn().textContent).toBe("2.688,29"));
+ test.start();
});
-*/