001package gwt.material.design.client.base.mixin; 002 003/* 004 * #%L 005 * GwtBootstrap3 006 * %% 007 * Copyright (C) 2013 - 2015 GwtBootstrap3 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import com.google.gwt.editor.client.Editor; 024import com.google.gwt.editor.client.EditorError; 025import com.google.gwt.event.dom.client.BlurEvent; 026import com.google.gwt.event.dom.client.BlurHandler; 027import com.google.gwt.event.logical.shared.ValueChangeEvent; 028import com.google.gwt.event.logical.shared.ValueChangeHandler; 029import com.google.gwt.event.shared.GwtEvent; 030import com.google.gwt.user.client.ui.HasValue; 031import com.google.gwt.user.client.ui.Widget; 032import com.google.web.bindery.event.shared.EventBus; 033import com.google.web.bindery.event.shared.HandlerRegistration; 034import com.google.web.bindery.event.shared.SimpleEventBus; 035import gwt.material.design.client.base.error.ErrorHandler; 036import gwt.material.design.client.base.validator.HasValidators; 037import gwt.material.design.client.base.validator.ValidationChangedEvent; 038import gwt.material.design.client.base.validator.ValidationChangedEvent.ValidationChangedHandler; 039import gwt.material.design.client.base.validator.Validator; 040import gwt.material.design.client.base.validator.ValidatorWrapper; 041 042import java.util.ArrayList; 043import java.util.List; 044import java.util.Set; 045import java.util.TreeSet; 046 047/** 048 * Default validator mixin. Contains all of the validation logic. 049 * 050 * @param <W> the generic type 051 * @param <V> the value type 052 * 053 * @author Steven Jardine 054 */ 055public class ValidatorMixin<W extends Widget & HasValue<V> & Editor<V>, V> implements HasValidators<V> { 056 057 protected ErrorHandler errorHandler; 058 059 private EventBus eventBus; 060 061 protected W inputWidget; 062 063 private Boolean valid = null; 064 065 private boolean validateOnBlur; 066 067 protected Set<ValidatorWrapper<V>> validators = new TreeSet<>(); 068 069 /** 070 * Instantiates a new abstract validator mixin. 071 * 072 * @param inputWidget the input widget 073 * @param errorHandler the error handler 074 */ 075 public ValidatorMixin(W inputWidget, ErrorHandler errorHandler) { 076 this.inputWidget = inputWidget; 077 this.errorHandler = errorHandler; 078 eventBus = new SimpleEventBus(); 079 080 setupValueChangeValidation(); 081 } 082 083 protected HandlerRegistration setupValueChangeValidation() { 084 return inputWidget.addHandler(new ValueChangeHandler<V>() { 085 @Override 086 public void onValueChange(ValueChangeEvent<V> event) { 087 validate(false); 088 } 089 }, ValueChangeEvent.getType()); 090 } 091 092 @Override 093 public HandlerRegistration addValidationChangedHandler(ValidationChangedHandler handler) { 094 return eventBus.addHandler(ValidationChangedEvent.getType(), handler); 095 } 096 097 @Override 098 public void addValidator(Validator<V> validator) { 099 validators.add(new ValidatorWrapper<>(validator, validators.size())); 100 } 101 102 @Override 103 public void fireEvent(GwtEvent<?> event) { 104 eventBus.fireEvent(event); 105 } 106 107 /** 108 * @return the inputWidget 109 */ 110 public W getInputWidget() { 111 return inputWidget; 112 } 113 114 @Override 115 public boolean isValidateOnBlur() { 116 return validateOnBlur; 117 } 118 119 @Override 120 public boolean removeValidator(Validator<V> validator) { 121 for (ValidatorWrapper<V> wrapper : validators) { 122 if (wrapper.getValidator().equals(validator)) { return validators.remove(wrapper); } 123 } 124 return false; 125 } 126 127 @Override 128 public void reset() { 129 if (errorHandler != null) { 130 errorHandler.clearErrors(); 131 } 132 } 133 134 /** 135 * Sets the error handler. 136 * 137 * @param errorHandler the new error handler 138 */ 139 public void setErrorHandler(ErrorHandler errorHandler) { 140 this.errorHandler = errorHandler; 141 } 142 143 @Override 144 public void setValidateOnBlur(boolean vob) { 145 validateOnBlur = vob; 146 } 147 148 @Override 149 public void setValidators(@SuppressWarnings("unchecked") Validator<V>... newValidators) { 150 validators.clear(); 151 for (Validator<V> validator : newValidators) { 152 addValidator(validator); 153 } 154 } 155 156 @Override 157 public boolean validate() { 158 return validate(true); 159 } 160 161 /** {@inheritDoc} */ 162 @Override 163 public boolean validate(boolean show) { 164 Boolean oldValid = valid; 165 valid = true; 166 if (errorHandler != null && !validators.isEmpty()) { 167 List<EditorError> errors = new ArrayList<EditorError>(); 168 for (ValidatorWrapper<V> wrapper : validators) { 169 Validator<V> validator = wrapper.getValidator(); 170 List<EditorError> result = validator.validate(inputWidget, inputWidget.getValue()); 171 if (result != null && !result.isEmpty()) { 172 errors.addAll(result); 173 valid = false; 174 } 175 } 176 if (show) { 177 if (errors.size() > 0) { 178 errorHandler.showErrors(errors); 179 } else { 180 errorHandler.clearErrors(); 181 } 182 } 183 } 184 if (valid != oldValid) { 185 eventBus.fireEvent(new ValidationChangedEvent(valid)); 186 } 187 return valid; 188 } 189}