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.event.dom.client.BlurEvent;
025import com.google.gwt.event.dom.client.BlurHandler;
026import com.google.gwt.event.dom.client.HasBlurHandlers;
027import com.google.gwt.event.logical.shared.AttachEvent;
028import com.google.gwt.user.client.ui.HasValue;
029import com.google.gwt.user.client.ui.Widget;
030import com.google.web.bindery.event.shared.HandlerRegistration;
031import gwt.material.design.client.base.error.ErrorHandler;
032import gwt.material.design.client.base.validator.BlankValidator;
033import gwt.material.design.client.base.validator.HasBlankValidator;
034import gwt.material.design.client.base.validator.Validator;
035
036/**
037 * Mixin that provides the allowBlank functionality for input fields.
038 *
039 * @param <W> the generic type
040 * @param <V> the value type
041 *
042 * @author Steven Jardine
043 */
044public class BlankValidatorMixin<W extends Widget & HasValue<V> & Editor<V> & HasBlurHandlers, V> extends ValidatorMixin<W, V> implements HasBlankValidator {
045
046    private boolean allowBlank = true;
047
048    private BlankValidator<V> blankValidator;
049    private AttachEvent.Handler attachHandler = new AttachEvent.Handler() {
050        HandlerRegistration registration;
051        @Override
052        public void onAttachOrDetach(AttachEvent event) {
053            if(registration != null) {
054                registration.removeHandler();
055            }
056            registration = inputWidget.addBlurHandler(new BlurHandler() {
057                @Override
058                public void onBlur(BlurEvent event) {
059                    validate(isValidateOnBlur());
060                }
061            });
062        }
063    };
064
065    /**
066     * Constructor.
067     *
068     * @param inputWidget the input widget
069     * @param errorHandler the error handler
070     */
071    public BlankValidatorMixin(W inputWidget, ErrorHandler errorHandler) {
072        super(inputWidget, errorHandler);
073
074        setupBlurValidation();
075    }
076
077    protected HandlerRegistration setupBlurValidation() {
078        if(!inputWidget.isAttached()) {
079            return inputWidget.addAttachHandler(attachHandler);
080        } else {
081            return inputWidget.addBlurHandler(new BlurHandler() {
082                @Override
083                public void onBlur(BlurEvent event) {
084                    validate(isValidateOnBlur());
085                }
086            });
087        }
088    }
089
090    @Override
091    public void addValidator(Validator<V> validator) {
092        if (validator instanceof BlankValidator) {
093            allowBlank = false;
094        }
095        super.addValidator(validator);
096    }
097
098    /**
099     * Hook for custom blank validators.
100     *
101     * @return the blank validator
102     */
103    protected BlankValidator<V> createBlankValidator() {
104        return new BlankValidator<>();
105    }
106
107    /**
108     * @return the allow blank
109     */
110    @Override
111    public boolean isAllowBlank() {
112        return allowBlank;
113    }
114
115    /**
116     * @param allowBlank the new allow blank
117     */
118    @Override
119    public void setAllowBlank(boolean allowBlank) {
120        if (blankValidator == null) {
121            blankValidator = createBlankValidator();
122        }
123        this.allowBlank = allowBlank;
124        if (!allowBlank) {
125            addValidator(blankValidator);
126        } else {
127            removeValidator(blankValidator);
128        }
129    }
130}