001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 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; 021 022import com.google.gwt.dom.client.Element; 023import com.google.gwt.editor.client.EditorError; 024import com.google.gwt.editor.client.HasEditorErrors; 025import com.google.gwt.editor.client.LeafValueEditor; 026import com.google.gwt.event.logical.shared.ValueChangeEvent; 027import com.google.gwt.event.logical.shared.ValueChangeHandler; 028import com.google.gwt.event.shared.HandlerRegistration; 029import com.google.gwt.user.client.ui.HasValue; 030import gwt.material.design.client.base.error.ErrorHandler; 031import gwt.material.design.client.base.error.ErrorHandlerType; 032import gwt.material.design.client.base.error.HasErrorHandler; 033import gwt.material.design.client.base.mixin.ErrorHandlerMixin; 034import gwt.material.design.client.base.mixin.ErrorMixin; 035import gwt.material.design.client.base.mixin.ValidatorMixin; 036import gwt.material.design.client.base.validator.BlankValidator; 037import gwt.material.design.client.base.validator.HasValidators; 038import gwt.material.design.client.base.validator.ValidationChangedEvent; 039import gwt.material.design.client.base.validator.Validator; 040 041import java.util.List; 042 043public abstract class AbstractValueWidget<V> extends MaterialWidget implements HasValue<V>, LeafValueEditor<V>, 044 HasEditorErrors<V>, HasErrorHandler, HasError, HasValidators<V> { 045 046 private boolean allowBlank = true; 047 private BlankValidator<V> blankValidator; 048 private ValidatorMixin<AbstractValueWidget<V>, V> validatorMixin; 049 private ErrorMixin<AbstractValueWidget, ?> errorMixin; 050 private ErrorHandlerMixin<V> errorHandlerMixin; 051 052 public AbstractValueWidget(Element element) { 053 super(element); 054 } 055 056 public AbstractValueWidget(Element element, String... initialClass) { 057 super(element, initialClass); 058 } 059 060 @Override 061 public void setValue(V value) { 062 setValue(value, false); 063 } 064 065 @Override 066 public void setValue(V value, boolean fireEvents) { 067 if (fireEvents) { 068 ValueChangeEvent.fire(this, value); 069 } 070 } 071 072 public void setValue(V value, boolean fireEvents, boolean reload) { 073 setValue(value, fireEvents); 074 075 if (this instanceof HasReload) { 076 if (reload) { 077 ((HasReload)this).reload(); 078 } 079 } 080 } 081 082 @Override 083 public void setError(String error) { 084 getErrorMixin().setError(error); 085 } 086 087 @Override 088 public void setSuccess(String success) { 089 getErrorMixin().setSuccess(success); 090 } 091 092 @Override 093 public void setHelperText(String helperText) { 094 getErrorMixin().setHelperText(helperText); 095 } 096 097 @Override 098 public void clearErrorOrSuccess() { 099 getErrorMixin().clearErrorOrSuccess(); 100 } 101 102 @Override 103 public void showErrors(List<EditorError> errors) { 104 getErrorHandlerMixin().showErrors(errors); 105 } 106 107 @Override 108 public ErrorHandler getErrorHandler() { 109 return getErrorHandlerMixin().getErrorHandler(); 110 } 111 112 @Override 113 public void setErrorHandler(ErrorHandler errorHandler) { 114 getErrorHandlerMixin().setErrorHandler(errorHandler); 115 } 116 117 @Override 118 public ErrorHandlerType getErrorHandlerType() { 119 return getErrorHandlerMixin().getErrorHandlerType(); 120 } 121 122 @Override 123 public void setErrorHandlerType(ErrorHandlerType errorHandlerType) { 124 getErrorHandlerMixin().setErrorHandlerType(errorHandlerType); 125 } 126 127 @Override 128 public void addValidator(Validator<V> validator) { 129 getValidatorMixin().addValidator(validator); 130 } 131 132 @Override 133 public boolean isValidateOnBlur() { 134 return getValidatorMixin().isValidateOnBlur(); 135 } 136 137 @Override 138 public boolean removeValidator(Validator<V> validator) { 139 return getValidatorMixin().removeValidator(validator); 140 } 141 142 @Override 143 public void reset() { 144 getValidatorMixin().reset(); 145 } 146 147 @Override 148 public void setValidateOnBlur(boolean validateOnBlur) { 149 getValidatorMixin().setValidateOnBlur(validateOnBlur); 150 setupBlurValidation(); 151 } 152 153 @Override 154 public void setValidators(@SuppressWarnings("unchecked") Validator<V>... validators) { 155 getValidatorMixin().setValidators(validators); 156 } 157 158 @Override 159 public boolean validate() { 160 return getValidatorMixin().validate(); 161 } 162 163 @Override 164 public boolean validate(boolean show) { 165 return getValidatorMixin().validate(show); 166 } 167 168 /** 169 * Enable or disable the default blank validator. 170 */ 171 public void setAllowBlank(boolean allowBlank) { 172 this.allowBlank = allowBlank; 173 174 // Setup the allow blank validation 175 if (!allowBlank) { 176 if (blankValidator == null) { 177 blankValidator = createBlankValidator(); 178 } 179 setupBlurValidation(); 180 addValidator(blankValidator); 181 } else { 182 removeValidator(blankValidator); 183 } 184 } 185 186 /** 187 * Will this widget allow blank values upon validation. 188 */ 189 public boolean isAllowBlank() { 190 return allowBlank; 191 } 192 193 /** 194 * Hook for custom blank validators. 195 * 196 * @return the blank validatorMixin 197 */ 198 protected BlankValidator<V> createBlankValidator() { 199 return new BlankValidator<>(); 200 } 201 202 protected void setupBlurValidation() { 203 final AbstractValueWidget inputWidget = getValidatorMixin().getInputWidget(); 204 if (!inputWidget.isAttached()) { 205 registerHandler(inputWidget.addAttachHandler(attachEvent -> registerHandler(inputWidget.addBlurHandler(blurEvent -> validate(isValidateOnBlur()))))); 206 } else { 207 registerHandler(inputWidget.addBlurHandler(blurEvent -> validate(isValidateOnBlur()))); 208 } 209 } 210 211 @Override 212 public HandlerRegistration addValidationChangedHandler(ValidationChangedEvent.ValidationChangedHandler handler) { 213 return getValidatorMixin().addValidationChangedHandler(handler); 214 } 215 216 @Override 217 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<V> handler) { 218 return addHandler(handler, ValueChangeEvent.getType()); 219 } 220 221 protected ValidatorMixin<AbstractValueWidget<V>, V> getValidatorMixin() { 222 if (validatorMixin == null) { 223 validatorMixin = new ValidatorMixin<>(this, getErrorHandler()); 224 } 225 return validatorMixin; 226 } 227 228 protected ErrorMixin<AbstractValueWidget, ?> getErrorMixin() { 229 if (errorMixin == null) { 230 errorMixin = new ErrorMixin<>(this); 231 } 232 return errorMixin; 233 } 234 235 protected ErrorHandlerMixin<V> getErrorHandlerMixin() { 236 if (errorHandlerMixin == null) { 237 errorHandlerMixin = new ErrorHandlerMixin<>(this); 238 } 239 return errorHandlerMixin; 240 } 241}