001/* 002 * #%L 003 * GwtBootstrap3 004 * %% 005 * Copyright (C) 2015 GwtBootstrap3 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.client.base.error; 021 022import com.google.gwt.editor.client.EditorError; 023import com.google.gwt.user.client.ui.HasWidgets; 024import com.google.gwt.user.client.ui.Widget; 025import gwt.material.design.client.base.HasError; 026import gwt.material.design.client.ui.MaterialHelpBlock; 027 028import java.util.List; 029 030/** 031 * This is the default {@link ErrorHandler} implementation. 032 * If there is a {@link MaterialHelpBlock} that is a child then error messages 033 * will be displayed in the {@link MaterialHelpBlock}. 034 * <p> 035 * Example: 036 * <p> 037 * <pre>{@code 038 * <m:MaterialRow> 039 * <m:TextBox m:id="username" ui:field="username" /> 040 * <m:MaterialHelpBlock iconType="EXCLAMATION" /> 041 * </m:MaterialRow> 042 * }</pre> 043 * 044 * @author Steven Jardine 045 * @author Ben Dol 046 */ 047public class DefaultErrorHandler implements ErrorHandler { 048 049 private boolean initialized = false; 050 051 private final Widget inputWidget; 052 053 private MaterialHelpBlock helpBlock = null; 054 055 /** 056 * Default error handler. 057 * 058 * @param widget the parent of this error handler. 059 */ 060 public DefaultErrorHandler(Widget widget) { 061 super(); 062 assert widget != null; 063 this.inputWidget = widget; 064 this.inputWidget.addAttachHandler(event -> { 065 if (event.isAttached()) { 066 init(); 067 } 068 }); 069 } 070 071 @Override 072 public void cleanup() { 073 } 074 075 @Override 076 public void clearErrors() { 077 if (inputWidget instanceof HasError) { 078 ((HasError) inputWidget).clearErrorOrSuccess(); 079 } 080 if (helpBlock != null) { 081 helpBlock.removeStyleName("field-error-label"); 082 helpBlock.removeStyleName("field-success-label"); 083 helpBlock.clear(); 084 } 085 } 086 087 /** 088 * Find the sibling {@link MaterialHelpBlock}. 089 * 090 * @param widget the {@link Widget} to search. 091 * @return the found {@link MaterialHelpBlock} of null if not found. 092 */ 093 protected MaterialHelpBlock findHelpBlock(Widget widget) { 094 if (widget != null) { 095 if (widget instanceof MaterialHelpBlock) { 096 return (MaterialHelpBlock) widget; 097 } 098 // Try and find the MaterialHelpBlock in the children of the given widget. 099 if (widget instanceof HasWidgets) { 100 for (Widget w : (HasWidgets) widget) { 101 if (w instanceof MaterialHelpBlock) { 102 return (MaterialHelpBlock) w; 103 } 104 } 105 } 106 // Try and find the MaterialHelpBlock in the parent of widget. 107 return findHelpBlock(widget.getParent()); 108 } 109 return null; 110 } 111 112 /** 113 * Initialize the instance. 114 */ 115 public void init() { 116 if (initialized) { 117 return; 118 } 119 Widget parent = inputWidget.getParent(); 120 while (parent != null && !parent.getClass().getName().equals("com.google.gwt.user.client.ui.Widget")) { 121 helpBlock = findHelpBlock(inputWidget); 122 if (helpBlock != null) { 123 break; 124 } else { 125 parent = parent.getParent(); 126 } 127 } 128 initialized = true; 129 } 130 131 @Override 132 public void showErrors(List<EditorError> errors) { 133 init(); 134 String errorMsg = ""; 135 for (int index = 0; index < errors.size(); index++) { 136 errorMsg = errors.get(0).getMessage(); 137 if (index + 1 < errors.size()) { 138 errorMsg += "; "; 139 } 140 } 141 142 if (inputWidget instanceof HasError) { 143 ((HasError) inputWidget).setError(errorMsg); 144 } 145 146 if (helpBlock != null) { 147 helpBlock.addStyleName("field-error-label"); 148 helpBlock.removeStyleName("field-success-label"); 149 helpBlock.setText(errorMsg); 150 } 151 } 152}