Add additional class names and style to components and error indicators to distinguish different error levels. Vaadin 8 implementation of #9816. Cherry picked changes and added compatibility package component changes and tests. Resolves #3139tags/8.2.0.alpha2
<li><tt>DataCommunicator</tt> method <tt>getDataProviderSize</tt> is now <tt>public</tt>, not <tt>protected</tt>.</li> | <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>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>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><span class="v-errorindicator"></span></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> | <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> | ||||
public static final String REQUIRED_EXT = "-required"; | public static final String REQUIRED_EXT = "-required"; | ||||
public static final String ERROR_EXT = "-error"; | 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"; | |||||
} | } |
package com.vaadin.client; | package com.vaadin.client; | ||||
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.shared.util.SharedUtil; | 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 { | public class TooltipInfo { | ||||
private String title; | private String title; | ||||
private String errorMessageHtml; | private String errorMessageHtml; | ||||
private ErrorLevel errorLevel; | |||||
// Contains the tooltip's identifier. If a tooltip's contents and this | // Contains the tooltip's identifier. If a tooltip's contents and this | ||||
// identifier haven't changed, the tooltip won't be updated in subsequent | // identifier haven't changed, the tooltip won't be updated in subsequent | ||||
// events. | // events. | ||||
private Object identifier; | private Object identifier; | ||||
/** | |||||
* Constructs a new tooltip info instance. | |||||
*/ | |||||
public TooltipInfo() { | public TooltipInfo() { | ||||
} | } | ||||
/** | |||||
* Constructs a new tooltip info instance. | |||||
* | |||||
* @param tooltip | |||||
* tooltip title | |||||
*/ | |||||
public TooltipInfo(String tooltip) { | public TooltipInfo(String tooltip) { | ||||
this(tooltip, ContentMode.PREFORMATTED); | this(tooltip, ContentMode.PREFORMATTED); | ||||
} | } | ||||
/** | /** | ||||
* Constructs a new instance using the {@code tooltip} for the title and | * Constructs a new instance using the {@code tooltip} for the title and | ||||
* {@code errorMessage} as a description. | * {@code errorMessage} as a description. | ||||
* | |||||
* | |||||
* @param tooltip | * @param tooltip | ||||
* tooltip title | * tooltip title | ||||
* @param errorMessage | * @param errorMessage | ||||
* error description | * error description | ||||
* | |||||
* | |||||
* @deprecated use {@link #TooltipInfo(String, ContentMode, String)} instead | * @deprecated use {@link #TooltipInfo(String, ContentMode, String)} instead | ||||
*/ | */ | ||||
@Deprecated | @Deprecated | ||||
/** | /** | ||||
* Constructs a new instance using the {@code tooltip} for the title, | * Constructs a new instance using the {@code tooltip} for the title, | ||||
* {@code errorMessage} as a description and {@code identifier} as its id. | * {@code errorMessage} as a description and {@code identifier} as its id. | ||||
* | |||||
* | |||||
* @param tooltip | * @param tooltip | ||||
* tooltip title | * tooltip title | ||||
* @param errorMessage | * @param errorMessage | ||||
* error description | * error description | ||||
* @param identifier | * @param identifier | ||||
* | |||||
* the tooltip's identifier | |||||
* | |||||
* @deprecated use {@link #TooltipInfo(String, ContentMode, String, Object)} | * @deprecated use {@link #TooltipInfo(String, ContentMode, String, Object)} | ||||
* instead | * instead | ||||
*/ | */ | ||||
this(tooltip, ContentMode.HTML, errorMessage, identifier); | 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) { | public TooltipInfo(String tooltip, ContentMode mode) { | ||||
setTitle(tooltip); | setTitle(tooltip); | ||||
setContentMode(mode); | 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) { | public TooltipInfo(String tooltip, ContentMode mode, String errorMessage) { | ||||
this(tooltip, mode, errorMessage, null); | 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, | public TooltipInfo(String tooltip, ContentMode mode, String errorMessage, | ||||
Object identifier) { | 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); | setIdentifier(identifier); | ||||
setTitle(tooltip); | setTitle(tooltip); | ||||
setContentMode(mode); | setContentMode(mode); | ||||
setErrorMessage(errorMessage); | setErrorMessage(errorMessage); | ||||
setErrorLevel(errorLevel); | |||||
} | } | ||||
/** | |||||
* Sets the tooltip's identifier. | |||||
* | |||||
* @param identifier | |||||
* the identifier to set | |||||
*/ | |||||
public void setIdentifier(Object identifier) { | public void setIdentifier(Object identifier) { | ||||
this.identifier = identifier; | this.identifier = identifier; | ||||
} | } | ||||
/** | |||||
* Gets the tooltip's identifier. | |||||
* | |||||
* @return the identifier | |||||
*/ | |||||
public Object getIdentifier() { | public Object getIdentifier() { | ||||
return identifier; | return identifier; | ||||
} | } | ||||
/** | |||||
* Gets the tooltip title. | |||||
* | |||||
* @return the title | |||||
*/ | |||||
public String getTitle() { | public String getTitle() { | ||||
return title; | return title; | ||||
} | } | ||||
/** | |||||
* Sets the tooltip title. | |||||
* | |||||
* @param title | |||||
* the title to set | |||||
*/ | |||||
public void setTitle(String title) { | public void setTitle(String title) { | ||||
this.title = title; | this.title = title; | ||||
} | } | ||||
/** | |||||
* Gets the error message. | |||||
* | |||||
* @return the error message | |||||
*/ | |||||
public String getErrorMessage() { | public String getErrorMessage() { | ||||
return errorMessageHtml; | return errorMessageHtml; | ||||
} | } | ||||
/** | |||||
* Sets the error message. | |||||
* | |||||
* @param errorMessage | |||||
* the error message to set | |||||
*/ | |||||
public void setErrorMessage(String errorMessage) { | public void setErrorMessage(String errorMessage) { | ||||
errorMessageHtml = errorMessage; | errorMessageHtml = errorMessage; | ||||
} | } | ||||
/** | |||||
* Gets the tooltip title's content mode. | |||||
* | |||||
* @return the content mode | |||||
*/ | |||||
public ContentMode getContentMode() { | public ContentMode getContentMode() { | ||||
return contentMode; | return contentMode; | ||||
} | } | ||||
/** | |||||
* Sets the tooltip title's content mode. | |||||
* | |||||
* @param contentMode | |||||
* the content mode to set | |||||
*/ | |||||
public void setContentMode(ContentMode contentMode) { | public void setContentMode(ContentMode contentMode) { | ||||
this.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. | * Checks is a message has been defined for the tooltip. | ||||
* | * | ||||
|| (errorMessageHtml != null && !errorMessageHtml.isEmpty()); | || (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) { | public boolean equals(TooltipInfo other) { | ||||
return (other != null && SharedUtil.equals(other.title, title) | return (other != null && SharedUtil.equals(other.title, title) | ||||
&& SharedUtil.equals(other.errorMessageHtml, errorMessageHtml) | && SharedUtil.equals(other.errorMessageHtml, errorMessageHtml) | ||||
&& SharedUtil.equals(other.errorLevel, errorLevel) | |||||
&& other.identifier == identifier); | && other.identifier == identifier); | ||||
} | } | ||||
} | } |
import com.google.gwt.user.client.Event; | import com.google.gwt.user.client.Event; | ||||
import com.google.gwt.user.client.ui.HTML; | import com.google.gwt.user.client.ui.HTML; | ||||
import com.google.gwt.user.client.ui.HasHTML; | import com.google.gwt.user.client.ui.HasHTML; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.HasErrorIndicator; | import com.vaadin.client.ui.HasErrorIndicator; | ||||
import com.vaadin.client.ui.HasErrorIndicatorElement; | |||||
import com.vaadin.client.ui.HasRequiredIndicator; | import com.vaadin.client.ui.HasRequiredIndicator; | ||||
import com.vaadin.client.ui.Icon; | import com.vaadin.client.ui.Icon; | ||||
import com.vaadin.client.ui.ImageIcon; | import com.vaadin.client.ui.ImageIcon; | ||||
import com.vaadin.shared.AbstractComponentState; | import com.vaadin.shared.AbstractComponentState; | ||||
import com.vaadin.shared.ComponentConstants; | import com.vaadin.shared.ComponentConstants; | ||||
import com.vaadin.shared.ui.ComponentStateUtil; | 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"; | public static final String CLASSNAME = "v-caption"; | ||||
AriaHelper.handleInputInvalid(owner.getWidget(), showError); | AriaHelper.handleInputInvalid(owner.getWidget(), showError); | ||||
if (showError) { | if (showError) { | ||||
if (errorIndicatorElement == null) { | |||||
errorIndicatorElement = DOM.createDiv(); | |||||
DOM.setInnerHTML(errorIndicatorElement, " "); | |||||
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); | return (wasPlacedAfterComponent != placedAfterComponent); | ||||
public boolean updateCaptionWithoutOwner(String caption, boolean disabled, | public boolean updateCaptionWithoutOwner(String caption, boolean disabled, | ||||
boolean hasDescription, boolean hasError, String iconURL, | boolean hasDescription, boolean hasError, String iconURL, | ||||
String iconAltText) { | 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; | boolean wasPlacedAfterComponent = placedAfterComponent; | ||||
// Caption is placed after component unless there is some part which | // Caption is placed after component unless there is some part which | ||||
} | } | ||||
if (hasError) { | if (hasError) { | ||||
if (errorIndicatorElement == null) { | |||||
errorIndicatorElement = DOM.createDiv(); | |||||
DOM.setInnerHTML(errorIndicatorElement, " "); | |||||
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); | return (wasPlacedAfterComponent != placedAfterComponent); | ||||
private static Logger getLogger() { | private static Logger getLogger() { | ||||
return Logger.getLogger(VCaption.class.getName()); | 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; | |||||
} | |||||
} | |||||
} | } |
import com.google.gwt.user.client.ui.HTML; | import com.google.gwt.user.client.ui.HTML; | ||||
import com.google.gwt.user.client.ui.Widget; | import com.google.gwt.user.client.ui.Widget; | ||||
import com.vaadin.client.ui.VOverlay; | import com.vaadin.client.ui.VOverlay; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
public class VErrorMessage extends FlowPanel { | public class VErrorMessage extends FlowPanel { | ||||
public static final String CLASSNAME = "v-errormessage"; | public static final String CLASSNAME = "v-errormessage"; | ||||
} | } | ||||
} | } | ||||
/** | |||||
* 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. | * Shows this error message next to given element. | ||||
* | * |
&& !info.getErrorMessage().isEmpty()) { | && !info.getErrorMessage().isEmpty()) { | ||||
em.setVisible(true); | em.setVisible(true); | ||||
em.updateMessage(info.getErrorMessage()); | em.updateMessage(info.getErrorMessage()); | ||||
em.updateErrorLevel(info.getErrorLevel()); | |||||
} else { | } else { | ||||
em.setVisible(false); | em.setVisible(false); | ||||
} | } | ||||
@Override | @Override | ||||
public void hide() { | public void hide() { | ||||
em.updateMessage(""); | em.updateMessage(""); | ||||
em.updateErrorLevel(null); | |||||
description.setHTML(""); | description.setHTML(""); | ||||
updatePosition(null, true); | updatePosition(null, true); |
import com.google.gwt.user.client.Window; | import com.google.gwt.user.client.Window; | ||||
import com.google.gwt.user.client.ui.RootPanel; | import com.google.gwt.user.client.ui.RootPanel; | ||||
import com.google.gwt.user.client.ui.Widget; | import com.google.gwt.user.client.ui.Widget; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.shared.util.SharedUtil; | import com.vaadin.shared.util.SharedUtil; | ||||
/** | /** | ||||
com.google.gwt.dom.client.Element el, String p) | com.google.gwt.dom.client.Element el, String p) | ||||
/*-{ | /*-{ | ||||
try { | try { | ||||
if (el.currentStyle) { | if (el.currentStyle) { | ||||
// IE | // IE | ||||
return el.currentStyle[p]; | return el.currentStyle[p]; | ||||
} catch (e) { | } catch (e) { | ||||
return ""; | return ""; | ||||
} | } | ||||
}-*/; | }-*/; | ||||
/** | /** | ||||
try { | try { | ||||
el.focus(); | el.focus(); | ||||
} catch (e) { | } catch (e) { | ||||
} | } | ||||
}-*/; | }-*/; | ||||
if ($wnd.document.activeElement) { | if ($wnd.document.activeElement) { | ||||
return $wnd.document.activeElement; | return $wnd.document.activeElement; | ||||
} | } | ||||
return null; | return null; | ||||
}-*/; | }-*/; | ||||
/*-{ | /*-{ | ||||
var top = elem.offsetTop; | var top = elem.offsetTop; | ||||
var height = elem.offsetHeight; | var height = elem.offsetHeight; | ||||
if (elem.parentNode != elem.offsetParent) { | if (elem.parentNode != elem.offsetParent) { | ||||
top -= elem.parentNode.offsetTop; | top -= elem.parentNode.offsetTop; | ||||
} | } | ||||
var cur = elem.parentNode; | var cur = elem.parentNode; | ||||
while (cur && (cur.nodeType == 1)) { | while (cur && (cur.nodeType == 1)) { | ||||
if (top < cur.scrollTop) { | if (top < cur.scrollTop) { | ||||
if (top + height > cur.scrollTop + cur.clientHeight) { | if (top + height > cur.scrollTop + cur.clientHeight) { | ||||
cur.scrollTop = (top + height) - cur.clientHeight; | cur.scrollTop = (top + height) - cur.clientHeight; | ||||
} | } | ||||
var offsetTop = cur.offsetTop; | var offsetTop = cur.offsetTop; | ||||
if (cur.parentNode != cur.offsetParent) { | if (cur.parentNode != cur.offsetParent) { | ||||
offsetTop -= cur.parentNode.offsetTop; | offsetTop -= cur.parentNode.offsetTop; | ||||
} | } | ||||
top += offsetTop - cur.scrollTop; | top += offsetTop - cur.scrollTop; | ||||
cur = cur.parentNode; | cur = cur.parentNode; | ||||
} | } | ||||
} | } | ||||
var heightWithoutBorder = cloneElement.offsetHeight; | var heightWithoutBorder = cloneElement.offsetHeight; | ||||
parentElement.removeChild(cloneElement); | parentElement.removeChild(cloneElement); | ||||
return heightWithBorder - heightWithoutBorder; | return heightWithBorder - heightWithoutBorder; | ||||
} | } | ||||
}-*/; | }-*/; | ||||
int relativeTop = element.getAbsoluteTop() - Window.getScrollTop(); | int relativeTop = element.getAbsoluteTop() - Window.getScrollTop(); | ||||
return WidgetUtil.getTouchOrMouseClientY(event) - relativeTop; | 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; | |||||
} | |||||
} | |||||
} | } |
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.VConsole; | import com.vaadin.client.VConsole; | ||||
import com.vaadin.client.WidgetUtil; | import com.vaadin.client.WidgetUtil; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.annotations.OnStateChange; | import com.vaadin.client.annotations.OnStateChange; | ||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.extensions.DragSourceExtensionConnector; | import com.vaadin.client.extensions.DragSourceExtensionConnector; | ||||
Profiler.leave("AbstractComponentConnector.onStateChanged"); | 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 | @Override | ||||
public void setWidgetEnabled(boolean widgetEnabled) { | public void setWidgetEnabled(boolean widgetEnabled) { | ||||
// add or remove v-disabled style name from the widget | // add or remove v-disabled style name from the widget | ||||
@Override | @Override | ||||
public TooltipInfo getTooltipInfo(Element element) { | public TooltipInfo getTooltipInfo(Element element) { | ||||
return new TooltipInfo(getState().description, | return new TooltipInfo(getState().description, | ||||
getState().descriptionContentMode, getState().errorMessage); | |||||
getState().descriptionContentMode, getState().errorMessage, | |||||
null, getState().errorLevel); | |||||
} | } | ||||
@Override | @Override |
/* | |||||
* 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); | |||||
} |
caption.updateCaptionWithoutOwner(tabState.caption, | caption.updateCaptionWithoutOwner(tabState.caption, | ||||
!tabState.enabled, hasAttribute(tabState.description), | !tabState.enabled, hasAttribute(tabState.description), | ||||
hasAttribute(tabState.componentError), | hasAttribute(tabState.componentError), | ||||
tabState.componentErrorLevel, | |||||
connector.getResourceUrl( | connector.getResourceUrl( | ||||
ComponentConstants.ICON_RESOURCE + tabState.key)); | |||||
ComponentConstants.ICON_RESOURCE + tabState.key), | |||||
tabState.iconAltText); | |||||
} | } | ||||
private boolean hasAttribute(String string) { | private boolean hasAttribute(String string) { |
import com.vaadin.client.BrowserInfo; | import com.vaadin.client.BrowserInfo; | ||||
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.WidgetUtil; | 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"; | public static final String CLASSNAME = "v-button"; | ||||
private static final String CLASSNAME_PRESSED = "v-pressed"; | private static final String CLASSNAME_PRESSED = "v-pressed"; | ||||
public final Element wrapper = DOM.createSpan(); | public final Element wrapper = DOM.createSpan(); | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** 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. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public final Element captionElement = DOM.createSpan(); | public final Element captionElement = DOM.createSpan(); | ||||
return ret; | 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; | |||||
} | |||||
} | |||||
} | } |
import com.vaadin.client.BrowserInfo; | import com.vaadin.client.BrowserInfo; | ||||
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.VTooltip; | import com.vaadin.client.VTooltip; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.ui.aria.AriaHelper; | import com.vaadin.client.ui.aria.AriaHelper; | ||||
import com.vaadin.client.ui.aria.HandlesAriaInvalid; | import com.vaadin.client.ui.aria.HandlesAriaInvalid; | ||||
import com.vaadin.client.ui.aria.HandlesAriaRequired; | import com.vaadin.client.ui.aria.HandlesAriaRequired; | ||||
public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox | 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"; | public static final String CLASSNAME = "v-checkbox"; | ||||
public ApplicationConnection client; | public ApplicationConnection client; | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** 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. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public Icon icon; | public Icon icon; | ||||
public void setAriaInvalid(boolean invalid) { | public void setAriaInvalid(boolean invalid) { | ||||
AriaHelper.handleInputInvalid(getCheckBoxElement(), 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; | |||||
} | |||||
} | |||||
} | } |
import com.vaadin.client.Focusable; | import com.vaadin.client.Focusable; | ||||
import com.vaadin.client.StyleConstants; | import com.vaadin.client.StyleConstants; | ||||
import com.vaadin.client.VTooltip; | import com.vaadin.client.VTooltip; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.ui.aria.AriaHelper; | import com.vaadin.client.ui.aria.AriaHelper; | ||||
import com.vaadin.shared.AbstractComponentState; | import com.vaadin.shared.AbstractComponentState; | ||||
import com.vaadin.shared.ComponentConstants; | import com.vaadin.shared.ComponentConstants; | ||||
import com.vaadin.shared.ui.ComponentStateUtil; | import com.vaadin.shared.ui.ComponentStateUtil; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.shared.ui.MarginInfo; | import com.vaadin.shared.ui.MarginInfo; | ||||
/** | /** | ||||
} | } | ||||
public void updateError(Widget widget, String errorMessage, | public void updateError(Widget widget, String errorMessage, | ||||
boolean hideErrors) { | |||||
ErrorLevel errorLevel, boolean hideErrors) { | |||||
final ErrorFlag e = widgetToError.get(widget); | final ErrorFlag e = widgetToError.get(widget); | ||||
if (e != null) { | if (e != null) { | ||||
e.updateError(errorMessage, hideErrors); | |||||
e.updateError(errorMessage, errorLevel, hideErrors); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** 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 | private static final String CLASSNAME = VFormLayout.CLASSNAME | ||||
+ "-error-indicator"; | + "-error-indicator"; | ||||
Element errorIndicatorElement; | Element errorIndicatorElement; | ||||
return owner; | return owner; | ||||
} | } | ||||
public void updateError(String errorMessage, boolean hideErrors) { | |||||
public void updateError(String errorMessage, ErrorLevel errorLevel, | |||||
boolean hideErrors) { | |||||
boolean showError = null != errorMessage; | boolean showError = null != errorMessage; | ||||
if (hideErrors) { | if (hideErrors) { | ||||
showError = false; | showError = false; | ||||
AriaHelper.handleInputInvalid(owner.getWidget(), showError); | AriaHelper.handleInputInvalid(owner.getWidget(), showError); | ||||
if (showError) { | if (showError) { | ||||
if (errorIndicatorElement == null) { | |||||
errorIndicatorElement = DOM.createDiv(); | |||||
DOM.setInnerHTML(errorIndicatorElement, " "); | |||||
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) { | } else if (errorIndicatorElement != null) { | ||||
DOM.removeChild(getElement(), errorIndicatorElement); | |||||
getElement().removeChild(errorIndicatorElement); | |||||
errorIndicatorElement = null; | errorIndicatorElement = null; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } |
import com.google.gwt.user.client.ui.HTML; | import com.google.gwt.user.client.ui.HTML; | ||||
import com.google.gwt.user.client.ui.HasEnabled; | import com.google.gwt.user.client.ui.HasEnabled; | ||||
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.shared.ui.BorderStyle; | 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"; | public static final String CLASSNAME = "v-link"; | ||||
public int targetHeight; | public int targetHeight; | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** 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. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public final Element anchor = DOM.createAnchor(); | public final Element anchor = DOM.createAnchor(); | ||||
this.enabled = enabled; | 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; | |||||
} | |||||
} | |||||
} | } |
import com.vaadin.client.MouseEventDetailsBuilder; | import com.vaadin.client.MouseEventDetailsBuilder; | ||||
import com.vaadin.client.StyleConstants; | import com.vaadin.client.StyleConstants; | ||||
import com.vaadin.client.Util; | import com.vaadin.client.Util; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.shared.MouseEventDetails; | import com.vaadin.shared.MouseEventDetails; | ||||
import com.vaadin.shared.ui.button.ButtonServerRpc; | 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"; | public static final String CLASSNAME = "v-nativebutton"; | ||||
public ButtonServerRpc buttonRpcProxy; | public ButtonServerRpc buttonRpcProxy; | ||||
/** For internal use only. May be removed or replaced in the future. */ | /** 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. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public final Element captionElement = DOM.createSpan(); | public final Element captionElement = DOM.createSpan(); | ||||
clickPending = false; | 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; | |||||
} | |||||
} | |||||
} | } |
import com.google.gwt.user.client.ui.SimplePanel; | import com.google.gwt.user.client.ui.SimplePanel; | ||||
import com.vaadin.client.ApplicationConnection; | import com.vaadin.client.ApplicationConnection; | ||||
import com.vaadin.client.Focusable; | import com.vaadin.client.Focusable; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; | import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; | ||||
import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; | 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"; | public static final String CLASSNAME = "v-panel"; | ||||
DOM.setInnerHTML(captionText, text); | DOM.setInnerHTML(captionText, text); | ||||
} | } | ||||
/** 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. */ | /** For internal use only. May be removed or replaced in the future. */ | ||||
public void setIconUri(String iconUri, ApplicationConnection client) { | public void setIconUri(String iconUri, ApplicationConnection client) { | ||||
if (icon != null) { | if (icon != null) { | ||||
} | } | ||||
touchScrollHandler.addElement(contentNode); | 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; | |||||
} | |||||
} | |||||
} | } |
|| tabState.componentError != null) { | || tabState.componentError != null) { | ||||
setTooltipInfo(new TooltipInfo(tabState.description, | setTooltipInfo(new TooltipInfo(tabState.description, | ||||
tabState.descriptionContentMode, | tabState.descriptionContentMode, | ||||
tabState.componentError, this)); | |||||
tabState.componentError, this, | |||||
tabState.componentErrorLevel)); | |||||
} else { | } else { | ||||
setTooltipInfo(null); | setTooltipInfo(null); | ||||
} | } | ||||
boolean ret = updateCaptionWithoutOwner(captionString, | boolean ret = updateCaptionWithoutOwner(captionString, | ||||
!tabState.enabled, hasAttribute(tabState.description), | !tabState.enabled, hasAttribute(tabState.description), | ||||
hasAttribute(tabState.componentError), | hasAttribute(tabState.componentError), | ||||
tabState.componentErrorLevel, | |||||
tab.getTabsheet().connector.getResourceUrl( | tab.getTabsheet().connector.getResourceUrl( | ||||
ComponentConstants.ICON_RESOURCE + tabState.key), | ComponentConstants.ICON_RESOURCE + tabState.key), | ||||
tabState.iconAltText); | tabState.iconAltText); |
import com.google.gwt.event.dom.client.ClickHandler; | import com.google.gwt.event.dom.client.ClickHandler; | ||||
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.vaadin.client.MouseEventDetailsBuilder; | import com.vaadin.client.MouseEventDetailsBuilder; | ||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.annotations.OnStateChange; | import com.vaadin.client.annotations.OnStateChange; | ||||
import com.vaadin.client.ui.AbstractComponentConnector; | import com.vaadin.client.ui.AbstractComponentConnector; | ||||
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | ||||
ConnectorFocusAndBlurHandler.addHandlers(this); | 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") | @OnStateChange("resources") | ||||
void onResourceChange() { | void onResourceChange() { | ||||
if (getWidget().icon != null) { | if (getWidget().icon != null) { |
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.google.gwt.user.client.Event; | import com.google.gwt.user.client.Event; | ||||
import com.vaadin.client.MouseEventDetailsBuilder; | import com.vaadin.client.MouseEventDetailsBuilder; | ||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.VTooltip; | import com.vaadin.client.VTooltip; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.annotations.OnStateChange; | import com.vaadin.client.annotations.OnStateChange; | ||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.AbstractFieldConnector; | import com.vaadin.client.ui.AbstractFieldConnector; | ||||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | public void onStateChanged(StateChangeEvent stateChangeEvent) { | ||||
super.onStateChanged(stateChangeEvent); | super.onStateChanged(stateChangeEvent); | ||||
if (null != getState().errorMessage) { | |||||
getWidget().setAriaInvalid(true); | |||||
if (getWidget().errorIndicatorElement == null) { | |||||
getWidget().errorIndicatorElement = DOM.createSpan(); | |||||
getWidget().errorIndicatorElement.setInnerHTML(" "); | |||||
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()); | getWidget().setAriaRequired(isRequiredIndicatorVisible()); | ||||
if (isReadOnly()) { | if (isReadOnly()) { |
} | } | ||||
getWidget().table.updateError(component.getWidget(), | getWidget().table.updateError(component.getWidget(), | ||||
component.getState().errorMessage, hideErrors); | |||||
component.getState().errorMessage, | |||||
component.getState().errorLevel, hideErrors); | |||||
} | } | ||||
@Override | @Override |
import com.google.gwt.dom.client.Style.Display; | import com.google.gwt.dom.client.Style.Display; | ||||
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.AbstractComponentConnector; | import com.vaadin.client.ui.AbstractComponentConnector; | ||||
import com.vaadin.client.ui.Icon; | import com.vaadin.client.ui.Icon; | ||||
// Set link caption | // Set link caption | ||||
VCaption.setCaptionText(getWidget().captionElement, getState()); | 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) { | if (getWidget().icon != null) { | ||||
getWidget().anchor.removeChild(getWidget().icon.getElement()); | getWidget().anchor.removeChild(getWidget().icon.getElement()); | ||||
getWidget().icon = null; | getWidget().icon = null; |
package com.vaadin.client.ui.nativebutton; | package com.vaadin.client.ui.nativebutton; | ||||
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.AbstractComponentConnector; | import com.vaadin.client.ui.AbstractComponentConnector; | ||||
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | ||||
// Set text | // Set text | ||||
VCaption.setCaptionText(getWidget(), getState()); | 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) { | if (getWidget().icon != null) { | ||||
getWidget().getElement().removeChild(getWidget().icon.getElement()); | getWidget().getElement().removeChild(getWidget().icon.getElement()); | ||||
getWidget().icon = null; | getWidget().icon = null; |
slot.setCaptionResizeListener(null); | 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.handleInputRequired(child.getWidget(), required); | ||||
AriaHelper.handleInputInvalid(child.getWidget(), showError); | AriaHelper.handleInputInvalid(child.getWidget(), showError); |
import com.vaadin.client.LayoutManager; | import com.vaadin.client.LayoutManager; | ||||
import com.vaadin.client.StyleConstants; | import com.vaadin.client.StyleConstants; | ||||
import com.vaadin.client.WidgetUtil; | import com.vaadin.client.WidgetUtil; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.ui.FontIcon; | import com.vaadin.client.ui.FontIcon; | ||||
import com.vaadin.client.ui.HasErrorIndicatorElement; | |||||
import com.vaadin.client.ui.Icon; | import com.vaadin.client.ui.Icon; | ||||
import com.vaadin.client.ui.ImageIcon; | import com.vaadin.client.ui.ImageIcon; | ||||
import com.vaadin.client.ui.layout.ElementResizeListener; | import com.vaadin.client.ui.layout.ElementResizeListener; | ||||
import com.vaadin.shared.ui.AlignmentInfo; | import com.vaadin.shared.ui.AlignmentInfo; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Represents a slot which contains the actual widget in the layout. | * 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-"; | private static final String ALIGN_CLASS_PREFIX = "v-align-"; | ||||
public void setCaption(String captionText, Icon icon, List<String> styles, | public void setCaption(String captionText, Icon icon, List<String> styles, | ||||
String error, boolean showError, boolean required, boolean enabled, | String error, boolean showError, boolean required, boolean enabled, | ||||
boolean captionAsHtml) { | 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 | // TODO place for optimization: check if any of these have changed | ||||
// since last time, and only run those changes | // since last time, and only run those changes | ||||
// Error | // Error | ||||
if (error != null && showError) { | 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) { | if (caption != null) { | ||||
return hasRelativeWidth(); | 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; | |||||
} | |||||
} | |||||
} | } |
getWidget().setIconUri(null, client); | getWidget().setIconUri(null, client); | ||||
} | } | ||||
getWidget().setErrorIndicatorVisible(isErrorIndicatorVisible()); | |||||
// We may have actions attached to this panel | // We may have actions attached to this panel | ||||
if (uidl.getChildCount() > 0) { | if (uidl.getChildCount() > 0) { | ||||
final int cnt = uidl.getChildCount(); | final int cnt = uidl.getChildCount(); |
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.google.gwt.user.client.Event; | import com.google.gwt.user.client.Event; | ||||
import com.vaadin.client.MouseEventDetailsBuilder; | import com.vaadin.client.MouseEventDetailsBuilder; | ||||
import com.vaadin.client.StyleConstants; | |||||
import com.vaadin.client.VCaption; | import com.vaadin.client.VCaption; | ||||
import com.vaadin.client.VTooltip; | import com.vaadin.client.VTooltip; | ||||
import com.vaadin.client.WidgetUtil.ErrorUtil; | |||||
import com.vaadin.client.annotations.OnStateChange; | import com.vaadin.client.annotations.OnStateChange; | ||||
import com.vaadin.client.communication.StateChangeEvent; | import com.vaadin.client.communication.StateChangeEvent; | ||||
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; | ||||
getWidget().errorIndicatorElement = DOM.createSpan(); | getWidget().errorIndicatorElement = DOM.createSpan(); | ||||
getWidget().errorIndicatorElement.setInnerHTML(" "); | getWidget().errorIndicatorElement.setInnerHTML(" "); | ||||
DOM.setElementProperty(getWidget().errorIndicatorElement, | DOM.setElementProperty(getWidget().errorIndicatorElement, | ||||
"className", "v-errorindicator"); | |||||
"className", StyleConstants.STYLE_NAME_ERROR_INDICATOR); | |||||
DOM.appendChild(getWidget().getElement(), | DOM.appendChild(getWidget().getElement(), | ||||
getWidget().errorIndicatorElement); | getWidget().errorIndicatorElement); | ||||
DOM.sinkEvents(getWidget().errorIndicatorElement, | DOM.sinkEvents(getWidget().errorIndicatorElement, | ||||
} else { | } else { | ||||
getWidget().errorIndicatorElement.getStyle().clearDisplay(); | getWidget().errorIndicatorElement.getStyle().clearDisplay(); | ||||
} | } | ||||
ErrorUtil.setErrorLevelStyle(getWidget().errorIndicatorElement, | |||||
StyleConstants.STYLE_NAME_ERROR_INDICATOR, | |||||
getState().errorLevel); | |||||
} else if (getWidget().errorIndicatorElement != null) { | } else if (getWidget().errorIndicatorElement != null) { | ||||
getWidget().errorIndicatorElement.getStyle() | getWidget().errorIndicatorElement.getStyle() | ||||
.setDisplay(Display.NONE); | .setDisplay(Display.NONE); |
if (null != getState().errorMessage) { | if (null != getState().errorMessage) { | ||||
getWidget().errorMessage.updateMessage(getState().errorMessage); | getWidget().errorMessage.updateMessage(getState().errorMessage); | ||||
getWidget().errorMessage.updateErrorLevel(getState().errorLevel); | |||||
getWidget().errorMessage.setVisible(true); | getWidget().errorMessage.setVisible(true); | ||||
} else { | } else { | ||||
getWidget().errorMessage.setVisible(false); | getWidget().errorMessage.setVisible(false); |
import com.vaadin.data.Binder; | import com.vaadin.data.Binder; | ||||
import com.vaadin.server.AbstractErrorMessage; | import com.vaadin.server.AbstractErrorMessage; | ||||
import com.vaadin.server.ErrorMessage; | import com.vaadin.server.ErrorMessage; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.ErrorMessageProducer; | import com.vaadin.server.ErrorMessageProducer; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.v7.data.Validator.InvalidValueException; | import com.vaadin.v7.data.Validator.InvalidValueException; | ||||
/** | /** |
import com.vaadin.server.AbstractErrorMessage; | import com.vaadin.server.AbstractErrorMessage; | ||||
import com.vaadin.server.AbstractErrorMessage.ContentMode; | import com.vaadin.server.AbstractErrorMessage.ContentMode; | ||||
import com.vaadin.server.ErrorMessage; | import com.vaadin.server.ErrorMessage; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.ErrorMessageProducer; | import com.vaadin.server.ErrorMessageProducer; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.server.VaadinServlet; | import com.vaadin.server.VaadinServlet; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Interface that implements a method for validating if an {@link Object} is | * Interface that implements a method for validating if an {@link Object} is |
import com.vaadin.shared.MouseEventDetails; | import com.vaadin.shared.MouseEventDetails; | ||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
import com.vaadin.shared.data.sort.SortDirection; | import com.vaadin.shared.data.sort.SortDirection; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.shared.util.SharedUtil; | import com.vaadin.shared.util.SharedUtil; | ||||
import com.vaadin.ui.AbstractComponent; | import com.vaadin.ui.AbstractComponent; | ||||
import com.vaadin.ui.Component; | import com.vaadin.ui.Component; |
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.ExternalResource; | import com.vaadin.server.ExternalResource; | ||||
import com.vaadin.server.FileResource; | import com.vaadin.server.FileResource; | ||||
import com.vaadin.server.Responsive; | import com.vaadin.server.Responsive; | ||||
import com.vaadin.server.ThemeResource; | import com.vaadin.server.ThemeResource; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.tests.design.DeclarativeTestBase; | import com.vaadin.tests.design.DeclarativeTestBase; | ||||
import com.vaadin.ui.AbstractComponent; | import com.vaadin.ui.AbstractComponent; | ||||
import com.vaadin.ui.Label; | import com.vaadin.ui.Label; |
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Base class for component error messages. | * Base class for component error messages. | ||||
* | * |
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Class for combining multiple error messages together. | * Class for combining multiple error messages together. | ||||
* | * | ||||
*/ | */ | ||||
public CompositeErrorMessage(ErrorMessage... errorMessages) { | public CompositeErrorMessage(ErrorMessage... errorMessages) { | ||||
super(null); | super(null); | ||||
setErrorLevel(ErrorLevel.INFORMATION); | |||||
setErrorLevel(ErrorLevel.INFO); | |||||
for (ErrorMessage errorMessage : errorMessages) { | for (ErrorMessage errorMessage : errorMessages) { | ||||
addErrorMessage(errorMessage); | addErrorMessage(errorMessage); | ||||
public CompositeErrorMessage( | public CompositeErrorMessage( | ||||
Collection<? extends ErrorMessage> errorMessages) { | Collection<? extends ErrorMessage> errorMessages) { | ||||
super(null); | super(null); | ||||
setErrorLevel(ErrorLevel.INFORMATION); | |||||
setErrorLevel(ErrorLevel.INFO); | |||||
for (ErrorMessage errorMessage : errorMessages) { | for (ErrorMessage errorMessage : errorMessages) { | ||||
addErrorMessage(errorMessage); | addErrorMessage(errorMessage); |
import java.io.Serializable; | import java.io.Serializable; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Interface for rendering error messages to terminal. All the visible errors | * Interface for rendering error messages to terminal. All the visible errors | ||||
* shown to user must implement this interface. | * shown to user must implement this interface. | ||||
*/ | */ | ||||
public interface ErrorMessage extends 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 | @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 | * @deprecated As of 7.0, use {@link ErrorLevel#CRITICAL} instead | ||||
public static final ErrorLevel WARNING = ErrorLevel.WARNING; | 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 | @Deprecated | ||||
public static final ErrorLevel INFORMATION = ErrorLevel.INFORMATION; | |||||
public static final ErrorLevel INFORMATION = ErrorLevel.INFO; | |||||
/** | /** | ||||
* Gets the errors level. | * Gets the errors level. |
package com.vaadin.server; | package com.vaadin.server; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* <code>SystemError</code> is an error message for a problem caused by error in | * <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 | * system, not the user application code. The system error can contain technical | ||||
*/ | */ | ||||
public SystemError(String message) { | public SystemError(String message) { | ||||
super(message); | super(message); | ||||
setErrorLevel(ErrorLevel.SYSTEMERROR); | |||||
setErrorLevel(ErrorLevel.SYSTEM); | |||||
setMode(ContentMode.HTML); | setMode(ContentMode.HTML); | ||||
setMessage(getHtmlMessage()); | setMessage(getHtmlMessage()); | ||||
} | } |
package com.vaadin.server; | package com.vaadin.server; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* <code>UserError</code> is a controlled error occurred in application. User | * <code>UserError</code> is a controlled error occurred in application. User | ||||
* errors are occur in normal usage of the application and guide the user. | * errors are occur in normal usage of the application and guide the user. |
import com.vaadin.server.ClientConnector; | import com.vaadin.server.ClientConnector; | ||||
import com.vaadin.server.ComponentSizeValidator; | import com.vaadin.server.ComponentSizeValidator; | ||||
import com.vaadin.server.ErrorMessage; | import com.vaadin.server.ErrorMessage; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.Extension; | import com.vaadin.server.Extension; | ||||
import com.vaadin.server.Resource; | import com.vaadin.server.Resource; | ||||
import com.vaadin.server.Responsive; | import com.vaadin.server.Responsive; | ||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
import com.vaadin.shared.ui.ComponentStateUtil; | import com.vaadin.shared.ui.ComponentStateUtil; | ||||
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.shared.util.SharedUtil; | import com.vaadin.shared.util.SharedUtil; | ||||
import com.vaadin.ui.declarative.DesignAttributeHandler; | import com.vaadin.ui.declarative.DesignAttributeHandler; | ||||
import com.vaadin.ui.declarative.DesignContext; | import com.vaadin.ui.declarative.DesignContext; | ||||
ErrorMessage error = getErrorMessage(); | ErrorMessage error = getErrorMessage(); | ||||
if (null != error) { | if (null != error) { | ||||
getState().errorMessage = error.getFormattedHtmlMessage(); | getState().errorMessage = error.getFormattedHtmlMessage(); | ||||
getState().errorLevel = error.getErrorLevel(); | |||||
} else { | } else { | ||||
getState().errorMessage = null; | getState().errorMessage = null; | ||||
getState().errorLevel = null; | |||||
} | } | ||||
} | } | ||||
public void setComponentError(ErrorMessage componentError) { | public void setComponentError(ErrorMessage componentError) { | ||||
this.componentError = 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(); | markAsDirty(); | ||||
} | } |
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.server.ExternalResource; | import com.vaadin.server.ExternalResource; | ||||
import com.vaadin.server.FileResource; | import com.vaadin.server.FileResource; | ||||
import com.vaadin.server.Responsive; | import com.vaadin.server.Responsive; | ||||
import com.vaadin.server.ThemeResource; | import com.vaadin.server.ThemeResource; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.tests.design.DeclarativeTestBase; | import com.vaadin.tests.design.DeclarativeTestBase; | ||||
import com.vaadin.ui.AbstractComponent; | import com.vaadin.ui.AbstractComponent; | ||||
import com.vaadin.ui.Button; | import com.vaadin.ui.Button; |
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.ExternalResource; | import com.vaadin.server.ExternalResource; | ||||
import com.vaadin.server.FileResource; | import com.vaadin.server.FileResource; | ||||
import com.vaadin.server.ThemeResource; | import com.vaadin.server.ThemeResource; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.tests.design.DeclarativeTestBase; | import com.vaadin.tests.design.DeclarativeTestBase; | ||||
import com.vaadin.ui.AbstractComponent; | import com.vaadin.ui.AbstractComponent; | ||||
import com.vaadin.ui.declarative.DesignContext; | import com.vaadin.ui.declarative.DesignContext; |
import com.vaadin.shared.annotations.NoLayout; | import com.vaadin.shared.annotations.NoLayout; | ||||
import com.vaadin.shared.communication.SharedState; | import com.vaadin.shared.communication.SharedState; | ||||
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Default shared state implementation for AbstractComponent. | * Default shared state implementation for AbstractComponent. | ||||
public String id = null; | public String id = null; | ||||
public String primaryStyleName = 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; | public String errorMessage = null; | ||||
/** | |||||
* Level of error | |||||
* | |||||
* @since 8.2 | |||||
*/ | |||||
public ErrorLevel errorLevel = null; | |||||
public boolean captionAsHtml = false; | public boolean captionAsHtml = false; | ||||
} | } |
/* | |||||
* 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(); | |||||
} | |||||
} |
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
/** | /** | ||||
* Shared state of a single tab in a Tabsheet or an Accordion. | * Shared state of a single tab in a Tabsheet or an Accordion. | ||||
* | * | ||||
public String styleName; | public String styleName; | ||||
public String key; | public String key; | ||||
public String componentError; | public String componentError; | ||||
/** | |||||
* Represents the level of error on a tab. | |||||
* | |||||
* @since 8.2 | |||||
*/ | |||||
public ErrorLevel componentErrorLevel; | |||||
public String id; | public String id; | ||||
public String iconAltText; | public String iconAltText; | ||||
Subproject commit 3a4a26065d36ac5fb706c159f1dd757fb52bf8eb | |||||
Subproject commit 37f67cd836df7d34469f55298bb167696338f2a5 |
} | } | ||||
} | } | ||||
.#{$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 { | .#{$primary-stylename}-suggestpopup { | ||||
@include valo-combobox-popup-style; | @include valo-combobox-popup-style; | ||||
} | } |
} | } | ||||
} | } | ||||
.#{$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 | // Different widths for different resolutions | ||||
.#{$primary-stylename}-full { | .#{$primary-stylename}-full { | ||||
width: round($v-font-size * 15); | width: round($v-font-size * 15); |
@include valo-textfield-error-style; | @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 { | @if $include-additional-styles { | ||||
.#{$primary-stylename}-borderless { | .#{$primary-stylename}-borderless { | ||||
* | * | ||||
* @group textfield | * @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; | background: $bg; | ||||
color: valo-font-color($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). | * 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). |
} | } | ||||
} | } | ||||
.#{$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; | |||||
} | |||||
} | |||||
} | } | ||||
@include valo-error-indicator-style; | @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 { | .v-required-field-indicator { | ||||
color: $v-required-field-indicator-color; | color: $v-required-field-indicator-color; | ||||
padding: 0 .2em; | padding: 0 .2em; | ||||
* | * | ||||
* @requires {mixin} valo-error-indicator-icon-style by default | * @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; | font-weight: 600; | ||||
width: ceil($v-unit-size/2); | width: ceil($v-unit-size/2); | ||||
text-align: center; | text-align: center; |
*/ | */ | ||||
$v-tooltip-error-message-font-color: $v-error-indicator-color !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. | * The corner radius for tooltips. | ||||
* | * | ||||
} | } | ||||
} | } | ||||
.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 { | .v-tooltip-text { | ||||
max-height: 10em; | max-height: 10em; | ||||
overflow: auto; | overflow: auto; |
*/ | */ | ||||
$v-selection-color: $v-focus-color !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 | * Color of the component error indicator and other error indications, such as the | ||||
* error style notification. | * error style notification. | ||||
* @group color | * @group color | ||||
* @type 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. | * Color of the required indicator in field components. |
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()); | |||||
} | |||||
} |
import com.vaadin.navigator.View; | import com.vaadin.navigator.View; | ||||
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; | import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; | ||||
import com.vaadin.server.AbstractErrorMessage; | import com.vaadin.server.AbstractErrorMessage; | ||||
import com.vaadin.server.ErrorMessage.ErrorLevel; | |||||
import com.vaadin.server.Page; | import com.vaadin.server.Page; | ||||
import com.vaadin.server.UserError; | import com.vaadin.server.UserError; | ||||
import com.vaadin.shared.Position; | import com.vaadin.shared.Position; | ||||
import com.vaadin.shared.ui.ContentMode; | import com.vaadin.shared.ui.ContentMode; | ||||
import com.vaadin.shared.ui.ErrorLevel; | |||||
import com.vaadin.ui.Alignment; | import com.vaadin.ui.Alignment; | ||||
import com.vaadin.ui.Button; | import com.vaadin.ui.Button; | ||||
import com.vaadin.ui.Button.ClickEvent; | import com.vaadin.ui.Button.ClickEvent; |
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; | |||||
} | |||||
} | |||||
} |
} | } | ||||
private WebElement getCurrentErrorMessage() { | 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) { | private void assertTooltip(String tooltip) { |