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     */
016    package com.github.gwtbootstrap.datepicker.client.ui.base;
017    
018    import java.util.Date;
019    
020    import com.github.gwtbootstrap.client.ui.TextBox;
021    import com.github.gwtbootstrap.client.ui.base.HasAlternateSize;
022    import com.github.gwtbootstrap.client.ui.base.HasId;
023    import com.github.gwtbootstrap.client.ui.base.HasPlaceholder;
024    import com.github.gwtbootstrap.client.ui.base.HasSize;
025    import com.github.gwtbootstrap.client.ui.base.HasStyle;
026    import com.github.gwtbootstrap.client.ui.base.HasVisibility;
027    import com.github.gwtbootstrap.client.ui.base.HasVisibleHandlers;
028    import com.github.gwtbootstrap.client.ui.base.IsResponsive;
029    import com.github.gwtbootstrap.client.ui.base.IsSearchQuery;
030    import com.github.gwtbootstrap.client.ui.base.PlaceholderHelper;
031    import com.github.gwtbootstrap.client.ui.base.ResponsiveHelper;
032    import com.github.gwtbootstrap.client.ui.base.SearchQueryStyleHelper;
033    import com.github.gwtbootstrap.client.ui.base.SizeHelper;
034    import com.github.gwtbootstrap.client.ui.base.Style;
035    import com.github.gwtbootstrap.client.ui.base.StyleHelper;
036    import com.github.gwtbootstrap.client.ui.constants.AlternateSize;
037    import com.github.gwtbootstrap.client.ui.constants.Device;
038    import com.github.gwtbootstrap.client.ui.event.HiddenHandler;
039    import com.github.gwtbootstrap.client.ui.event.HideEvent;
040    import com.github.gwtbootstrap.client.ui.event.HideHandler;
041    import com.github.gwtbootstrap.client.ui.event.ShowEvent;
042    import com.github.gwtbootstrap.client.ui.event.ShowHandler;
043    import com.github.gwtbootstrap.client.ui.event.ShownHandler;
044    import com.github.gwtbootstrap.datepicker.client.ui.util.LocaleUtil;
045    import com.google.gwt.core.client.GWT;
046    import com.google.gwt.dom.client.Element;
047    import com.google.gwt.editor.client.IsEditor;
048    import com.google.gwt.editor.client.adapters.TakesValueEditor;
049    import com.google.gwt.event.dom.client.ChangeEvent;
050    import com.google.gwt.event.dom.client.ChangeHandler;
051    import com.google.gwt.event.dom.client.HasChangeHandlers;
052    import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
053    import com.google.gwt.event.logical.shared.ValueChangeEvent;
054    import com.google.gwt.event.logical.shared.ValueChangeHandler;
055    import com.google.gwt.event.shared.HandlerRegistration;
056    import com.google.gwt.i18n.client.DateTimeFormat;
057    import com.google.gwt.user.client.ui.HasValue;
058    import com.google.gwt.user.client.ui.Widget;
059    
060    /**
061     * Base DatePicker component.
062     *
063     * @author Carlos Alexandro Becker
064     * @author ohashi keisuke
065     * @since 2.0.4.0
066     */
067    public class DateBoxBase extends Widget implements HasValue<Date>, HasValueChangeHandlers<Date>, HasVisibility,
068            HasChangeHandlers, HasVisibleHandlers, HasAllDatePickerHandlers, IsEditor<TakesValueEditor<Date>>, HasPlaceholder, HasAlternateSize, IsSearchQuery, HasSize, HasId, IsResponsive , HasStyle {
069    
070        private final TextBox box;
071        private String format;
072        private String language;
073        private DateTimeFormat dtf;
074        private TakesValueEditor<Date> editor;
075    
076        /** placeholderHelper */
077        private PlaceholderHelper placeholderHelper = GWT.create(PlaceholderHelper.class);
078    
079        public DateBoxBase() {
080            this.box = new TextBox();
081            setElement(box.getElement());
082            setFormat("mm/dd/yyyy");
083            this.language = LocaleUtil.getLanguage();
084            setValue(new Date());
085        }
086    
087        /**
088         * {@inheritDoc}
089         */
090        @Override
091        public void setFormat(String format) {
092            this.format = format;
093            Date oldValue = getValue();
094            this.dtf = DateTimeFormat.getFormat(format.replaceAll("mm", "MM"));
095            if (oldValue != null) {
096                setValue(oldValue);
097            }
098        }
099    
100        public void setLanguage(String language) {
101            this.language = language;
102            LocaleUtil.forceLocale(language);
103        }
104    
105        /**
106         * Returns the internal instance of textbox element. Use only if know what you are doing.
107         *
108         * @return internal textbox intance.
109         */
110        protected TextBox getBox() {
111            return box;
112        }
113    
114        /**
115         * {@inheritDoc}
116         */
117        @Override
118        public Date getValue() {
119            try {
120                return dtf != null && box.getValue() != null ? dtf.parse(box.getValue()) : null;
121            } catch(Exception e) {
122                return null;
123            }
124        }
125        
126        /**
127         * Get un-tranceform text
128         * @return text box value
129         */
130        public String getOriginalValue() {
131            return box.getValue();
132        }
133    
134        /**
135         * {@inheritDoc}
136         */
137        @Override
138        public void setValue(Date value) {
139            setValue(value, false);
140        }
141    
142        /**
143         * {@inheritDoc}
144         */
145        @Override
146        public void setValue(Date value, boolean fireEvents) {
147            box.setValue(value != null ? dtf.format(value) : null);
148            
149            updateValue(box.getElement());
150            
151            if (fireEvents) {
152                ValueChangeEvent.fire(this, value);
153            }
154        }
155        
156        protected native void updateValue(Element e)/*-{
157            if($wnd.jQuery(e).data('datepicker')) {
158                $wnd.jQuery(e).data('datepicker').update();
159            }
160        }-*/;
161    
162        /**
163         * {@inheritDoc}
164         */
165        @Override
166        public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Date> dateValueChangeHandler) {
167            return addHandler(dateValueChangeHandler, ValueChangeEvent.getType());
168        }
169    
170        /**
171         * {@inheritDoc}
172         */
173        @Override
174        protected void onLoad() {
175            super.onLoad();
176            configure();
177        }
178    
179        /**
180         * Configure the elements for a specific widget.
181         * Use only if you know what you are doing.
182         *
183         * @param w: the widget to configure.
184         */
185        protected void configure(Widget w) {
186            w.getElement().setAttribute("data-date-format", format);
187            w.getElement().setAttribute("data-date-language", language);
188            configure(w.getElement());
189        }
190    
191        /**
192         * dateChange event handler.
193         */
194        public void onChange() {
195            ValueChangeEvent.fire(this, getValue());
196        }
197        
198        public void onShow() {
199            fireEvent(new ShowEvent());
200        }
201        
202        public void onHide() {
203            fireEvent(new HideEvent());
204        }
205        public void reconfigure() {
206            removeDataIfExists(getElement());
207            configure();
208        }
209    
210        /**
211         * configure this datepicker.
212         */
213        protected void configure() {
214            configure(this);
215        }
216        
217        protected native void removeDataIfExists(Element e) /*-{
218            var $that = $wnd.jQuery(e);
219            if($that.data('datepicker')) {
220                console.log($that.data());
221                $that.removeData('dateFormat');
222                $that.removeData('dateLanguage');
223                $that.removeData('dateWeekstart');
224                $that.removeData('dateStartdate');
225                $that.removeData('dateEnddate');
226                $that.removeData('datepicker');
227                $that.off();
228                console.log($that.data());
229            }
230        }-*/;
231    
232        /**
233         * call jquery datepicker plugin in a element.
234         *
235         * @param e: Element that will be transformed in a datepicker.
236         */
237        protected native void configure(Element e) /*-{
238            var that = this;
239            $wnd.jQuery(e).datepicker();
240            $wnd.jQuery(e).on('change' , function() {
241                that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onChange()();
242            });
243            $wnd.jQuery(e).datepicker().on("show", function () {
244                that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onShow()();
245            });
246            $wnd.jQuery(e).datepicker().on("hide", function () {
247                that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onHide()();
248            });
249        }-*/;
250    
251        private native void execute(Element e, String cmd) /*-{
252            $wnd.jQuery(e).datepicker(cmd);
253        }-*/;
254    
255        private void execute(String cmd) {
256            execute(getElement(), cmd);
257        }
258    
259        /**
260         * {@inheritDoc}
261         */
262        @Override
263        public void show() {
264            execute("show");
265        }
266    
267        /**
268         * {@inheritDoc}
269         */
270        @Override
271        public void hide() {
272            execute("hide");
273        }
274    
275        /**
276         * {@inheritDoc}
277         */
278        @Override
279        public void toggle() {
280            //TODO 2012/06/21 ohashi keisuke shoud be support
281            throw new UnsupportedOperationException("not support toggle");
282        }
283    
284        /**
285         * {@inheritDoc}
286         */
287        @Override
288        public HandlerRegistration addHideHandler(HideHandler handler) {
289            return addHandler(handler, HideEvent.getType());
290        }
291    
292        /**
293         * {@inheritDoc}
294         */
295        @Override
296        public HandlerRegistration addHiddenHandler(HiddenHandler handler) {
297            //TODO 2012/06/21 ohashi keisuke shoud be support
298            throw new UnsupportedOperationException("not support hidden event");
299        }
300    
301        /**
302         * {@inheritDoc}
303         */
304        @Override
305        public HandlerRegistration addShowHandler(ShowHandler handler) {
306            return addHandler(handler, ShowEvent.getType());
307        }
308    
309        /**
310         * {@inheritDoc}
311         */
312        @Override
313        public HandlerRegistration addShownHandler(ShownHandler handler) {
314            //TODO 2012/06/21 ohashi keisuke shoud be support
315            throw new UnsupportedOperationException("not support shown event");
316        }
317    
318        /**
319         * {@inheritDoc}
320         */
321        @Override
322        public void setWeekStart(int start) {
323            getElement().setAttribute("data-date-weekstart", start + "");
324        }
325    
326        /**
327         * {@inheritDoc}
328         */
329        @Override
330        public void setStartDate(String startDate) {
331            getElement().setAttribute("data-date-startdate", startDate);
332        }
333    
334        /**
335         * {@inheritDoc}
336         */
337        @Override
338        public void setStartDate_(Date startDate) {
339            setStartDate(dtf.format(startDate));
340        }
341    
342    
343        /**
344         * {@inheritDoc}
345         */
346        @Override
347        public void setEndDate(String endDate) {
348            getElement().setAttribute("data-date-enddate", endDate);
349        }
350    
351        /**
352         * {@inheritDoc}
353         */
354        @Override
355        public void setEndDate_(Date endDate) {
356            setEndDate(dtf.format(endDate));
357        }
358    
359        /**
360         * {@inheritDoc}
361         */
362        @Override
363        public void setAutoClose(boolean autoclose) {
364            getElement().setAttribute("data-date-autoclose", autoclose + "");
365        }
366    
367        /**
368         * {@inheritDoc}
369         */
370        @Override
371        public void setStartView(ViewMode mode) {
372            setStartView(mode.name());
373        }
374    
375        /**
376         * {@inheritDoc}
377         */
378        @Override
379        public void setStartView(String mode) {
380            getElement().setAttribute("data-date-startview", mode.toLowerCase());
381        }
382    
383            /**
384             * Retuen Editor
385             * @return editor
386             */
387            @Override
388            public TakesValueEditor<Date> asEditor() {
389                    if(editor == null){
390                            editor = TakesValueEditor.of(this);
391                    }
392                    return editor;
393            }
394    
395        @Override
396        public HandlerRegistration addChangeHandler(ChangeHandler handler) {
397            return addHandler(handler, ChangeEvent.getType());
398        }
399    
400        /**
401         * {@inheritDoc}
402         */
403        @Override
404        public void setPlaceholder(String placeholder) {
405            placeholderHelper.setPlaceholer(getElement(), placeholder);
406        }
407    
408        /**
409         * {@inheritDoc}
410         */
411        @Override
412        public String getPlaceholder() {
413            return placeholderHelper.getPlaceholder(getElement());
414        }
415    
416        /**
417         * {@inheritDoc}
418         */
419        @Override
420        public void setSearchQuery(boolean searchQuery) {
421            SearchQueryStyleHelper.setSearchQuery(this, searchQuery);
422        }
423    
424        /**
425         * {@inheritDoc}
426         */
427        @Override
428        public boolean isSearchQuery() {
429            return SearchQueryStyleHelper.isSearchQuery(this);
430        }
431    
432        /**
433         * {@inheritDoc}
434         */
435        @Override
436        public void setAlternateSize(AlternateSize size) {
437            StyleHelper.changeStyle(this, size, AlternateSize.class);
438        }
439    
440        /**
441         * {@inheritDoc}
442         */
443        @Override
444        public void setSize(int size) {
445            SizeHelper.setSize(this, size);
446        }
447    
448        /**
449         * {@inheritDoc}
450         */
451        @Override
452        public String getId() {
453            return getElement().getId();
454        }
455    
456        /**
457         * {@inheritDoc}
458         */
459        @Override
460        public void setId(String id) {
461            getElement().setId(id);
462        }
463    
464        /**
465         * {@inheritDoc}
466         */
467        @Override
468        public void setShowOn(Device device) {
469            ResponsiveHelper.setShowOn(this, device);
470        }
471    
472        /**
473         * {@inheritDoc}
474         */
475        @Override
476        public void setHideOn(Device device) {
477            ResponsiveHelper.setHideOn(this, device);
478            
479        }
480    
481        /**
482         * {@inheritDoc}
483         */
484        @Override
485        public void setStyle(Style style) {
486            StyleHelper.setStyle(this, style);
487        }
488    
489        /**
490         * {@inheritDoc}
491         */
492        @Override
493        public void addStyle(Style style) {
494            StyleHelper.addStyle(this, style);
495        }
496    
497        /**
498         * {@inheritDoc}
499         */
500        @Override
501        public void removeStyle(Style style) {
502            StyleHelper.removeStyle(this, style);
503            
504        }
505    }