001package gwt.material.design.client.base.validator; 002 003/* 004 * #%L 005 * GwtBootstrap3 006 * %% 007 * Copyright (C) 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.event.shared.GwtEvent; 024import com.google.gwt.user.client.ui.Widget; 025import com.google.web.bindery.event.shared.EventBus; 026import com.google.web.bindery.event.shared.HandlerRegistration; 027import com.google.web.bindery.event.shared.SimpleEventBus; 028import gwt.material.design.client.base.validator.ValidationChangedEvent.ValidationChangedHandler; 029 030import java.util.LinkedHashMap; 031import java.util.Map; 032 033/** 034 * Useful for validating a group of fields that implement the {@link HasValidators} interface. 035 * 036 * @author Steven Jardine 037 */ 038public class GroupValidator implements ValidationChangedEvent.HasValidationChangedHandlers { 039 040 private final SimpleEventBus eventBus; 041 042 private boolean fireEvents = false; 043 044 private final Map<HasValidators<?>, Boolean> fields; 045 046 private final Map<HasValidators<?>, HandlerRegistration> registrations; 047 048 private Boolean groupValid = null; 049 050 /** 051 * Constructor. 052 */ 053 public GroupValidator() { 054 fields = new LinkedHashMap<>(); 055 registrations = new LinkedHashMap<>(); 056 eventBus = new SimpleEventBus(); 057 } 058 059 /** 060 * Adds a field to the group. 061 * 062 * @param <T> the generic type 063 * @param field the field 064 */ 065 public <T extends Widget & HasValidators<?>> void add(final T field) { 066 fields.put(field, field.validate(false)); 067 if (field.isAttached()) { 068 updateStateAndNotify(); 069 } 070 registrations.put(field, field.addValidationChangedHandler(new ValidationChangedHandler() { 071 @Override 072 public void onValidationChanged(ValidationChangedEvent event) { 073 fields.put(field, event.isValid()); 074 if (fireEvents) { 075 updateStateAndNotify(); 076 } 077 } 078 })); 079 } 080 081 @Override 082 public HandlerRegistration addValidationChangedHandler(ValidationChangedHandler handler) { 083 return eventBus.addHandler(ValidationChangedEvent.getType(), handler); 084 } 085 086 @Override 087 public void fireEvent(GwtEvent<?> event) { 088 eventBus.fireEvent(event); 089 } 090 091 /** 092 * Removes a field from the validation group. 093 * 094 * @param <T> the generic type 095 * @param field the field 096 * @return true, if successful 097 */ 098 public <T extends Widget & HasValidators<?>> boolean remove(final T field) { 099 fields.remove(field); 100 HandlerRegistration reg = registrations.remove(field); 101 if (reg != null) { 102 reg.removeHandler(); 103 return true; 104 } 105 return false; 106 } 107 108 /** 109 * Update the state of the validator and notify via {@link EventBus} any changed handlers. 110 */ 111 protected void updateStateAndNotify() { 112 Boolean oldGroupValid = groupValid; 113 groupValid = true; 114 for (Boolean valid : fields.values()) { 115 groupValid &= valid; 116 } 117 if (groupValid != oldGroupValid) { 118 eventBus.fireEvent(new ValidationChangedEvent(groupValid)); 119 } 120 } 121 122 /** 123 * Validate the group. This calls {@link Validator #validate(Editor, Object)} on each field in the group. 124 * 125 * @return true, if successful 126 */ 127 public boolean validate() { 128 return validate(true); 129 } 130 131 /** 132 * Validate the group. This calls {@link Validator #validate(Editor, Object)} on each field in the group. 133 * 134 * @param show do we want to show the user the result of the validate via ui marks? 135 * @return true, if successful 136 */ 137 public boolean validate(boolean show) { 138 fireEvents = false; 139 for (HasValidators<?> field : fields.keySet()) { 140 field.validate(show); 141 } 142 fireEvents = true; 143 updateStateAndNotify(); 144 return groupValid; 145 } 146}