001/*
002 *  Copyright 2012 GWT-Bootstrap
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.github.gwtbootstrap.client.ui.base;
017
018import java.util.List;
019
020import com.github.gwtbootstrap.client.ui.constants.AlternateSize;
021import com.github.gwtbootstrap.client.ui.constants.Constants;
022import com.github.gwtbootstrap.client.ui.constants.ControlGroupType;
023import com.github.gwtbootstrap.client.ui.constants.Device;
024import com.google.gwt.core.client.GWT;
025import com.google.gwt.dom.client.Element;
026import com.google.gwt.editor.client.EditorError;
027import com.google.gwt.editor.client.HasEditorErrors;
028import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
029import com.google.gwt.text.shared.Parser;
030import com.google.gwt.text.shared.Renderer;
031import com.google.gwt.user.client.ui.Widget;
032
033/**
034 * A ValueBoxBase extending for Bootstarp style.
035 * 
036 * <pre>
037 * It is GWT's {@link com.google.gwt.user.client.ui.ValueBoxBase} extending for Bootstrap style.
038 * </pre>
039 * @since 2.0.4.0
040 * 
041 * @author ohashi keisuke
042 * @see com.google.gwt.user.client.ui.ValueBoxBase
043 * @param <T> the value type
044 */
045public class ValueBoxBase<T> extends com.google.gwt.user.client.ui.ValueBoxBase<T> implements HasPlaceholder, HasAlternateSize, IsSearchQuery, HasSize, HasId, IsResponsive , HasStyle, HasEditorErrors<T>{
046
047        /** placeholderHelper */
048        private PlaceholderHelper placeholderHelper = GWT.create(PlaceholderHelper.class);
049
050        /** Widget for control decoration on <code>EditorError</code>s */
051        private Widget controlGroup;// could be a ControlGroup widget
052        /** Widget where <code>EditorError</code>s messages will be placed */
053        private Widget errorLabel;// could be a HelpInline widget
054
055        /**
056         * Creates a value box that wraps the given browser element handle. This is
057         * only used by subclasses.
058         * 
059         * @param elem
060         *            the browser element to wrap
061         */
062        protected ValueBoxBase(Element elem,
063                Renderer<T> renderer,
064                Parser<T> parser) {
065                super(elem, renderer, parser);
066        }
067
068        /**
069         * 
070         * @see com.google.gwt.editor.client.HasEditorErrors#showErrors(java.util.List)
071         */
072        @Override
073        public void showErrors(List<EditorError> errors) {
074                Widget decoratedWidget = controlGroup != null? controlGroup : this;
075                if(errors != null && !errors.isEmpty()) {
076                        StyleHelper.addStyle(decoratedWidget, ControlGroupType.ERROR);
077                        SafeHtmlBuilder sb = new SafeHtmlBuilder();
078                        for (EditorError error : errors) {
079                                if(error.getEditor() == this) {
080                                        error.setConsumed(true);
081                                        sb.appendEscaped(error.getMessage());
082                                        sb.appendHtmlConstant("<br />");
083                                }
084                        }
085                        setErrorLabelText(sb.toSafeHtml().asString());
086                } else {
087                        StyleHelper.removeStyle(decoratedWidget, ControlGroupType.ERROR);
088                        setErrorLabelText("");
089                }
090        }
091        
092        @Override
093        public void setValue(T value) {
094                showErrors(null);//clear errors on value change
095                super.setValue(value);
096        }
097        
098        @Override
099        public void setValue(T value, boolean fireEvents) {
100                showErrors(null);//clear errors on value change
101                super.setValue(value, fireEvents);
102        }
103        
104        /**
105         * The widget that will be decorated on <code>EditorError</code>s will be added de <code>ControlGroupType.ERROR</code> style.
106         * It can be a ControlGroup or any widget.
107         * @param controlGroup
108         */
109        public void setControlGroup(Widget controlGroup) {
110                this.controlGroup = controlGroup;
111        }
112        /**
113         * Widget where <code>EditorError</code>s messages will be placed.
114         * It can be a HelpBlock or any other widget.
115         * @param errorLabel
116         */
117        public void setErrorLabel(Widget errorLabel) {
118                this.errorLabel = errorLabel;
119        }
120
121        /**
122         * Sets the content of the <code>EditorError</code>s messages inside de <code>errorLabel</code>.
123         * This implementation uses {@link Element#setInnerHTML(String)} to set the content.
124         * @param errorMessage
125         */
126        protected void setErrorLabelText(String errorMessage) {
127                if(errorLabel != null) {
128                        errorLabel.getElement().setInnerHTML(errorMessage);
129                }
130        }
131
132
133        /**
134         * {@inheritDoc}
135         */
136        @Override
137        public void setPlaceholder(String placeholder) {
138                placeholderHelper.setPlaceholer(getElement(), placeholder);
139        }
140
141        /**
142         * {@inheritDoc}
143         */
144        @Override
145        public String getPlaceholder() {
146                return placeholderHelper.getPlaceholder(getElement());
147        }
148
149        /**
150         * {@inheritDoc}
151         */
152        @Override
153        public void setSearchQuery(boolean searchQuery) {
154                SearchQueryStyleHelper.setSearchQuery(this, searchQuery);
155        }
156
157        /**
158         * {@inheritDoc}
159         */
160        @Override
161        public boolean isSearchQuery() {
162                return SearchQueryStyleHelper.isSearchQuery(this);
163        }
164
165        /**
166         * {@inheritDoc}
167         */
168        @Override
169        public void setAlternateSize(AlternateSize size) {
170                StyleHelper.changeStyle(this, size, AlternateSize.class);
171        }
172
173        /**
174         * {@inheritDoc}
175         */
176        @Override
177        public void setSize(int size) {
178                SizeHelper.setSize(this, size);
179        }
180
181        /**
182         * {@inheritDoc}
183         */
184        @Override
185        public String getId() {
186                return getElement().getId();
187        }
188
189        /**
190         * {@inheritDoc}
191         */
192        @Override
193        public void setId(String id) {
194                getElement().setId(id);
195        }
196
197        /**
198         * {@inheritDoc}
199         */
200        @Override
201        public void setEnabled(boolean enabled) {
202                super.setEnabled(enabled);
203                if (enabled) {
204                        removeStyleName(Constants.DISABLED);
205                } else {
206                        addStyleName(Constants.DISABLED);
207                }
208        }
209
210        /**
211         * {@inheritDoc}
212         */
213        @Override
214        public void setShowOn(Device device) {
215                ResponsiveHelper.setShowOn(this, device);
216        }
217
218        /**
219         * {@inheritDoc}
220         */
221        @Override
222        public void setHideOn(Device device) {
223                ResponsiveHelper.setHideOn(this, device);
224                
225        }
226
227        /**
228         * {@inheritDoc}
229         */
230        @Override
231        public void setStyle(Style style) {
232                StyleHelper.setStyle(this, style);
233        }
234
235        /**
236         * {@inheritDoc}
237         */
238        @Override
239        public void addStyle(Style style) {
240                StyleHelper.addStyle(this, style);
241        }
242
243        /**
244         * {@inheritDoc}
245         */
246        @Override
247        public void removeStyle(Style style) {
248                StyleHelper.removeStyle(this, style);
249                
250        }
251
252    /**
253     * Make any <input> or <textarea> element behave like a block level element.
254     *
255     * @param blockLevel
256     */
257    public void setBlockLevel(boolean blockLevel) {
258        //setStyleDependentName cannot be used, because stylePrimaryName is gwt default name, e.g: "gwt-TextBox"
259        setStyleName(Constants.BLOCK_LEVEL, blockLevel);
260    }
261}