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