summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--all/src/main/templates/release-notes.html2
-rw-r--r--client/src/main/java/com/vaadin/client/StyleConstants.java5
-rw-r--r--client/src/main/java/com/vaadin/client/TooltipInfo.java174
-rw-r--r--client/src/main/java/com/vaadin/client/VCaption.java74
-rw-r--r--client/src/main/java/com/vaadin/client/VErrorMessage.java14
-rw-r--r--client/src/main/java/com/vaadin/client/VTooltip.java2
-rw-r--r--client/src/main/java/com/vaadin/client/WidgetUtil.java63
-rw-r--r--client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java25
-rw-r--r--client/src/main/java/com/vaadin/client/ui/HasErrorIndicatorElement.java42
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAccordion.java4
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VButton.java23
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VCheckBox.java26
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VFormLayout.java50
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VLink.java23
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VNativeButton.java24
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VPanel.java42
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VTabsheet.java4
-rw-r--r--client/src/main/java/com/vaadin/client/ui/button/ButtonConnector.java18
-rw-r--r--client/src/main/java/com/vaadin/client/ui/checkbox/CheckBoxConnector.java24
-rw-r--r--client/src/main/java/com/vaadin/client/ui/formlayout/FormLayoutConnector.java3
-rw-r--r--client/src/main/java/com/vaadin/client/ui/link/LinkConnector.java16
-rw-r--r--client/src/main/java/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java19
-rw-r--r--client/src/main/java/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java5
-rw-r--r--client/src/main/java/com/vaadin/client/ui/orderedlayout/Slot.java67
-rw-r--r--client/src/main/java/com/vaadin/client/ui/panel/PanelConnector.java2
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/ui/checkbox/CheckBoxConnector.java9
-rw-r--r--compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java1
-rw-r--r--compatibility-server/src/main/java/com/vaadin/v7/data/Buffered.java2
-rw-r--r--compatibility-server/src/main/java/com/vaadin/v7/data/Validator.java2
-rw-r--r--compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java1
-rw-r--r--compatibility-server/src/test/java/com/vaadin/v7/ui/AbstractLegacyComponentDeclarativeTest.java2
-rw-r--r--server/src/main/java/com/vaadin/server/AbstractErrorMessage.java2
-rw-r--r--server/src/main/java/com/vaadin/server/CompositeErrorMessage.java6
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorMessage.java65
-rw-r--r--server/src/main/java/com/vaadin/server/SystemError.java4
-rw-r--r--server/src/main/java/com/vaadin/server/UserError.java2
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractComponent.java4
-rw-r--r--server/src/main/java/com/vaadin/ui/TabSheet.java12
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java2
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java2
-rw-r--r--shared/src/main/java/com/vaadin/shared/AbstractComponentState.java13
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/ErrorLevel.java58
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/tabsheet/TabState.java9
m---------tests/screenshots0
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss55
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss55
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_textfield.scss70
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_twincolselect.scss34
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/shared/_global.scss24
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/shared/_tooltip.scss60
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/shared/_variables.scss42
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/ErrorLevels.java210
-rw-r--r--uitest/src/main/java/com/vaadin/tests/themes/valo/CommonParts.java2
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/ErrorLevelsTest.java160
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java4
55 files changed, 1408 insertions, 255 deletions
diff --git a/all/src/main/templates/release-notes.html b/all/src/main/templates/release-notes.html
index fab73eff2a..7087b6c46c 100644
--- a/all/src/main/templates/release-notes.html
+++ b/all/src/main/templates/release-notes.html
@@ -106,6 +106,8 @@
<li><tt>DataCommunicator</tt> method <tt>getDataProviderSize</tt> is now <tt>public</tt>, not <tt>protected</tt>.</li>
<li><tt>Binder</tt> method <tt>getBindings</tt> now returns a Collection, not a Set.</li>
<li><tt>BindingBuilder</tt> now works like a proper builder. Adding a converter will not mark Binding as <tt>bound</tt> allowing chaining to the same object.</li>
+ <li><tt>ErrorLevel</tt> is removed from <tt>ErrorMessage</tt> and now <tt>com.vaadin.shared.ui.ErrorLevel</tt> should be used.</li>
+ <li>Error indicators are now <tt>&lt;span class="v-errorindicator"&gt;&lt;/span&gt;</tt> elements.</li>
<h2>For incompatible or behaviour-altering changes in 8.1, please see <a href="https://vaadin.com/download/release/8.1/8.1.0/release-notes.html#incompatible">8.1 release notes</a></h2>
diff --git a/client/src/main/java/com/vaadin/client/StyleConstants.java b/client/src/main/java/com/vaadin/client/StyleConstants.java
index 3b587ce233..13549b4938 100644
--- a/client/src/main/java/com/vaadin/client/StyleConstants.java
+++ b/client/src/main/java/com/vaadin/client/StyleConstants.java
@@ -44,4 +44,9 @@ public class StyleConstants {
public static final String REQUIRED_EXT = "-required";
public static final String ERROR_EXT = "-error";
+
+ /**
+ * Style name and style name prefix for the error indicator element.
+ */
+ public static final String STYLE_NAME_ERROR_INDICATOR = "v-errorindicator";
}
diff --git a/client/src/main/java/com/vaadin/client/TooltipInfo.java b/client/src/main/java/com/vaadin/client/TooltipInfo.java
index a84e45e988..1f01dab811 100644
--- a/client/src/main/java/com/vaadin/client/TooltipInfo.java
+++ b/client/src/main/java/com/vaadin/client/TooltipInfo.java
@@ -16,8 +16,13 @@
package com.vaadin.client;
import com.vaadin.shared.ui.ContentMode;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.shared.util.SharedUtil;
+/**
+ * An object that contains information about a tooltip, such as the tooltip's
+ * title, error message, error level and an ID.
+ */
public class TooltipInfo {
private String title;
@@ -26,14 +31,25 @@ public class TooltipInfo {
private String errorMessageHtml;
+ private ErrorLevel errorLevel;
+
// Contains the tooltip's identifier. If a tooltip's contents and this
// identifier haven't changed, the tooltip won't be updated in subsequent
// events.
private Object identifier;
+ /**
+ * Constructs a new tooltip info instance.
+ */
public TooltipInfo() {
}
+ /**
+ * Constructs a new tooltip info instance.
+ *
+ * @param tooltip
+ * tooltip title
+ */
public TooltipInfo(String tooltip) {
this(tooltip, ContentMode.PREFORMATTED);
}
@@ -41,12 +57,12 @@ public class TooltipInfo {
/**
* Constructs a new instance using the {@code tooltip} for the title and
* {@code errorMessage} as a description.
- *
+ *
* @param tooltip
* tooltip title
* @param errorMessage
* error description
- *
+ *
* @deprecated use {@link #TooltipInfo(String, ContentMode, String)} instead
*/
@Deprecated
@@ -57,13 +73,14 @@ public class TooltipInfo {
/**
* Constructs a new instance using the {@code tooltip} for the title,
* {@code errorMessage} as a description and {@code identifier} as its id.
- *
+ *
* @param tooltip
* tooltip title
* @param errorMessage
* error description
* @param identifier
- *
+ * the tooltip's identifier
+ *
* @deprecated use {@link #TooltipInfo(String, ContentMode, String, Object)}
* instead
*/
@@ -72,56 +89,195 @@ public class TooltipInfo {
this(tooltip, ContentMode.HTML, errorMessage, identifier);
}
+ /**
+ * Constructs a new instance using the {@code tooltip} for the title,
+ * {@code errorMessage} as a description, {@code identifier} as its id and
+ * {@code errorLevel} as the error level.
+ *
+ * @param tooltip
+ * tooltip title
+ * @param errorMessage
+ * error description
+ * @param identifier
+ * the tooltip's identifier
+ * @param errorLevel
+ * error level
+ *
+ * @deprecated use {@link #TooltipInfo(String, ContentMode, String, Object,
+ * ErrorLevel)} instead
+ * @since 8.2
+ */
+ @Deprecated
+ public TooltipInfo(String tooltip, String errorMessage, Object identifier,
+ ErrorLevel errorLevel) {
+ this(tooltip, ContentMode.HTML, errorMessage, identifier, errorLevel);
+ }
+
+ /**
+ * Constructs a new tooltip info instance.
+ *
+ * @param tooltip
+ * tooltip title
+ * @param mode
+ * content mode
+ */
public TooltipInfo(String tooltip, ContentMode mode) {
setTitle(tooltip);
setContentMode(mode);
}
+ /**
+ * Constructs a new tooltip info instance.
+ *
+ * @param tooltip
+ * tooltip title
+ * @param mode
+ * content mode
+ * @param errorMessage
+ * error message
+ */
public TooltipInfo(String tooltip, ContentMode mode, String errorMessage) {
this(tooltip, mode, errorMessage, null);
}
+ /**
+ * Constructs a new tooltip info instance.
+ *
+ * @param tooltip
+ * tooltip title
+ * @param mode
+ * content mode
+ * @param errorMessage
+ * error message
+ * @param identifier
+ * the tooltip's identifier
+ */
public TooltipInfo(String tooltip, ContentMode mode, String errorMessage,
Object identifier) {
+ this(tooltip, mode, errorMessage, identifier, null);
+ }
+
+ /**
+ * Constructs a new tooltip info instance.
+ *
+ * @param tooltip
+ * tooltip title
+ * @param mode
+ * content mode
+ * @param errorMessage
+ * error message
+ * @param identifier
+ * the tooltip's identifier
+ * @param errorLevel
+ * error level
+ */
+ public TooltipInfo(String tooltip, ContentMode mode, String errorMessage,
+ Object identifier, ErrorLevel errorLevel) {
setIdentifier(identifier);
setTitle(tooltip);
setContentMode(mode);
setErrorMessage(errorMessage);
+ setErrorLevel(errorLevel);
}
+ /**
+ * Sets the tooltip's identifier.
+ *
+ * @param identifier
+ * the identifier to set
+ */
public void setIdentifier(Object identifier) {
this.identifier = identifier;
}
+ /**
+ * Gets the tooltip's identifier.
+ *
+ * @return the identifier
+ */
public Object getIdentifier() {
return identifier;
}
+ /**
+ * Gets the tooltip title.
+ *
+ * @return the title
+ */
public String getTitle() {
return title;
}
+ /**
+ * Sets the tooltip title.
+ *
+ * @param title
+ * the title to set
+ */
public void setTitle(String title) {
this.title = title;
}
+ /**
+ * Gets the error message.
+ *
+ * @return the error message
+ */
public String getErrorMessage() {
return errorMessageHtml;
}
+ /**
+ * Sets the error message.
+ *
+ * @param errorMessage
+ * the error message to set
+ */
public void setErrorMessage(String errorMessage) {
errorMessageHtml = errorMessage;
}
+ /**
+ * Gets the tooltip title's content mode.
+ *
+ * @return the content mode
+ */
public ContentMode getContentMode() {
return contentMode;
}
+ /**
+ * Sets the tooltip title's content mode.
+ *
+ * @param contentMode
+ * the content mode to set
+ */
public void setContentMode(ContentMode contentMode) {
this.contentMode = contentMode;
}
/**
+ * Gets the error level.
+ *
+ * @return the error level
+ * @since
+ */
+ public ErrorLevel getErrorLevel() {
+ return errorLevel;
+ }
+
+ /**
+ * Sets the error level.
+ *
+ * @param errorLevel
+ * the error level to set
+ * @since
+ */
+ public void setErrorLevel(ErrorLevel errorLevel) {
+ this.errorLevel = errorLevel;
+ }
+
+ /**
* Checks is a message has been defined for the tooltip.
*
* @return true if title or error message is present, false if both are
@@ -132,9 +288,19 @@ public class TooltipInfo {
|| (errorMessageHtml != null && !errorMessageHtml.isEmpty());
}
+ /**
+ * Indicates whether another tooltip info instance is equal to this one. Two
+ * instances are equal if their title, error message, error level and
+ * identifier are equal.
+ *
+ * @param other
+ * the reference tooltip info instance with which to compare
+ * @return {@code true} if the instances are equal, {@code false} otherwise
+ */
public boolean equals(TooltipInfo other) {
return (other != null && SharedUtil.equals(other.title, title)
&& SharedUtil.equals(other.errorMessageHtml, errorMessageHtml)
+ && SharedUtil.equals(other.errorLevel, errorLevel)
&& other.identifier == identifier);
}
}
diff --git a/client/src/main/java/com/vaadin/client/VCaption.java b/client/src/main/java/com/vaadin/client/VCaption.java
index 1bff175d7e..f7d7d55ffe 100644
--- a/client/src/main/java/com/vaadin/client/VCaption.java
+++ b/client/src/main/java/com/vaadin/client/VCaption.java
@@ -25,8 +25,10 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHTML;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.HasErrorIndicator;
+import com.vaadin.client.ui.HasErrorIndicatorElement;
import com.vaadin.client.ui.HasRequiredIndicator;
import com.vaadin.client.ui.Icon;
import com.vaadin.client.ui.ImageIcon;
@@ -34,8 +36,9 @@ import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.ComponentConstants;
import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.shared.ui.ErrorLevel;
-public class VCaption extends HTML {
+public class VCaption extends HTML implements HasErrorIndicatorElement {
public static final String CLASSNAME = "v-caption";
@@ -259,23 +262,17 @@ public class VCaption extends HTML {
AriaHelper.handleInputInvalid(owner.getWidget(), showError);
if (showError) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- DOM.setInnerHTML(errorIndicatorElement, "&nbsp;");
- DOM.setElementProperty(errorIndicatorElement, "className",
- "v-errorindicator");
+ setErrorIndicatorElementVisible(true);
- DOM.insertChild(getElement(), errorIndicatorElement,
- getInsertPosition(InsertPosition.ERROR));
+ // Hide error indicator from assistive devices
+ Roles.getTextboxRole()
+ .setAriaHiddenState(errorIndicatorElement, true);
- // Hide error indicator from assistive devices
- Roles.getTextboxRole().setAriaHiddenState(errorIndicatorElement,
- true);
- }
- } else if (errorIndicatorElement != null) {
- // Remove existing
- getElement().removeChild(errorIndicatorElement);
- errorIndicatorElement = null;
+ ErrorUtil.setErrorLevelStyle(errorIndicatorElement,
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR,
+ owner.getState().errorLevel);
+ } else {
+ setErrorIndicatorElementVisible(false);
}
return (wasPlacedAfterComponent != placedAfterComponent);
@@ -322,6 +319,14 @@ public class VCaption extends HTML {
public boolean updateCaptionWithoutOwner(String caption, boolean disabled,
boolean hasDescription, boolean hasError, String iconURL,
String iconAltText) {
+ return updateCaptionWithoutOwner(caption, disabled, hasDescription,
+ hasError, null, iconURL, iconAltText);
+ }
+
+ @Deprecated
+ public boolean updateCaptionWithoutOwner(String caption, boolean disabled,
+ boolean hasDescription, boolean hasError, ErrorLevel errorLevel,
+ String iconURL, String iconAltText) {
boolean wasPlacedAfterComponent = placedAfterComponent;
// Caption is placed after component unless there is some part which
@@ -401,19 +406,11 @@ public class VCaption extends HTML {
}
if (hasError) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- DOM.setInnerHTML(errorIndicatorElement, "&nbsp;");
- DOM.setElementProperty(errorIndicatorElement, "className",
- "v-errorindicator");
-
- DOM.insertChild(getElement(), errorIndicatorElement,
- getInsertPosition(InsertPosition.ERROR));
- }
- } else if (errorIndicatorElement != null) {
- // Remove existing
- getElement().removeChild(errorIndicatorElement);
- errorIndicatorElement = null;
+ setErrorIndicatorElementVisible(true);
+ ErrorUtil.setErrorLevelStyle(errorIndicatorElement,
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR, errorLevel);
+ } else {
+ setErrorIndicatorElementVisible(false);
}
return (wasPlacedAfterComponent != placedAfterComponent);
@@ -775,4 +772,23 @@ public class VCaption extends HTML {
private static Logger getLogger() {
return Logger.getLogger(VCaption.class.getName());
}
+
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ DOM.insertChild(getElement(), errorIndicatorElement,
+ getInsertPosition(InsertPosition.ERROR));
+ }
+ } else if (errorIndicatorElement != null) {
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/VErrorMessage.java b/client/src/main/java/com/vaadin/client/VErrorMessage.java
index 0baa1baff1..7caffa1275 100644
--- a/client/src/main/java/com/vaadin/client/VErrorMessage.java
+++ b/client/src/main/java/com/vaadin/client/VErrorMessage.java
@@ -22,6 +22,8 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.VOverlay;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
+import com.vaadin.shared.ui.ErrorLevel;
public class VErrorMessage extends FlowPanel {
public static final String CLASSNAME = "v-errormessage";
@@ -58,6 +60,18 @@ public class VErrorMessage extends FlowPanel {
}
/**
+ * Sets the correct error level style name for the error message and removes
+ * all previous style names.
+ *
+ * @param errorLevel
+ * error level
+ * @since
+ */
+ public void updateErrorLevel(ErrorLevel errorLevel) {
+ ErrorUtil.setErrorLevelStyle(getStyleElement(), CLASSNAME, errorLevel);
+ }
+
+ /**
* Shows this error message next to given element.
*
* @param indicatorElement
diff --git a/client/src/main/java/com/vaadin/client/VTooltip.java b/client/src/main/java/com/vaadin/client/VTooltip.java
index 74da680c66..84647abf9a 100644
--- a/client/src/main/java/com/vaadin/client/VTooltip.java
+++ b/client/src/main/java/com/vaadin/client/VTooltip.java
@@ -138,6 +138,7 @@ public class VTooltip extends VOverlay {
&& !info.getErrorMessage().isEmpty()) {
em.setVisible(true);
em.updateMessage(info.getErrorMessage());
+ em.updateErrorLevel(info.getErrorLevel());
} else {
em.setVisible(false);
}
@@ -459,6 +460,7 @@ public class VTooltip extends VOverlay {
@Override
public void hide() {
em.updateMessage("");
+ em.updateErrorLevel(null);
description.setHTML("");
updatePosition(null, true);
diff --git a/client/src/main/java/com/vaadin/client/WidgetUtil.java b/client/src/main/java/com/vaadin/client/WidgetUtil.java
index 0aced86b03..fed9320edc 100644
--- a/client/src/main/java/com/vaadin/client/WidgetUtil.java
+++ b/client/src/main/java/com/vaadin/client/WidgetUtil.java
@@ -44,6 +44,7 @@ import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.shared.util.SharedUtil;
/**
@@ -790,7 +791,7 @@ public class WidgetUtil {
com.google.gwt.dom.client.Element el, String p)
/*-{
try {
-
+
if (el.currentStyle) {
// IE
return el.currentStyle[p];
@@ -805,7 +806,7 @@ public class WidgetUtil {
} catch (e) {
return "";
}
-
+
}-*/;
/**
@@ -819,7 +820,7 @@ public class WidgetUtil {
try {
el.focus();
} catch (e) {
-
+
}
}-*/;
@@ -1172,7 +1173,7 @@ public class WidgetUtil {
if ($wnd.document.activeElement) {
return $wnd.document.activeElement;
}
-
+
return null;
}-*/;
@@ -1243,11 +1244,11 @@ public class WidgetUtil {
/*-{
var top = elem.offsetTop;
var height = elem.offsetHeight;
-
+
if (elem.parentNode != elem.offsetParent) {
top -= elem.parentNode.offsetTop;
}
-
+
var cur = elem.parentNode;
while (cur && (cur.nodeType == 1)) {
if (top < cur.scrollTop) {
@@ -1256,12 +1257,12 @@ public class WidgetUtil {
if (top + height > cur.scrollTop + cur.clientHeight) {
cur.scrollTop = (top + height) - cur.clientHeight;
}
-
+
var offsetTop = cur.offsetTop;
if (cur.parentNode != cur.offsetParent) {
offsetTop -= cur.parentNode.offsetTop;
}
-
+
top += offsetTop - cur.scrollTop;
cur = cur.parentNode;
}
@@ -1710,7 +1711,7 @@ public class WidgetUtil {
}
var heightWithoutBorder = cloneElement.offsetHeight;
parentElement.removeChild(cloneElement);
-
+
return heightWithBorder - heightWithoutBorder;
}
}-*/;
@@ -1866,4 +1867,48 @@ public class WidgetUtil {
int relativeTop = element.getAbsoluteTop() - Window.getScrollTop();
return WidgetUtil.getTouchOrMouseClientY(event) - relativeTop;
}
+
+ /**
+ * Utility methods for displaying error message on components.
+ *
+ * @since 8.2
+ */
+ public static class ErrorUtil {
+
+ /**
+ * Sets the error level style name for the given element and removes all
+ * previously applied error level style names. The style name has the
+ * {@code prefix-errorLevel} format.
+ *
+ * @param element
+ * element to apply the style name to
+ * @param prefix
+ * part of the style name before the error level string
+ * @param errorLevel
+ * error level for which the style will be applied
+ */
+ public static void setErrorLevelStyle(Element element, String prefix,
+ ErrorLevel errorLevel) {
+ for (ErrorLevel errorLevelValue : ErrorLevel.values()) {
+ String className =
+ prefix + "-" + errorLevelValue.toString().toLowerCase();
+ if (errorLevel == errorLevelValue) {
+ element.addClassName(className);
+ } else {
+ element.removeClassName(className);
+ }
+ }
+ }
+
+ /**
+ * Creates an element to use by widgets as an error indicator.
+ *
+ * @return the error indicator element
+ */
+ public static Element createErrorIndicatorElement() {
+ Element indicator = DOM.createSpan();
+ indicator.setClassName(StyleConstants.STYLE_NAME_ERROR_INDICATOR);
+ return indicator;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
index 7ce3e5c9b7..d3b595b55a 100644
--- a/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -46,6 +46,7 @@ import com.vaadin.client.UIDL;
import com.vaadin.client.Util;
import com.vaadin.client.VConsole;
import com.vaadin.client.WidgetUtil;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.extensions.DragSourceExtensionConnector;
@@ -489,6 +490,27 @@ public abstract class AbstractComponentConnector extends AbstractConnector
Profiler.leave("AbstractComponentConnector.onStateChanged");
}
+ @OnStateChange({"errorMessage", "errorLevel"})
+ private void setErrorLevel() {
+ // Add or remove the widget's error level style name
+ ErrorUtil.setErrorLevelStyle(getWidget().getElement(),
+ getWidget().getStylePrimaryName() + StyleConstants.ERROR_EXT,
+ getState().errorLevel);
+
+ // Add or remove error indicator element
+ if (getWidget() instanceof HasErrorIndicatorElement) {
+ HasErrorIndicatorElement widget = (HasErrorIndicatorElement) getWidget();
+ if (getState().errorMessage != null) {
+ widget.setErrorIndicatorElementVisible(true);
+ ErrorUtil.setErrorLevelStyle(widget.getErrorIndicatorElement(),
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR,
+ getState().errorLevel);
+ } else {
+ widget.setErrorIndicatorElementVisible(false);
+ }
+ }
+ }
+
@Override
public void setWidgetEnabled(boolean widgetEnabled) {
// add or remove v-disabled style name from the widget
@@ -764,7 +786,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector
@Override
public TooltipInfo getTooltipInfo(Element element) {
return new TooltipInfo(getState().description,
- getState().descriptionContentMode, getState().errorMessage);
+ getState().descriptionContentMode, getState().errorMessage,
+ null, getState().errorLevel);
}
@Override
diff --git a/client/src/main/java/com/vaadin/client/ui/HasErrorIndicatorElement.java b/client/src/main/java/com/vaadin/client/ui/HasErrorIndicatorElement.java
new file mode 100644
index 0000000000..8ee0e5e757
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/ui/HasErrorIndicatorElement.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.ui;
+
+import com.google.gwt.dom.client.Element;
+
+/**
+ * Implemented by widgets supporting an error indicator.
+ *
+ * @since 8.2
+ */
+public interface HasErrorIndicatorElement {
+
+ /**
+ * Gets the error indicator element.
+ *
+ * @return the error indicator element
+ */
+ Element getErrorIndicatorElement();
+
+ /**
+ * Sets the visibility of the error indicator element.
+ *
+ * @param visible
+ * {@code true} to show the error indicator element, {@code false}
+ * to hide it
+ */
+ void setErrorIndicatorElementVisible(boolean visible);
+}
diff --git a/client/src/main/java/com/vaadin/client/ui/VAccordion.java b/client/src/main/java/com/vaadin/client/ui/VAccordion.java
index 16c16935d0..642c647a62 100644
--- a/client/src/main/java/com/vaadin/client/ui/VAccordion.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAccordion.java
@@ -364,8 +364,10 @@ public class VAccordion extends VTabsheetBase {
caption.updateCaptionWithoutOwner(tabState.caption,
!tabState.enabled, hasAttribute(tabState.description),
hasAttribute(tabState.componentError),
+ tabState.componentErrorLevel,
connector.getResourceUrl(
- ComponentConstants.ICON_RESOURCE + tabState.key));
+ ComponentConstants.ICON_RESOURCE + tabState.key),
+ tabState.iconAltText);
}
private boolean hasAttribute(String string) {
diff --git a/client/src/main/java/com/vaadin/client/ui/VButton.java b/client/src/main/java/com/vaadin/client/ui/VButton.java
index 0e738032b5..725931008e 100644
--- a/client/src/main/java/com/vaadin/client/ui/VButton.java
+++ b/client/src/main/java/com/vaadin/client/ui/VButton.java
@@ -30,8 +30,10 @@ import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.Util;
import com.vaadin.client.WidgetUtil;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
-public class VButton extends FocusWidget implements ClickHandler {
+public class VButton extends FocusWidget implements ClickHandler,
+ HasErrorIndicatorElement {
public static final String CLASSNAME = "v-button";
private static final String CLASSNAME_PRESSED = "v-pressed";
@@ -48,7 +50,7 @@ public class VButton extends FocusWidget implements ClickHandler {
public final Element wrapper = DOM.createSpan();
/** For internal use only. May be removed or replaced in the future. */
- public Element errorIndicatorElement;
+ private Element errorIndicatorElement;
/** For internal use only. May be removed or replaced in the future. */
public final Element captionElement = DOM.createSpan();
@@ -481,4 +483,21 @@ public class VButton extends FocusWidget implements ClickHandler {
return ret;
}-*/;
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ wrapper.insertFirst(errorIndicatorElement);
+ }
+ } else if (errorIndicatorElement != null) {
+ wrapper.removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VCheckBox.java b/client/src/main/java/com/vaadin/client/ui/VCheckBox.java
index b2f78dce31..18140c203d 100644
--- a/client/src/main/java/com/vaadin/client/ui/VCheckBox.java
+++ b/client/src/main/java/com/vaadin/client/ui/VCheckBox.java
@@ -25,12 +25,14 @@ import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.Util;
import com.vaadin.client.VTooltip;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.client.ui.aria.HandlesAriaInvalid;
import com.vaadin.client.ui.aria.HandlesAriaRequired;
public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox
- implements Field, HandlesAriaInvalid, HandlesAriaRequired {
+ implements Field, HandlesAriaInvalid, HandlesAriaRequired,
+ HasErrorIndicatorElement {
public static final String CLASSNAME = "v-checkbox";
@@ -41,7 +43,7 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox
public ApplicationConnection client;
/** For internal use only. May be removed or replaced in the future. */
- public Element errorIndicatorElement;
+ private Element errorIndicatorElement;
/** For internal use only. May be removed or replaced in the future. */
public Icon icon;
@@ -101,4 +103,24 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox
public void setAriaInvalid(boolean invalid) {
AriaHelper.handleInputInvalid(getCheckBoxElement(), invalid);
}
+
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ getElement().appendChild(errorIndicatorElement);
+ DOM.sinkEvents(errorIndicatorElement,
+ VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
+ }
+ } else if (errorIndicatorElement != null) {
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VFormLayout.java b/client/src/main/java/com/vaadin/client/ui/VFormLayout.java
index a8a43a2d8d..5704dc497d 100644
--- a/client/src/main/java/com/vaadin/client/ui/VFormLayout.java
+++ b/client/src/main/java/com/vaadin/client/ui/VFormLayout.java
@@ -34,10 +34,12 @@ import com.vaadin.client.ComponentConnector;
import com.vaadin.client.Focusable;
import com.vaadin.client.StyleConstants;
import com.vaadin.client.VTooltip;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.ComponentConstants;
import com.vaadin.shared.ui.ComponentStateUtil;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.shared.ui.MarginInfo;
/**
@@ -201,10 +203,10 @@ public class VFormLayout extends SimplePanel {
}
public void updateError(Widget widget, String errorMessage,
- boolean hideErrors) {
+ ErrorLevel errorLevel, boolean hideErrors) {
final ErrorFlag e = widgetToError.get(widget);
if (e != null) {
- e.updateError(errorMessage, hideErrors);
+ e.updateError(errorMessage, errorLevel, hideErrors);
}
}
@@ -340,7 +342,7 @@ public class VFormLayout extends SimplePanel {
}
/** For internal use only. May be removed or replaced in the future. */
- public class ErrorFlag extends HTML {
+ public class ErrorFlag extends HTML implements HasErrorIndicatorElement {
private static final String CLASSNAME = VFormLayout.CLASSNAME
+ "-error-indicator";
Element errorIndicatorElement;
@@ -361,7 +363,8 @@ public class VFormLayout extends SimplePanel {
return owner;
}
- public void updateError(String errorMessage, boolean hideErrors) {
+ public void updateError(String errorMessage, ErrorLevel errorLevel,
+ boolean hideErrors) {
boolean showError = null != errorMessage;
if (hideErrors) {
showError = false;
@@ -370,24 +373,37 @@ public class VFormLayout extends SimplePanel {
AriaHelper.handleInputInvalid(owner.getWidget(), showError);
if (showError) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- DOM.setInnerHTML(errorIndicatorElement, "&nbsp;");
- DOM.setElementProperty(errorIndicatorElement, "className",
- "v-errorindicator");
- DOM.appendChild(getElement(), errorIndicatorElement);
+ setErrorIndicatorElementVisible(true);
- // Hide the error indicator from screen reader, as this
- // information is set directly at the input field
- Roles.getFormRole()
- .setAriaHiddenState(errorIndicatorElement, true);
- }
+ // Hide the error indicator from screen reader, as this
+ // information is set directly at the input field
+ Roles.getFormRole()
+ .setAriaHiddenState(errorIndicatorElement, true);
+
+ ErrorUtil.setErrorLevelStyle(errorIndicatorElement,
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR, errorLevel);
+ } else {
+ setErrorIndicatorElementVisible(false);
+ }
+ }
+
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil
+ .createErrorIndicatorElement();
+ getElement().appendChild(errorIndicatorElement);
+ }
} else if (errorIndicatorElement != null) {
- DOM.removeChild(getElement(), errorIndicatorElement);
+ getElement().removeChild(errorIndicatorElement);
errorIndicatorElement = null;
}
}
-
}
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VLink.java b/client/src/main/java/com/vaadin/client/ui/VLink.java
index 84aac0f17e..28e262b110 100644
--- a/client/src/main/java/com/vaadin/client/ui/VLink.java
+++ b/client/src/main/java/com/vaadin/client/ui/VLink.java
@@ -25,9 +25,11 @@ import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasEnabled;
import com.vaadin.client.Util;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.shared.ui.BorderStyle;
-public class VLink extends HTML implements ClickHandler, HasEnabled {
+public class VLink extends HTML implements ClickHandler, HasEnabled,
+ HasErrorIndicatorElement {
public static final String CLASSNAME = "v-link";
@@ -59,7 +61,7 @@ public class VLink extends HTML implements ClickHandler, HasEnabled {
public int targetHeight;
/** For internal use only. May be removed or replaced in the future. */
- public Element errorIndicatorElement;
+ private Element errorIndicatorElement;
/** For internal use only. May be removed or replaced in the future. */
public final Element anchor = DOM.createAnchor();
@@ -145,4 +147,21 @@ public class VLink extends HTML implements ClickHandler, HasEnabled {
this.enabled = enabled;
}
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ getElement().insertFirst(errorIndicatorElement);
+ }
+ } else if (errorIndicatorElement != null) {
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VNativeButton.java b/client/src/main/java/com/vaadin/client/ui/VNativeButton.java
index ec95a28755..db8e820b82 100644
--- a/client/src/main/java/com/vaadin/client/ui/VNativeButton.java
+++ b/client/src/main/java/com/vaadin/client/ui/VNativeButton.java
@@ -27,10 +27,12 @@ import com.vaadin.client.BrowserInfo;
import com.vaadin.client.MouseEventDetailsBuilder;
import com.vaadin.client.StyleConstants;
import com.vaadin.client.Util;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.button.ButtonServerRpc;
-public class VNativeButton extends Button implements ClickHandler {
+public class VNativeButton extends Button implements ClickHandler,
+ HasErrorIndicatorElement {
public static final String CLASSNAME = "v-nativebutton";
@@ -44,7 +46,7 @@ public class VNativeButton extends Button implements ClickHandler {
public ButtonServerRpc buttonRpcProxy;
/** For internal use only. May be removed or replaced in the future. */
- public Element errorIndicatorElement;
+ private Element errorIndicatorElement;
/** For internal use only. May be removed or replaced in the future. */
public final Element captionElement = DOM.createSpan();
@@ -159,4 +161,22 @@ public class VNativeButton extends Button implements ClickHandler {
clickPending = false;
}
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ getElement()
+ .insertBefore(errorIndicatorElement, captionElement);
+ }
+ } else if (errorIndicatorElement != null) {
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VPanel.java b/client/src/main/java/com/vaadin/client/ui/VPanel.java
index fa4a939a95..bf41ef1f9e 100644
--- a/client/src/main/java/com/vaadin/client/ui/VPanel.java
+++ b/client/src/main/java/com/vaadin/client/ui/VPanel.java
@@ -24,11 +24,12 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.SimplePanel;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.Focusable;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler;
-public class VPanel extends SimplePanel
- implements ShortcutActionHandlerOwner, Focusable {
+public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner,
+ Focusable, HasErrorIndicatorElement {
public static final String CLASSNAME = "v-panel";
@@ -134,23 +135,6 @@ public class VPanel extends SimplePanel
}
/** For internal use only. May be removed or replaced in the future. */
- public void setErrorIndicatorVisible(boolean showError) {
- if (showError) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createSpan();
- DOM.setElementProperty(errorIndicatorElement, "className",
- "v-errorindicator");
- DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS);
- sinkEvents(Event.MOUSEEVENTS);
- }
- DOM.insertBefore(captionNode, errorIndicatorElement, captionText);
- } else if (errorIndicatorElement != null) {
- DOM.removeChild(captionNode, errorIndicatorElement);
- errorIndicatorElement = null;
- }
- }
-
- /** For internal use only. May be removed or replaced in the future. */
public void setIconUri(String iconUri, ApplicationConnection client) {
if (icon != null) {
captionNode.removeChild(icon.getElement());
@@ -201,4 +185,24 @@ public class VPanel extends SimplePanel
}
touchScrollHandler.addElement(contentNode);
}
+
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIndicatorElement;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = ErrorUtil.createErrorIndicatorElement();
+ DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS);
+ sinkEvents(Event.MOUSEEVENTS);
+ captionNode.insertBefore(errorIndicatorElement, captionText);
+ }
+ } else if (errorIndicatorElement != null){
+ captionNode.removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VTabsheet.java b/client/src/main/java/com/vaadin/client/ui/VTabsheet.java
index 52b48899dd..44814f9e0a 100644
--- a/client/src/main/java/com/vaadin/client/ui/VTabsheet.java
+++ b/client/src/main/java/com/vaadin/client/ui/VTabsheet.java
@@ -340,7 +340,8 @@ public class VTabsheet extends VTabsheetBase
|| tabState.componentError != null) {
setTooltipInfo(new TooltipInfo(tabState.description,
tabState.descriptionContentMode,
- tabState.componentError, this));
+ tabState.componentError, this,
+ tabState.componentErrorLevel));
} else {
setTooltipInfo(null);
}
@@ -352,6 +353,7 @@ public class VTabsheet extends VTabsheetBase
boolean ret = updateCaptionWithoutOwner(captionString,
!tabState.enabled, hasAttribute(tabState.description),
hasAttribute(tabState.componentError),
+ tabState.componentErrorLevel,
tab.getTabsheet().connector.getResourceUrl(
ComponentConstants.ICON_RESOURCE + tabState.key),
tabState.iconAltText);
diff --git a/client/src/main/java/com/vaadin/client/ui/button/ButtonConnector.java b/client/src/main/java/com/vaadin/client/ui/button/ButtonConnector.java
index b0d17465bb..eac2ffd11e 100644
--- a/client/src/main/java/com/vaadin/client/ui/button/ButtonConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/button/ButtonConnector.java
@@ -20,7 +20,9 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.vaadin.client.MouseEventDetailsBuilder;
+import com.vaadin.client.StyleConstants;
import com.vaadin.client.VCaption;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
@@ -50,22 +52,6 @@ public class ButtonConnector extends AbstractComponentConnector
ConnectorFocusAndBlurHandler.addHandlers(this);
}
- @OnStateChange("errorMessage")
- void setErrorMessage() {
- if (null != getState().errorMessage) {
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createSpan();
- getWidget().errorIndicatorElement
- .setClassName("v-errorindicator");
- }
- getWidget().wrapper.insertFirst(getWidget().errorIndicatorElement);
-
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().wrapper.removeChild(getWidget().errorIndicatorElement);
- getWidget().errorIndicatorElement = null;
- }
- }
-
@OnStateChange("resources")
void onResourceChange() {
if (getWidget().icon != null) {
diff --git a/client/src/main/java/com/vaadin/client/ui/checkbox/CheckBoxConnector.java b/client/src/main/java/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
index cf39e5ee21..c02607790f 100644
--- a/client/src/main/java/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
@@ -21,8 +21,10 @@ import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.vaadin.client.MouseEventDetailsBuilder;
+import com.vaadin.client.StyleConstants;
import com.vaadin.client.VCaption;
import com.vaadin.client.VTooltip;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractFieldConnector;
@@ -66,27 +68,7 @@ public class CheckBoxConnector extends AbstractFieldConnector
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
- if (null != getState().errorMessage) {
- getWidget().setAriaInvalid(true);
-
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createSpan();
- getWidget().errorIndicatorElement.setInnerHTML("&nbsp;");
- DOM.setElementProperty(getWidget().errorIndicatorElement,
- "className", "v-errorindicator");
- DOM.appendChild(getWidget().getElement(),
- getWidget().errorIndicatorElement);
- DOM.sinkEvents(getWidget().errorIndicatorElement,
- VTooltip.TOOLTIP_EVENTS | Event.ONCLICK);
- } else {
- getWidget().errorIndicatorElement.getStyle().clearDisplay();
- }
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().errorIndicatorElement.getStyle()
- .setDisplay(Display.NONE);
-
- getWidget().setAriaInvalid(false);
- }
+ getWidget().setAriaInvalid(getState().errorMessage != null);
getWidget().setAriaRequired(isRequiredIndicatorVisible());
if (isReadOnly()) {
diff --git a/client/src/main/java/com/vaadin/client/ui/formlayout/FormLayoutConnector.java b/client/src/main/java/com/vaadin/client/ui/formlayout/FormLayoutConnector.java
index ba1d79c776..ea9fd57c26 100644
--- a/client/src/main/java/com/vaadin/client/ui/formlayout/FormLayoutConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/formlayout/FormLayoutConnector.java
@@ -254,7 +254,8 @@ public class FormLayoutConnector extends AbstractLayoutConnector
}
getWidget().table.updateError(component.getWidget(),
- component.getState().errorMessage, hideErrors);
+ component.getState().errorMessage,
+ component.getState().errorLevel, hideErrors);
}
@Override
diff --git a/client/src/main/java/com/vaadin/client/ui/link/LinkConnector.java b/client/src/main/java/com/vaadin/client/ui/link/LinkConnector.java
index e110bbb935..edc5449127 100644
--- a/client/src/main/java/com/vaadin/client/ui/link/LinkConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/link/LinkConnector.java
@@ -18,7 +18,9 @@ package com.vaadin.client.ui.link;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.user.client.DOM;
+import com.vaadin.client.StyleConstants;
import com.vaadin.client.VCaption;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.Icon;
@@ -70,20 +72,6 @@ public class LinkConnector extends AbstractComponentConnector {
// Set link caption
VCaption.setCaptionText(getWidget().captionElement, getState());
- // handle error
- if (null != getState().errorMessage) {
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createDiv();
- DOM.setElementProperty(getWidget().errorIndicatorElement,
- "className", "v-errorindicator");
- }
- DOM.insertChild(getWidget().getElement(),
- getWidget().errorIndicatorElement, 0);
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().errorIndicatorElement.getStyle()
- .setDisplay(Display.NONE);
- }
-
if (getWidget().icon != null) {
getWidget().anchor.removeChild(getWidget().icon.getElement());
getWidget().icon = null;
diff --git a/client/src/main/java/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java b/client/src/main/java/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
index 18db2cf424..5560e9825c 100644
--- a/client/src/main/java/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java
@@ -16,7 +16,9 @@
package com.vaadin.client.ui.nativebutton;
import com.google.gwt.user.client.DOM;
+import com.vaadin.client.StyleConstants;
import com.vaadin.client.VCaption;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
@@ -55,23 +57,6 @@ public class NativeButtonConnector extends AbstractComponentConnector {
// Set text
VCaption.setCaptionText(getWidget(), getState());
- // handle error
- if (null != getState().errorMessage) {
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createSpan();
- getWidget().errorIndicatorElement
- .setClassName("v-errorindicator");
- }
- getWidget().getElement().insertBefore(
- getWidget().errorIndicatorElement,
- getWidget().captionElement);
-
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().getElement()
- .removeChild(getWidget().errorIndicatorElement);
- getWidget().errorIndicatorElement = null;
- }
-
if (getWidget().icon != null) {
getWidget().getElement().removeChild(getWidget().icon.getElement());
getWidget().icon = null;
diff --git a/client/src/main/java/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/main/java/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
index 5ab5f5fcda..ee8438de22 100644
--- a/client/src/main/java/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
@@ -275,8 +275,9 @@ public abstract class AbstractOrderedLayoutConnector
slot.setCaptionResizeListener(null);
}
- slot.setCaption(caption, icon, styles, error, showError, required,
- enabled, child.getState().captionAsHtml);
+ slot.setCaption(caption, icon, styles, error,
+ child.getState().errorLevel, showError, required, enabled,
+ child.getState().captionAsHtml);
AriaHelper.handleInputRequired(child.getWidget(), required);
AriaHelper.handleInputInvalid(child.getWidget(), showError);
diff --git a/client/src/main/java/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/main/java/com/vaadin/client/ui/orderedlayout/Slot.java
index d8e0544aaf..fb89972d04 100644
--- a/client/src/main/java/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/main/java/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -30,16 +30,19 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.StyleConstants;
import com.vaadin.client.WidgetUtil;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.ui.FontIcon;
+import com.vaadin.client.ui.HasErrorIndicatorElement;
import com.vaadin.client.ui.Icon;
import com.vaadin.client.ui.ImageIcon;
import com.vaadin.client.ui.layout.ElementResizeListener;
import com.vaadin.shared.ui.AlignmentInfo;
+import com.vaadin.shared.ui.ErrorLevel;
/**
* Represents a slot which contains the actual widget in the layout.
*/
-public class Slot extends SimplePanel {
+public class Slot extends SimplePanel implements HasErrorIndicatorElement {
private static final String ALIGN_CLASS_PREFIX = "v-align-";
@@ -493,6 +496,37 @@ public class Slot extends SimplePanel {
public void setCaption(String captionText, Icon icon, List<String> styles,
String error, boolean showError, boolean required, boolean enabled,
boolean captionAsHtml) {
+ setCaption(captionText, icon, styles, error, null, showError, required,
+ enabled, captionAsHtml);
+ }
+
+ /**
+ * Set the caption of the slot
+ *
+ * @param captionText
+ * The text of the caption
+ * @param icon
+ * The icon
+ * @param styles
+ * The style names
+ * @param error
+ * The error message
+ * @param errorLevel
+ * The error level
+ * @param showError
+ * Should the error message be shown
+ * @param required
+ * Is the (field) required
+ * @param enabled
+ * Is the component enabled
+ * @param captionAsHtml
+ * true if the caption should be rendered as HTML, false
+ * otherwise
+ * @since 8.2
+ */
+ public void setCaption(String captionText, Icon icon, List<String> styles,
+ String error, ErrorLevel errorLevel, boolean showError,
+ boolean required, boolean enabled, boolean captionAsHtml) {
// TODO place for optimization: check if any of these have changed
// since last time, and only run those changes
@@ -583,14 +617,11 @@ public class Slot extends SimplePanel {
// Error
if (error != null && showError) {
- if (errorIcon == null) {
- errorIcon = DOM.createSpan();
- errorIcon.setClassName("v-errorindicator");
- }
- caption.appendChild(errorIcon);
- } else if (errorIcon != null) {
- errorIcon.removeFromParent();
- errorIcon = null;
+ setErrorIndicatorElementVisible(true);
+ ErrorUtil.setErrorLevelStyle(getErrorIndicatorElement(),
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR, errorLevel);
+ } else {
+ setErrorIndicatorElementVisible(false);
}
if (caption != null) {
@@ -799,4 +830,22 @@ public class Slot extends SimplePanel {
return hasRelativeWidth();
}
}
+
+ @Override
+ public Element getErrorIndicatorElement() {
+ return errorIcon;
+ }
+
+ @Override
+ public void setErrorIndicatorElementVisible(boolean visible) {
+ if (visible) {
+ if (errorIcon == null) {
+ errorIcon = ErrorUtil.createErrorIndicatorElement();
+ }
+ caption.appendChild(errorIcon);
+ } else if (errorIcon != null) {
+ errorIcon.removeFromParent();
+ errorIcon = null;
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/panel/PanelConnector.java b/client/src/main/java/com/vaadin/client/ui/panel/PanelConnector.java
index 84ed73e537..25434e2701 100644
--- a/client/src/main/java/com/vaadin/client/ui/panel/PanelConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/panel/PanelConnector.java
@@ -143,8 +143,6 @@ public class PanelConnector extends AbstractSingleComponentContainerConnector
getWidget().setIconUri(null, client);
}
- getWidget().setErrorIndicatorVisible(isErrorIndicatorVisible());
-
// We may have actions attached to this panel
if (uidl.getChildCount() > 0) {
final int cnt = uidl.getChildCount();
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/checkbox/CheckBoxConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/checkbox/CheckBoxConnector.java
index d2a761ba0a..714367b0ae 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/checkbox/CheckBoxConnector.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/checkbox/CheckBoxConnector.java
@@ -21,8 +21,10 @@ import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.vaadin.client.MouseEventDetailsBuilder;
+import com.vaadin.client.StyleConstants;
import com.vaadin.client.VCaption;
import com.vaadin.client.VTooltip;
+import com.vaadin.client.WidgetUtil.ErrorUtil;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
@@ -67,7 +69,7 @@ public class CheckBoxConnector extends AbstractFieldConnector
getWidget().errorIndicatorElement = DOM.createSpan();
getWidget().errorIndicatorElement.setInnerHTML("&nbsp;");
DOM.setElementProperty(getWidget().errorIndicatorElement,
- "className", "v-errorindicator");
+ "className", StyleConstants.STYLE_NAME_ERROR_INDICATOR);
DOM.appendChild(getWidget().getElement(),
getWidget().errorIndicatorElement);
DOM.sinkEvents(getWidget().errorIndicatorElement,
@@ -75,6 +77,11 @@ public class CheckBoxConnector extends AbstractFieldConnector
} else {
getWidget().errorIndicatorElement.getStyle().clearDisplay();
}
+
+ ErrorUtil.setErrorLevelStyle(getWidget().errorIndicatorElement,
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR,
+ getState().errorLevel);
+
} else if (getWidget().errorIndicatorElement != null) {
getWidget().errorIndicatorElement.getStyle()
.setDisplay(Display.NONE);
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java
index e904cd6803..ab28118c66 100644
--- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java
+++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java
@@ -126,6 +126,7 @@ public class FormConnector extends AbstractComponentContainerConnector
if (null != getState().errorMessage) {
getWidget().errorMessage.updateMessage(getState().errorMessage);
+ getWidget().errorMessage.updateErrorLevel(getState().errorLevel);
getWidget().errorMessage.setVisible(true);
} else {
getWidget().errorMessage.setVisible(false);
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/Buffered.java b/compatibility-server/src/main/java/com/vaadin/v7/data/Buffered.java
index 2bb4065921..8bb2cefccc 100644
--- a/compatibility-server/src/main/java/com/vaadin/v7/data/Buffered.java
+++ b/compatibility-server/src/main/java/com/vaadin/v7/data/Buffered.java
@@ -21,9 +21,9 @@ import java.io.Serializable;
import com.vaadin.data.Binder;
import com.vaadin.server.AbstractErrorMessage;
import com.vaadin.server.ErrorMessage;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.ErrorMessageProducer;
import com.vaadin.server.UserError;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.v7.data.Validator.InvalidValueException;
/**
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/Validator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/Validator.java
index f226622359..f13a01a5b5 100644
--- a/compatibility-server/src/main/java/com/vaadin/v7/data/Validator.java
+++ b/compatibility-server/src/main/java/com/vaadin/v7/data/Validator.java
@@ -22,10 +22,10 @@ import com.vaadin.data.Binder;
import com.vaadin.server.AbstractErrorMessage;
import com.vaadin.server.AbstractErrorMessage.ContentMode;
import com.vaadin.server.ErrorMessage;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.ErrorMessageProducer;
import com.vaadin.server.UserError;
import com.vaadin.server.VaadinServlet;
+import com.vaadin.shared.ui.ErrorLevel;
/**
* Interface that implements a method for validating if an {@link Object} is
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
index 9b64d1e6f8..6cd7323cd9 100644
--- a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
+++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
@@ -58,6 +58,7 @@ import com.vaadin.server.VaadinSession;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.sort.SortDirection;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
diff --git a/compatibility-server/src/test/java/com/vaadin/v7/ui/AbstractLegacyComponentDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/v7/ui/AbstractLegacyComponentDeclarativeTest.java
index 5a26833169..938e2d61de 100644
--- a/compatibility-server/src/test/java/com/vaadin/v7/ui/AbstractLegacyComponentDeclarativeTest.java
+++ b/compatibility-server/src/test/java/com/vaadin/v7/ui/AbstractLegacyComponentDeclarativeTest.java
@@ -29,12 +29,12 @@ import org.jsoup.parser.Tag;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FileResource;
import com.vaadin.server.Responsive;
import com.vaadin.server.ThemeResource;
import com.vaadin.server.UserError;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.tests.design.DeclarativeTestBase;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Label;
diff --git a/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java b/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java
index cad1dc425d..b7e439244e 100644
--- a/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/AbstractErrorMessage.java
@@ -21,6 +21,8 @@ import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* Base class for component error messages.
*
diff --git a/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java b/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java
index 6d6a775a1b..510ef4ed00 100644
--- a/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/CompositeErrorMessage.java
@@ -19,6 +19,8 @@ package com.vaadin.server;
import java.util.Collection;
import java.util.Iterator;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* Class for combining multiple error messages together.
*
@@ -37,7 +39,7 @@ public class CompositeErrorMessage extends AbstractErrorMessage {
*/
public CompositeErrorMessage(ErrorMessage... errorMessages) {
super(null);
- setErrorLevel(ErrorLevel.INFORMATION);
+ setErrorLevel(ErrorLevel.INFO);
for (ErrorMessage errorMessage : errorMessages) {
addErrorMessage(errorMessage);
@@ -60,7 +62,7 @@ public class CompositeErrorMessage extends AbstractErrorMessage {
public CompositeErrorMessage(
Collection<? extends ErrorMessage> errorMessages) {
super(null);
- setErrorLevel(ErrorLevel.INFORMATION);
+ setErrorLevel(ErrorLevel.INFO);
for (ErrorMessage errorMessage : errorMessages) {
addErrorMessage(errorMessage);
diff --git a/server/src/main/java/com/vaadin/server/ErrorMessage.java b/server/src/main/java/com/vaadin/server/ErrorMessage.java
index f4030ed4c9..8095a5afdd 100644
--- a/server/src/main/java/com/vaadin/server/ErrorMessage.java
+++ b/server/src/main/java/com/vaadin/server/ErrorMessage.java
@@ -18,6 +18,8 @@ package com.vaadin.server;
import java.io.Serializable;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* Interface for rendering error messages to terminal. All the visible errors
* shown to user must implement this interface.
@@ -27,66 +29,11 @@ import java.io.Serializable;
*/
public interface ErrorMessage extends Serializable {
- public enum ErrorLevel {
- /**
- * Error code for informational messages.
- */
- INFORMATION("info", 0),
- /**
- * Error code for warning messages.
- */
- WARNING("warning", 1),
- /**
- * Error code for regular error messages.
- */
- ERROR("error", 2),
- /**
- * Error code for critical error messages.
- */
- CRITICAL("critical", 3),
- /**
- * Error code for system errors and bugs.
- */
- SYSTEMERROR("system", 4);
-
- String text;
- int errorLevel;
-
- private ErrorLevel(String text, int errorLevel) {
- this.text = text;
- this.errorLevel = errorLevel;
- }
-
- /**
- * Textual representation for server-client communication of level
- *
- * @return String for error severity
- */
- public String getText() {
- return text;
- }
-
- /**
- * Integer representation of error severity for comparison
- *
- * @return integer for error severity
- */
- public int intValue() {
- return errorLevel;
- }
-
- @Override
- public String toString() {
- return text;
- }
-
- }
-
/**
- * @deprecated As of 7.0, use {@link ErrorLevel#SYSTEMERROR} instead    
+ * @deprecated As of 7.0, use {@link ErrorLevel#SYSTEM} instead    
*/
@Deprecated
- public static final ErrorLevel SYSTEMERROR = ErrorLevel.SYSTEMERROR;
+ public static final ErrorLevel SYSTEMERROR = ErrorLevel.SYSTEM;
/**
* @deprecated As of 7.0, use {@link ErrorLevel#CRITICAL} instead    
@@ -108,10 +55,10 @@ public interface ErrorMessage extends Serializable {
public static final ErrorLevel WARNING = ErrorLevel.WARNING;
/**
- * @deprecated As of 7.0, use {@link ErrorLevel#INFORMATION} instead    
+ * @deprecated As of 7.0, use {@link ErrorLevel#INFO} instead    
*/
@Deprecated
- public static final ErrorLevel INFORMATION = ErrorLevel.INFORMATION;
+ public static final ErrorLevel INFORMATION = ErrorLevel.INFO;
/**
* Gets the errors level.
diff --git a/server/src/main/java/com/vaadin/server/SystemError.java b/server/src/main/java/com/vaadin/server/SystemError.java
index 734b4862a8..151021d1f8 100644
--- a/server/src/main/java/com/vaadin/server/SystemError.java
+++ b/server/src/main/java/com/vaadin/server/SystemError.java
@@ -16,6 +16,8 @@
package com.vaadin.server;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* <code>SystemError</code> is an error message for a problem caused by error in
* system, not the user application code. The system error can contain technical
@@ -39,7 +41,7 @@ public class SystemError extends AbstractErrorMessage {
*/
public SystemError(String message) {
super(message);
- setErrorLevel(ErrorLevel.SYSTEMERROR);
+ setErrorLevel(ErrorLevel.SYSTEM);
setMode(ContentMode.HTML);
setMessage(getHtmlMessage());
}
diff --git a/server/src/main/java/com/vaadin/server/UserError.java b/server/src/main/java/com/vaadin/server/UserError.java
index b017c9e1f9..636e98a02f 100644
--- a/server/src/main/java/com/vaadin/server/UserError.java
+++ b/server/src/main/java/com/vaadin/server/UserError.java
@@ -16,6 +16,8 @@
package com.vaadin.server;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* <code>UserError</code> is a controlled error occurred in application. User
* errors are occur in normal usage of the application and guide the user.
diff --git a/server/src/main/java/com/vaadin/ui/AbstractComponent.java b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
index a0bb648ffb..f74f2141da 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
@@ -45,7 +45,6 @@ import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ComponentSizeValidator;
import com.vaadin.server.ErrorMessage;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.Extension;
import com.vaadin.server.Resource;
import com.vaadin.server.Responsive;
@@ -62,6 +61,7 @@ import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.Registration;
import com.vaadin.shared.ui.ComponentStateUtil;
import com.vaadin.shared.ui.ContentMode;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
@@ -723,8 +723,10 @@ public abstract class AbstractComponent extends AbstractClientConnector
ErrorMessage error = getErrorMessage();
if (null != error) {
getState().errorMessage = error.getFormattedHtmlMessage();
+ getState().errorLevel = error.getErrorLevel();
} else {
getState().errorMessage = null;
+ getState().errorLevel = null;
}
}
diff --git a/server/src/main/java/com/vaadin/ui/TabSheet.java b/server/src/main/java/com/vaadin/ui/TabSheet.java
index 385c6b5f5c..ac3a22eb41 100644
--- a/server/src/main/java/com/vaadin/ui/TabSheet.java
+++ b/server/src/main/java/com/vaadin/ui/TabSheet.java
@@ -1314,9 +1314,15 @@ public class TabSheet extends AbstractComponentContainer
public void setComponentError(ErrorMessage componentError) {
this.componentError = componentError;
- String formattedHtmlMessage = componentError != null
- ? componentError.getFormattedHtmlMessage() : null;
- tabState.componentError = formattedHtmlMessage;
+ if (componentError != null) {
+ tabState.componentError = componentError
+ .getFormattedHtmlMessage();
+ tabState.componentErrorLevel = componentError.getErrorLevel();
+ } else {
+ tabState.componentError = null;
+ tabState.componentErrorLevel = null;
+ }
+
markAsDirty();
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
index 018aa25cd4..b2a32efaa0 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTest.java
@@ -28,13 +28,13 @@ import org.jsoup.parser.Tag;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FileResource;
import com.vaadin.server.Responsive;
import com.vaadin.server.ThemeResource;
import com.vaadin.server.UserError;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.tests.design.DeclarativeTestBase;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Button;
diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
index 84c2534f84..48d9646c37 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/abstractcomponent/AbstractComponentDeclarativeTestBase.java
@@ -24,11 +24,11 @@ import java.util.Locale;
import org.junit.Test;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FileResource;
import com.vaadin.server.ThemeResource;
import com.vaadin.server.UserError;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.tests.design.DeclarativeTestBase;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.declarative.DesignContext;
diff --git a/shared/src/main/java/com/vaadin/shared/AbstractComponentState.java b/shared/src/main/java/com/vaadin/shared/AbstractComponentState.java
index 81f808f676..9b949111a7 100644
--- a/shared/src/main/java/com/vaadin/shared/AbstractComponentState.java
+++ b/shared/src/main/java/com/vaadin/shared/AbstractComponentState.java
@@ -21,6 +21,7 @@ import java.util.List;
import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.ui.ContentMode;
+import com.vaadin.shared.ui.ErrorLevel;
/**
* Default shared state implementation for AbstractComponent.
@@ -43,9 +44,15 @@ public class AbstractComponentState extends SharedState {
public String id = null;
public String primaryStyleName = null;
- // HTML formatted error message for the component
- // TODO this could be an object with more information, but currently the UI
- // only uses the message
+ /** HTML formatted error message for the component */
public String errorMessage = null;
+
+ /**
+ * Level of error
+ *
+ * @since 8.2
+ */
+ public ErrorLevel errorLevel = null;
+
public boolean captionAsHtml = false;
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/ErrorLevel.java b/shared/src/main/java/com/vaadin/shared/ui/ErrorLevel.java
new file mode 100644
index 0000000000..fe216fb878
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/ErrorLevel.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.shared.ui;
+
+/**
+ * Represents the error levels displayed on components.
+ * @author Vaadin Ltd
+ * @since
+ */
+public enum ErrorLevel {
+
+ /**
+ * Error level for informational messages.
+ */
+ INFO,
+
+ /**
+ * Error level for warning messages.
+ */
+ WARNING,
+
+ /**
+ * Error level for regular messages.
+ */
+ ERROR,
+
+ /**
+ * Error level for critical messages.
+ */
+ CRITICAL,
+
+ /**
+ * Error level for system errors and bugs.
+ */
+ SYSTEM;
+
+ /**
+ * Integer representation of error severity for comparison
+ *
+ * @return integer for error severity
+ */
+ public int intValue() {
+ return ordinal();
+ }
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/tabsheet/TabState.java b/shared/src/main/java/com/vaadin/shared/ui/tabsheet/TabState.java
index 763f2cf20f..b337d4f063 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/tabsheet/TabState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/tabsheet/TabState.java
@@ -19,6 +19,8 @@ import java.io.Serializable;
import com.vaadin.shared.ui.ContentMode;
+import com.vaadin.shared.ui.ErrorLevel;
+
/**
* Shared state of a single tab in a Tabsheet or an Accordion.
*
@@ -36,6 +38,13 @@ public class TabState implements Serializable {
public String styleName;
public String key;
public String componentError;
+
+ /**
+ * Represents the level of error on a tab.
+ *
+ * @since 8.2
+ */
+ public ErrorLevel componentErrorLevel;
public String id;
public String iconAltText;
diff --git a/tests/screenshots b/tests/screenshots
-Subproject 3a4a26065d36ac5fb706c159f1dd757fb52bf8e
+Subproject 37f67cd836df7d34469f55298bb167696338f2a
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
index 4069415985..8e45fc4afc 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_combobox.scss
@@ -35,6 +35,61 @@
}
}
+ .#{$primary-stylename}-error-info {
+ .#{$primary-stylename}-input {
+ @include valo-textfield-error-level-info-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-info-color;
+ border-color: $v-error-indicator-level-info-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-warning {
+ .#{$primary-stylename}-input {
+ @include valo-textfield-error-level-warning-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-warning-color;
+ border-color: $v-error-indicator-level-warning-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-error {
+ .#{$primary-stylename}-input {
+ @include valo-textfield-error-level-error-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-error-color;
+ border-color: $v-error-indicator-level-error-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-critical {
+ .#{$primary-stylename}-input {
+ @include valo-textfield-error-level-critical-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-critical-color;
+ border-color: $v-error-indicator-level-critical-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-system {
+ .#{$primary-stylename}-input {
+ @include valo-textfield-error-level-system-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-system-color;
+ border-color: $v-error-indicator-level-system-color;
+ }
+ }
+
.#{$primary-stylename}-suggestpopup {
@include valo-combobox-popup-style;
}
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss
index bfe1e33743..e92c9ce436 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss
@@ -25,6 +25,61 @@
}
}
+ .#{$primary-stylename}-error-info {
+ .#{$primary-stylename}-textfield {
+ @include valo-textfield-error-level-info-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-info-color;
+ border-color: $v-error-indicator-level-info-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-warning {
+ .#{$primary-stylename}-textfield {
+ @include valo-textfield-error-level-warning-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-warning-color;
+ border-color: $v-error-indicator-level-warning-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-error {
+ .#{$primary-stylename}-textfield {
+ @include valo-textfield-error-level-error-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-error-color;
+ border-color: $v-error-indicator-level-error-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-critical {
+ .#{$primary-stylename}-textfield {
+ @include valo-textfield-error-level-critical-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-critical-color;
+ border-color: $v-error-indicator-level-critical-color;
+ }
+ }
+
+ .#{$primary-stylename}-error-system {
+ .#{$primary-stylename}-textfield {
+ @include valo-textfield-error-level-system-style;
+ }
+
+ .#{$primary-stylename}-button {
+ color: $v-error-indicator-level-system-color;
+ border-color: $v-error-indicator-level-system-color;
+ }
+ }
+
// Different widths for different resolutions
.#{$primary-stylename}-full {
width: round($v-font-size * 15);
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_textfield.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_textfield.scss
index 5a62be5dbc..91fad01744 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_textfield.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_textfield.scss
@@ -70,6 +70,25 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
@include valo-textfield-error-style;
}
+ .#{$primary-stylename}-error-info {
+ @include valo-textfield-error-level-info-style;
+ }
+
+ .#{$primary-stylename}-error-warning {
+ @include valo-textfield-error-level-warning-style;
+ }
+
+ .#{$primary-stylename}-error-error {
+ @include valo-textfield-error-level-error-style;
+ }
+
+ .#{$primary-stylename}-error-critical {
+ @include valo-textfield-error-level-critical-style;
+ }
+
+ .#{$primary-stylename}-error-system {
+ @include valo-textfield-error-level-system-style;
+ }
@if $include-additional-styles {
.#{$primary-stylename}-borderless {
@@ -319,13 +338,58 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
*
* @group textfield
*/
-@mixin valo-textfield-error-style {
- border-color: $v-error-indicator-color !important;
- $bg: scale-color($v-error-indicator-color, $lightness: 98%);
+@mixin valo-textfield-error-style($indicator-color: $v-error-indicator-color) {
+ border-color: $indicator-color !important;
+ $bg: scale-color($indicator-color, $lightness: 98%);
background: $bg;
color: valo-font-color($bg);
}
+/**
+ * Outputs the styles for a text field error state with error level 'info'.
+ *
+ * @group textfield
+ */
+@mixin valo-textfield-error-level-info-style {
+ @include valo-textfield-error-style($v-error-indicator-level-info-color);
+}
+
+/**
+ * Outputs the styles for a text field error state with error level 'warning'.
+ *
+ * @group textfield
+ */
+@mixin valo-textfield-error-level-warning-style {
+ @include valo-textfield-error-style($v-error-indicator-level-warning-color);
+}
+
+/**
+ * Outputs the styles for a text field error state with error level 'error'.
+ *
+ * @group textfield
+ */
+@mixin valo-textfield-error-level-error-style {
+ @include valo-textfield-error-style($v-error-indicator-level-error-color);
+}
+
+/**
+ * Outputs the styles for a text field error state with error level 'critical'.
+ *
+ * @group textfield
+ */
+@mixin valo-textfield-error-level-critical-style {
+ @include valo-textfield-error-style($v-error-indicator-level-critical-color);
+}
+
+/**
+ * Outputs the styles for a text field error state with error level 'system'.
+ *
+ * @group textfield
+ */
+@mixin valo-textfield-error-level-system-style {
+ @include valo-textfield-error-style($v-error-indicator-level-system-color);
+}
+
/**
* Outputs the selectors and styles for an inline-icon style for a text field. Included indipendently (i.e. not enclosed with a parent text field selector).
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_twincolselect.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_twincolselect.scss
index 1d9a7e773e..8d220292e7 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_twincolselect.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_twincolselect.scss
@@ -85,6 +85,40 @@
}
}
+ .#{$primary-stylename}-error-info {
+ .#{$primary-stylename}-options,
+ .#{$primary-stylename}-selections {
+ @include valo-textfield-error-level-info-style;
+ }
+ }
+
+ .#{$primary-stylename}-error-warning {
+ .#{$primary-stylename}-options,
+ .#{$primary-stylename}-selections {
+ @include valo-textfield-error-level-warning-style;
+ }
+ }
+
+ .#{$primary-stylename}-error-error {
+ .#{$primary-stylename}-options,
+ .#{$primary-stylename}-selections {
+ @include valo-textfield-error-level-error-style;
+ }
+ }
+
+ .#{$primary-stylename}-error-critical {
+ .#{$primary-stylename}-options,
+ .#{$primary-stylename}-selections {
+ @include valo-textfield-error-level-critical-style;
+ }
+ }
+
+ .#{$primary-stylename}-error-system {
+ .#{$primary-stylename}-options,
+ .#{$primary-stylename}-selections {
+ @include valo-textfield-error-level-system-style;
+ }
+ }
}
diff --git a/themes/src/main/themes/VAADIN/themes/valo/shared/_global.scss b/themes/src/main/themes/VAADIN/themes/valo/shared/_global.scss
index ecd8e1a59b..99fbd360b1 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/shared/_global.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/shared/_global.scss
@@ -313,6 +313,26 @@ $valo-shared-pathPrefix: null;
@include valo-error-indicator-style;
}
+ .v-errorindicator-info {
+ @include valo-error-indicator-style($indicator-color: $v-error-indicator-level-info-color);
+ }
+
+ .v-errorindicator-warning {
+ @include valo-error-indicator-style($indicator-color: $v-error-indicator-level-warning-color);
+ }
+
+ .v-errorindicator-error {
+ @include valo-error-indicator-style($indicator-color: $v-error-indicator-level-error-color);
+ }
+
+ .v-errorindicator-critical {
+ @include valo-error-indicator-style($indicator-color: $v-error-indicator-level-critical-color);
+ }
+
+ .v-errorindicator-system {
+ @include valo-error-indicator-style($indicator-color: $v-error-indicator-level-system-color);
+ }
+
.v-required-field-indicator {
color: $v-required-field-indicator-color;
padding: 0 .2em;
@@ -366,8 +386,8 @@ $valo-shared-pathPrefix: null;
*
* @requires {mixin} valo-error-indicator-icon-style by default
*/
-@mixin valo-error-indicator-style ($is-pseudo-element: false) {
- color: $v-error-indicator-color;
+@mixin valo-error-indicator-style ($is-pseudo-element: false, $indicator-color: $v-error-indicator-color) {
+ color: $indicator-color;
font-weight: 600;
width: ceil($v-unit-size/2);
text-align: center;
diff --git a/themes/src/main/themes/VAADIN/themes/valo/shared/_tooltip.scss b/themes/src/main/themes/VAADIN/themes/valo/shared/_tooltip.scss
index cb3824d26f..99c453b16e 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/shared/_tooltip.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/shared/_tooltip.scss
@@ -63,6 +63,46 @@ $v-tooltip-error-message-background-color: #fff !default;
$v-tooltip-error-message-font-color: $v-error-indicator-color !default;
/**
+ * The font color for error tooltips for level 'info'.
+ *
+ * @type color
+ * @group tooltip
+ */
+$v-tooltip-error-message-level-info-font-color: $v-error-indicator-level-info-color !default;
+
+/**
+ * The font color for error tooltips for level 'warning'.
+ *
+ * @type color
+ * @group tooltip
+ */
+$v-tooltip-error-message-level-warning-font-color: $v-error-indicator-level-warning-color !default;
+
+/**
+ * The font color for error tooltips for level 'error'.
+ *
+ * @type color
+ * @group tooltip
+ */
+$v-tooltip-error-message-level-error-font-color: $v-error-indicator-level-error-color !default;
+
+/**
+ * The font color for error tooltips for level 'critical'.
+ *
+ * @type color
+ * @group tooltip
+ */
+$v-tooltip-error-message-level-critical-font-color: $v-error-indicator-level-critical-color !default;
+
+/**
+ * The font color for error tooltips for level 'system'.
+ *
+ * @type color
+ * @group tooltip
+ */
+$v-tooltip-error-message-level-system-font-color: $v-error-indicator-level-system-color !default;
+
+/**
* The corner radius for tooltips.
*
* @type size
@@ -100,6 +140,26 @@ $v-tooltip-border-radius: $v-border-radius - 1px !default;
}
}
+ .v-errormessage-info {
+ color: $v-tooltip-error-message-level-info-font-color;
+ }
+
+ .v-errormessage-warning {
+ color: $v-tooltip-error-message-level-warning-font-color;
+ }
+
+ .v-errormessage-error {
+ color: $v-tooltip-error-message-level-error-font-color;
+ }
+
+ .v-errormessage-critical {
+ color: $v-tooltip-error-message-level-critical-font-color;
+ }
+
+ .v-errormessage-system {
+ color: $v-tooltip-error-message-level-system-font-color;
+ }
+
.v-tooltip-text {
max-height: 10em;
overflow: auto;
diff --git a/themes/src/main/themes/VAADIN/themes/valo/shared/_variables.scss b/themes/src/main/themes/VAADIN/themes/valo/shared/_variables.scss
index 3237018087..51f6f73350 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/shared/_variables.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/shared/_variables.scss
@@ -207,13 +207,53 @@ $v-disabled-opacity: 0.5 !default;
$v-selection-color: $v-focus-color !default;
/**
+ * Color of the component error indication for 'info' error level.
+
+ * @group color
+ * @type color
+ */
+$v-error-indicator-level-info-color: #00a7f5 !default;
+
+/**
+ * Color of the component error indication for 'warning' error level.
+
+ * @group color
+ * @type color
+ */
+$v-error-indicator-level-warning-color: #fc9c00 !default;
+
+/**
+ * Color of the component error indication for 'error' error level.
+
+ * @group color
+ * @type color
+ */
+$v-error-indicator-level-error-color: #ed473b !default;
+
+/**
+ * Color of the component error indication for 'critical' error level.
+
+ * @group color
+ * @type color
+ */
+$v-error-indicator-level-critical-color: #fa007d !default;
+
+/**
+ * Color of the component error indication for 'system' error level.
+
+ * @group color
+ * @type color
+ */
+$v-error-indicator-level-system-color: #bb00ff !default;
+
+/**
* Color of the component error indicator and other error indications, such as the
* error style notification.
*
* @group color
* @type color
*/
-$v-error-indicator-color: #ed473b !default;
+$v-error-indicator-color: $v-error-indicator-level-error-color !default;
/**
* Color of the required indicator in field components.
diff --git a/uitest/src/main/java/com/vaadin/tests/components/ErrorLevels.java b/uitest/src/main/java/com/vaadin/tests/components/ErrorLevels.java
new file mode 100644
index 0000000000..9ab5ca6f0b
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/ErrorLevels.java
@@ -0,0 +1,210 @@
+package com.vaadin.tests.components;
+
+import java.util.Arrays;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.AbstractErrorMessage;
+import com.vaadin.server.ErrorMessage;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.UserError;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.ErrorLevel;
+import com.vaadin.ui.Accordion;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Link;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.TwinColSelect;
+import com.vaadin.ui.themes.ValoTheme;
+
+@Theme("valo")
+public class ErrorLevels extends AbstractTestUI {
+
+ private ComboBox<ErrorLevel> errorLevels;
+ private Button button;
+ private Button borderlessButton;
+ private Link link;
+ private ComboBox<String> comboBox;
+ private TextField textField;
+ private TextField textFieldBorderless;
+ private TabSheet tabSheet;
+ private Accordion accordion;
+ private CheckBox checkBox;
+ private NativeButton nativeButton;
+ private FormLayout formLayout;
+ private TextField formLayoutTextField;
+ private Panel panel;
+ private DateField dateField;
+ private TwinColSelect twinColSelect;
+
+ private com.vaadin.v7.ui.ComboBox comboBoxCompat;
+ private com.vaadin.v7.ui.TextField textFieldCompat;
+ private com.vaadin.v7.ui.CheckBox checkBoxCompat;
+ private com.vaadin.v7.ui.DateField dateFieldCompat;
+ private com.vaadin.v7.ui.TwinColSelect twinColSelectCompat;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ errorLevels = new ComboBox<>("Error level",
+ Arrays.asList(ErrorLevel.values()));
+ errorLevels.setEmptySelectionAllowed(false);
+ errorLevels.setValue(ErrorLevel.ERROR);
+ errorLevels.addValueChangeListener(event -> setErrorMessages());
+ addComponent(errorLevels);
+
+ Label subtitle = new Label("Components");
+ subtitle.setStyleName(ValoTheme.LABEL_H3);
+ addComponent(subtitle);
+
+ // Button
+ button = new Button("Button");
+
+ borderlessButton = new Button("Borderless button");
+ borderlessButton.setStyleName(ValoTheme.BUTTON_BORDERLESS);
+
+ addComponent(new HorizontalLayout(button, borderlessButton));
+
+ // Native button
+ nativeButton = new NativeButton("Native button");
+ addComponent(nativeButton);
+
+ // Link
+ link = new Link("Link", new ExternalResource("#"));
+ addComponent(link);
+
+ // Combo box
+ comboBox = new ComboBox<>("Combo box");
+ addComponent(comboBox);
+
+ // Text field
+ textField = new TextField("Text field");
+ textField.setValue("text");
+
+ textFieldBorderless = new TextField("Borderless text field");
+ textFieldBorderless.setStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
+ textFieldBorderless.setValue("text");
+
+ addComponent(new HorizontalLayout(textField, textFieldBorderless));
+
+ // Date field
+ dateField = new DateField("Date field");
+ addComponent(dateField);
+
+ // Check box
+ checkBox = new CheckBox("Check box");
+ addComponent(checkBox);
+
+ // Tab sheet
+ tabSheet = new TabSheet();
+ tabSheet.addTab(new Label("Label1"), "Tab1");
+ tabSheet.addTab(new Label("Label2"), "Tab2");
+ tabSheet.setWidth("400px");
+ addComponent(tabSheet);
+
+ // Accordion
+ accordion = new Accordion();
+ accordion.addTab(new Label("Label1"), "Tab1");
+ accordion.addTab(new Label("Label2"), "Tab2");
+ accordion.setWidth("400px");
+ addComponent(accordion);
+
+ // Form layout
+ formLayout = new FormLayout();
+ formLayout.setWidth("400px");
+
+ formLayoutTextField = new TextField("Form layout text field");
+ formLayout.addComponent(formLayoutTextField);
+
+ addComponent(formLayout);
+
+ // Panel
+ panel = new Panel();
+ panel.setContent(new Label("Panel"));
+ panel.setWidth("400px");
+ addComponent(panel);
+
+ // TwinColSelect
+ twinColSelect = new TwinColSelect("Twin col select");
+ addComponent(twinColSelect);
+
+ Label subtitleCompat = new Label("Compatibility components");
+ subtitleCompat.setStyleName(ValoTheme.LABEL_H3);
+ addComponent(subtitleCompat);
+
+ // Compatibility combo box
+ comboBoxCompat = new com.vaadin.v7.ui.ComboBox(
+ "Compatibility combo box");
+ addComponent(comboBoxCompat);
+
+ // Compatibility text field
+ textFieldCompat = new com.vaadin.v7.ui.TextField(
+ "Compatibility text field");
+ textFieldCompat.setValue("text");
+
+ // Compatibility check box
+ checkBoxCompat = new com.vaadin.v7.ui.CheckBox("Check box");
+ addComponent(checkBoxCompat);
+
+ // Compatibility date field
+ dateFieldCompat = new com.vaadin.v7.ui.DateField("Date field");
+ addComponent(dateFieldCompat);
+
+ // Compatibility twin col select
+ twinColSelectCompat = new com.vaadin.v7.ui.TwinColSelect(
+ "Twin col select");
+ addComponent(twinColSelectCompat);
+
+ setErrorMessages();
+
+ getLayout().setSpacing(true);
+ }
+
+ private void setErrorMessages() {
+ button.setComponentError(createErrorMessage("Button error"));
+ borderlessButton.setComponentError(
+ createErrorMessage("Borderless button error"));
+ link.setComponentError(createErrorMessage("Link error"));
+ comboBox.setComponentError(createErrorMessage("ComboBox error"));
+ textField.setComponentError(createErrorMessage("Text field error"));
+ textFieldBorderless.setComponentError(
+ createErrorMessage("Borderless text field error"));
+ tabSheet.setComponentError(createErrorMessage("Tab sheet error"));
+ tabSheet.getTab(0).setComponentError(createErrorMessage("Tab error"));
+ accordion.setComponentError(createErrorMessage("Accordion error"));
+ accordion.getTab(0).setComponentError(createErrorMessage("Tab error"));
+ checkBox.setComponentError(createErrorMessage("Check box error"));
+ nativeButton
+ .setComponentError(createErrorMessage("Native button error"));
+ formLayout.setComponentError(createErrorMessage("Form layout error"));
+ formLayoutTextField.setComponentError(
+ createErrorMessage("Form layout text field error"));
+ panel.setComponentError(createErrorMessage("Panel error"));
+ dateField.setComponentError(createErrorMessage("Date field error"));
+ twinColSelect
+ .setComponentError(createErrorMessage("Twin col select error"));
+ comboBoxCompat.setComponentError(
+ createErrorMessage("Compatibility combo box error"));
+ textFieldCompat.setComponentError(
+ createErrorMessage("Compatibility text field error"));
+ checkBoxCompat.setComponentError(
+ createErrorMessage("Compatibility check box error"));
+ dateFieldCompat.setComponentError(
+ createErrorMessage("Compatibility date field error"));
+ twinColSelectCompat.setComponentError(
+ createErrorMessage("Compatibility twin col select error"));
+ }
+
+ private ErrorMessage createErrorMessage(String text) {
+ return new UserError(text, AbstractErrorMessage.ContentMode.TEXT,
+ errorLevels.getValue());
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/themes/valo/CommonParts.java b/uitest/src/main/java/com/vaadin/tests/themes/valo/CommonParts.java
index 6d7a67cfa8..4c83430832 100644
--- a/uitest/src/main/java/com/vaadin/tests/themes/valo/CommonParts.java
+++ b/uitest/src/main/java/com/vaadin/tests/themes/valo/CommonParts.java
@@ -20,11 +20,11 @@ import com.vaadin.icons.VaadinIcons;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.AbstractErrorMessage;
-import com.vaadin.server.ErrorMessage.ErrorLevel;
import com.vaadin.server.Page;
import com.vaadin.server.UserError;
import com.vaadin.shared.Position;
import com.vaadin.shared.ui.ContentMode;
+import com.vaadin.shared.ui.ErrorLevel;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
diff --git a/uitest/src/test/java/com/vaadin/tests/components/ErrorLevelsTest.java b/uitest/src/test/java/com/vaadin/tests/components/ErrorLevelsTest.java
new file mode 100644
index 0000000000..750545ce89
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/components/ErrorLevelsTest.java
@@ -0,0 +1,160 @@
+package com.vaadin.tests.components;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.client.StyleConstants;
+import com.vaadin.shared.ui.ErrorLevel;
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.AccordionElement;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.testbench.elements.FormLayoutElement;
+import com.vaadin.testbench.elements.LinkElement;
+import com.vaadin.testbench.elements.NativeButtonElement;
+import com.vaadin.testbench.elements.PanelElement;
+import com.vaadin.testbench.elements.TabSheetElement;
+import com.vaadin.testbench.elements.TwinColSelectElement;
+import com.vaadin.testbench.parallel.BrowserUtil;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class ErrorLevelsTest extends SingleBrowserTest {
+
+ private ComboBoxElement errorLevelSelector;
+
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+ openTestURL();
+
+ errorLevelSelector = $(ComboBoxElement.class).first();
+ }
+
+ @Test
+ public void testErrorIndicatorsClassName() {
+ ErrorLevel errorLevel = ErrorLevel.WARNING;
+ selectErrorLevel(errorLevel);
+
+ List<WebElement> errorIndicators = findElements(
+ By.className(StyleConstants.STYLE_NAME_ERROR_INDICATOR));
+ for (WebElement errorIndicator : errorIndicators) {
+ assertHasRightClassNames(errorIndicator,
+ StyleConstants.STYLE_NAME_ERROR_INDICATOR, errorLevel);
+ }
+ }
+
+ @Test
+ public void testComponentsClassName() {
+ ErrorLevel errorLevel = ErrorLevel.WARNING;
+ selectErrorLevel(errorLevel);
+
+ // Button
+ ButtonElement buttonElement = $(ButtonElement.class).first();
+ assertHasRightClassNames(buttonElement, "v-button-error", errorLevel);
+
+ // Native button
+ NativeButtonElement nativeButtonElement = $(NativeButtonElement.class)
+ .first();
+ assertHasRightClassNames(nativeButtonElement, "v-nativebutton-error",
+ errorLevel);
+
+ // Link
+ LinkElement linkElement = $(LinkElement.class).first();
+ assertHasRightClassNames(linkElement, "v-link-error", errorLevel);
+
+ // Combo box
+ ComboBoxElement comboBoxElement = $(ComboBoxElement.class).get(1);
+ assertHasRightClassNames(comboBoxElement, "v-filterselect-error",
+ errorLevel);
+
+ // Date field
+ DateFieldElement dateFieldElement = $(DateFieldElement.class).first();
+ assertHasRightClassNames(dateFieldElement, "v-datefield-error",
+ errorLevel);
+
+ // Checkbox
+ CheckBoxElement checkBoxElement = $(CheckBoxElement.class).first();
+ assertHasRightClassNames(checkBoxElement, "v-checkbox-error",
+ errorLevel);
+
+ // Tab sheet
+ TabSheetElement tabSheetElement = $(TabSheetElement.class).first();
+ assertHasRightClassNames(tabSheetElement, "v-tabsheet-error",
+ errorLevel);
+
+ // Accordion
+ AccordionElement accordionElement = $(AccordionElement.class).first();
+ assertHasRightClassNames(accordionElement, "v-accordion-error",
+ errorLevel);
+
+ // Form layout
+ FormLayoutElement formLayoutElement = $(FormLayoutElement.class)
+ .first();
+ assertHasRightClassNames(formLayoutElement, "v-formlayout-error",
+ errorLevel);
+
+ // Panel
+ PanelElement panelElement = $(PanelElement.class).first();
+ assertHasRightClassNames(panelElement, "v-panel-error", errorLevel);
+
+ // Twin col select
+ TwinColSelectElement twinColSelectElement = $(
+ TwinColSelectElement.class).first();
+ assertHasRightClassNames(twinColSelectElement, "v-select-twincol-error",
+ errorLevel);
+ }
+
+ private void assertHasRightClassNames(WebElement element, String prefix,
+ ErrorLevel errorLevel) {
+ Assert.assertTrue("Element must have only one error level class name",
+ containsCorrectErrorLevelClassNameOnly(element, prefix,
+ errorLevel));
+ }
+
+ private boolean containsCorrectErrorLevelClassNameOnly(WebElement element,
+ String prefix, ErrorLevel errorLevel) {
+ List<String> classNames = new ArrayList<String>(
+ Arrays.asList(element.getAttribute("class").split(" ")));
+ classNames.retainAll(getErrorLevelClassNames(prefix,
+ Arrays.asList(ErrorLevel.values())));
+ return classNames.size() == 1 && classNames
+ .contains(getErrorLevelClassName(prefix, errorLevel));
+ }
+
+ private String getErrorLevelClassName(String prefix,
+ ErrorLevel errorLevel) {
+ return prefix + "-" + errorLevel.toString().toLowerCase();
+ }
+
+ private List<String> getErrorLevelClassNames(String prefix,
+ Collection<ErrorLevel> errorLevels) {
+ List<String> classNames = new ArrayList<String>(errorLevels.size());
+ for (ErrorLevel errorLevel : errorLevels) {
+ classNames.add(getErrorLevelClassName(prefix, errorLevel));
+ }
+ return classNames;
+ }
+
+ private void selectErrorLevel(ErrorLevel errorLevel) {
+ errorLevelSelector.clear();
+ errorLevelSelector.sendKeys(errorLevel.toString().toLowerCase());
+ errorLevelSelector.sendKeys(getReturn());
+ }
+
+ private Keys getReturn() {
+ if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) {
+ return Keys.ENTER;
+ } else {
+ return Keys.RETURN;
+ }
+ }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java b/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java
index 99c7a1d770..31011b8837 100644
--- a/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java
+++ b/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java
@@ -84,8 +84,8 @@ public class TabSheetErrorTooltipTest extends MultiBrowserTest {
}
private WebElement getCurrentErrorMessage() {
- return getDriver()
- .findElement(By.xpath("//div[@class='v-errormessage']"));
+ return getDriver().findElement(
+ By.xpath("//div[contains(@class, 'v-errormessage')]"));
}
private void assertTooltip(String tooltip) {