org.spiffyui.client.widgets.DatePickerTextBox.java Source code

Java tutorial

Introduction

Here is the source code for org.spiffyui.client.widgets.DatePickerTextBox.java

Source

/*******************************************************************************
 * 
 * Copyright 2011-2012 Spiffy UI Team   
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/
package org.spiffyui.client.widgets;

import java.util.Date;

import org.spiffyui.client.JSDateUtil;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.TextBox;

/**
 * This widget uses a simple GWT TextBox and attaches the JQuery UI
 * date picker.  When the field gets focus the date picker will become
 * visible.
 */
public class DatePickerTextBox extends TextBox {
    private String m_minDate;
    private String m_maxDate;

    private String m_format;

    /**
     * Create a DatePickerTextBox with a rendomly generated ID.  The ID is required
     * because the JQuery data picker needs a specific ID to connect to.
     *  
     */
    public DatePickerTextBox() {
        this(HTMLPanel.createUniqueId());
    }

    /**
     * Create a DatePickerTextBox with the specified ID.  The ID is required
     * because the JQuery data picker needs a specific ID to connect to.
     * 
     * @param id     the id for the text box
     */
    public DatePickerTextBox(String id) {
        super();
        getElement().setId(id);

        /*
         * The JQuery date picker follows slightly different rules for date
         * formats than our date library does.  We need to do a little conversion
         * to make it work.  See the date format here:
         *
         * http://docs.jquery.com/UI/Datepicker/formatDate
         */
        m_format = JSDateUtil.getShortDateFormat().replace('M', 'm').replaceAll("yyyy", "yy");

    }

    @Override
    public void onLoad() {
        super.onLoad();

        addDatePickerJS(this, getElement().getId(), m_format);
        if (m_minDate != null || m_maxDate != null) {
            setDateJS(getElement().getId(), m_minDate, m_maxDate);
        }
    }

    @Override
    protected void onUnload() {
        destroyDatePickerJS(getElement().getId());
        super.onUnload();
    }

    /**
     * Set a minimum selectable date via a Date object or as a string in 
     * the current dateFormat, or a number of days from today (e.g. +7) 
     * or a string of values and periods ('y' for years, 'm' for months, 
     * 'w' for weeks, 'd' for days, e.g. '-1y -1m'), or null for no limit. 
     *  
     * <b>Code examples</b>
     * 
     * setMinimumDate("-20"); 
     * setMinimumDate("+1M +10D");
     * 
     * @param dateSpecifier
     *               the date specifier
     */
    public void setMinimumDate(String dateSpecifier) {
        m_minDate = dateSpecifier;
        setDateJS(getElement().getId(), m_minDate, m_maxDate);
    }

    /**
     * Set a minimum selectable date via a java.util.Date object
     * 
     * @param date
     *               the date specifier
     */
    public void setMinimumDate(Date date) {
        m_minDate = JSDateUtil.getDate(date);
        setDateJS(getElement().getId(), m_minDate, m_maxDate);
    }

    /**
     * Gets the minimum date specifier for this date picker
     * 
     * @return the minimum date specifier
     */
    public String getMinimumDate() {
        return m_minDate;
    }

    /**
     * Set a maximum selectable date via a Date object or as a string in 
     * the current dateFormat, or a number of days from today (e.g. +7) 
     * or a string of values and periods ('y' for years, 'm' for months, 
     * 'w' for weeks, 'd' for days, e.g. '-1y -1m'), or null for no limit. 
     *  
     * <b>Code examples</b>
     * 
     * setMaximumDate("-20"); 
     * setMaximumDate("+1M +10D");
     * 
     * @param dateSpecifier
     *               the date specifier
     */
    public void setMaximumDate(String dateSpecifier) {
        m_maxDate = dateSpecifier;
        setDateJS(getElement().getId(), m_minDate, m_maxDate);
    }

    /**
     * Set a maximum selectable date via a java.util.Date object
     * 
     * @param date
     *               the date specifier
     */
    public void setMaximumDate(Date date) {
        m_maxDate = JSDateUtil.getDate(date);
        setDateJS(getElement().getId(), m_minDate, m_maxDate);
    }

    /**
     * Gets the minimum date specifier for this date picker
     * 
     * @return the minimum date specifier
     */
    public String getMaximumDate() {
        return m_maxDate;
    }

    private void fireOnChangeEvent() {
        /*
         * This is necessary for IE since an onchange event is not fired when a calendar date is selected.
         * This is cleaner than doing it the onPreviewNativeEvent way done in previous versions.
         */
        NativeEvent nativeEvent = Document.get().createChangeEvent();
        ChangeEvent.fireNativeEvent(nativeEvent, this);

    }

    private static native void setDateJS(String id, String mindate, String maxdate) /*-{ 
                                                                                    if (maxdate) {
                                                                                    $wnd.jQuery('#' + id).datepicker('option', 'maxDate',
                                                                                    $wnd.Date.parseExact(maxdate, $wnd.Date.CultureInfo.formatPatterns.shortDate));
                                                                                    }
                                                                                        
                                                                                    if (mindate) {
                                                                                    $wnd.jQuery('#' + id).datepicker('option', 'minDate',
                                                                                    $wnd.Date.parseExact(mindate, $wnd.Date.CultureInfo.formatPatterns.shortDate));
                                                                                    }
                                                                                    }-*/;

    private static native void addDatePickerJS(DatePickerTextBox x, String id, String format) /*-{
                                                                                              $wnd.jQuery('#' + id).datepicker({
                                                                                              dateFormat: format,
                                                                                              changeMonth: true,
                                                                                              changeYear: true,
                                                                                              onSelect: function(dateText, inst) {
                                                                                              return x.@org.spiffyui.client.widgets.DatePickerTextBox::fireOnChangeEvent()();
                                                                                              }
                                                                                              });
                                                                                              }-*/;

    private native void destroyDatePickerJS(String id) /*-{
                                                       $wnd.jQuery("#" + id).datepicker("destroy");
                                                       }-*/;

    /**
     * Get the value as a type-safe java.util.Date
     * @return the value in the TextBox as a java.util.Date or null if it was unparseable.
     */
    public Date getDateValue() {
        if (isEmpty()) {
            return null;
        } else {
            try {
                return JSDateUtil.parseShortDate(getValue());
            } catch (IllegalArgumentException e) {
                //the date was unparseable also return null
                return null;
            }
        }
    }

    /**
     * Sets the current Date value
     *
     * @param date the date value to set
     */
    public void setDateValue(Date date) {
        setValue(JSDateUtil.getDate(date));
    }

    /**
     * Convenience method to determine if the value is empty
     * since getDateValue will return null for empty as well as unparseable.
     * @return boolean true if empty
     */
    public boolean isEmpty() {
        return getValue().length() == 0;
    }

}