All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.user.datepicker.client.DatePicker Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2008 Google Inc.
 *
 * 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 com.google.gwt.user.datepicker.client;

import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.event.logical.shared.HasHighlightHandlers;
import com.google.gwt.event.logical.shared.HasShowRangeHandlers;
import com.google.gwt.event.logical.shared.HighlightEvent;
import com.google.gwt.event.logical.shared.HighlightHandler;
import com.google.gwt.event.logical.shared.ShowRangeEvent;
import com.google.gwt.event.logical.shared.ShowRangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.VerticalPanel;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Standard GWT date picker.
 *
 * 

CSS Style Rules

* *
    * *
  • .gwt-DatePicker { }
  • * *
  • .datePickerMonthSelector { the month selector widget }
  • * *
  • .datePickerMonth { the month in the month selector widget }
  • * *
  • .datePickerYear { the year in the month selector widget }
  • * *
  • .datePickerPreviousButton { the previous month button }
  • * *
  • .datePickerNextButton { the next month button }
  • * *
  • .datePickerPreviousYearButton { the previous year button }
  • * *
  • .datePickerNextYearButton { the next year button }
  • * *
  • .datePickerDays { the portion of the picker that shows the days }
  • * *
  • .datePickerWeekdayLabel { the label over weekdays }
  • * *
  • .datePickerWeekendLabel { the label over weekends }
  • * *
  • .datePickerDay { a single day }
  • * *
  • .datePickerDayIsToday { today's date }
  • * *
  • .datePickerDayIsWeekend { a weekend day }
  • * *
  • .datePickerDayIsFiller { a day in another month }
  • * *
  • .datePickerDayIsValue { the selected day }
  • * *
  • .datePickerDayIsDisabled { a disabled day }
  • * *
  • .datePickerDayIsHighlighted { the currently highlighted day }
  • * *
  • .datePickerDayIsValueAndHighlighted { the highlighted day if it is also * selected }
  • * *
* *

*

Example

* {@example com.google.gwt.examples.DatePickerExample} *

*/ public class DatePicker extends Composite implements HasHighlightHandlers, HasShowRangeHandlers, HasValue, IsEditor> { /** * Convenience class to group css style names. */ static class StandardCss { static StandardCss DEFAULT = new StandardCss("gwt-DatePicker", "datePicker"); private String baseName; private String widgetName; public StandardCss(String widgetName, String baseName) { this.widgetName = widgetName; this.baseName = baseName; } public String datePicker() { return getWidgetStyleName(); } public String day() { return wrap("Day"); } public String day(String dayModifier) { return day() + "Is" + dayModifier; } public String dayIsDisabled() { return day("Disabled"); } public String dayIsFiller() { return day("Filler"); } public String dayIsHighlighted() { return day("Highlighted"); } public String dayIsToday() { return day("Today"); } public String dayIsValue() { return day("Value"); } public String dayIsValueAndHighlighted() { return dayIsValue() + "AndHighlighted"; } public String dayIsWeekend() { return day("Weekend"); } public String days() { return wrap("Days"); } public String daysLabel() { return wrap("DaysLabel"); } public String getBaseStyleName() { return baseName; } public String getWidgetStyleName() { return widgetName; } public String month() { return wrap("Month"); } public String monthSelector() { return wrap("MonthSelector"); } public String nextButton() { return wrap("NextButton"); } public String nextYearButton() { return wrap("NextYearButton"); } public String previousButton() { return wrap("PreviousButton"); } public String previousYearButton() { return wrap("PreviousYearButton"); } public String weekdayLabel() { return wrap("WeekdayLabel"); } public String weekendLabel() { return wrap("WeekendLabel"); } public String year() { return wrap("Year"); } /** * Prepends the base name to the given style. * * @param style style name * @return style name */ protected String wrap(String style) { return baseName + style; } } /** * A date highlighted event that copied on read. */ private static class DateHighlightEvent extends HighlightEvent { protected DateHighlightEvent(Date highlighted) { super(highlighted); } @Override public Date getHighlighted() { return CalendarUtil.copyDate(super.getHighlighted()); } } private static class DateStyler { private Map info = new HashMap(); public String getStyleName(Date d) { return info.get(genKey(d)); } public void setStyleName(Date d, String styleName, boolean add) { // Code is easier to maintain if surrounded by " ", and on all browsers // this is a no-op. styleName = " " + styleName + " "; String key = genKey(d); String current = info.get(key); if (add) { if (current == null) { info.put(key, styleName); } else if (current.indexOf(styleName) == -1) { info.put(key, current + styleName); } } else { if (current != null) { String newValue = current.replaceAll(styleName, ""); if (newValue.trim().length() == 0) { info.remove(key); } else { info.put(key, newValue); } } } } @SuppressWarnings("deprecation") private String genKey(Date d) { return d.getYear() + "/" + d.getMonth() + "/" + d.getDate(); } } private static final int DEFAULT_VISIBLE_YEAR_COUNT = 21; private final DateStyler styler = new DateStyler(); private final MonthSelector monthAndYearSelector; private final CalendarView view; private final CalendarModel model; private Date value; private Date highlighted; private StandardCss css = StandardCss.DEFAULT; private LeafValueEditor editor; private int visibleYearCount = DEFAULT_VISIBLE_YEAR_COUNT; private boolean yearArrowsVisible; private boolean yearAndMonthDropdownVisible; /** * Create a new date picker. */ public DatePicker() { this(new DefaultMonthSelector(), new DefaultCalendarView(), new CalendarModel()); } /** * Creates a new date picker. * * @param monthAndYearSelector the month selector * @param view the view * @param model the model */ protected DatePicker(MonthSelector monthAndYearSelector, CalendarView view, CalendarModel model) { this.model = model; this.monthAndYearSelector = monthAndYearSelector; monthAndYearSelector.setDatePicker(this); this.view = view; view.setDatePicker(this); view.setup(); monthAndYearSelector.setup(); this.setup(); setCurrentMonth(new Date()); addStyleToDates(css().dayIsToday(), new Date()); } public HandlerRegistration addHighlightHandler(HighlightHandler handler) { return addHandler(handler, HighlightEvent.getType()); } public HandlerRegistration addShowRangeHandler(ShowRangeHandler handler) { return addHandler(handler, ShowRangeEvent.getType()); } /** * Adds a show range handler and immediately activate the handler on the * current view. * * @param handler the handler * @return the handler registration */ public HandlerRegistration addShowRangeHandlerAndFire( ShowRangeHandler handler) { ShowRangeEvent event = new ShowRangeEvent( getView().getFirstDate(), getView().getLastDate()) { }; handler.onShowRange(event); return addShowRangeHandler(handler); } /** * Add a style name to the given dates. */ public void addStyleToDates(String styleName, Date date) { styler.setStyleName(date, styleName, true); if (isDateVisible(date)) { getView().addStyleToDate(styleName, date); } } /** * Add a style name to the given dates. */ public void addStyleToDates(String styleName, Date date, Date... moreDates) { addStyleToDates(styleName, date); for (Date d : moreDates) { addStyleToDates(styleName, d); } } /** * Add a style name to the given dates. */ public void addStyleToDates(String styleName, Iterable dates) { for (Date d : dates) { addStyleToDates(styleName, d); } } /** * Adds the given style name to the specified dates, which must be visible. * This is only set until the next time the DatePicker is refreshed. */ public void addTransientStyleToDates(String styleName, Date date) { assert isDateVisible(date) : date + " must be visible"; getView().addStyleToDate(styleName, date); } /** * Adds the given style name to the specified dates, which must be visible. * This is only set until the next time the DatePicker is refreshed. */ public final void addTransientStyleToDates(String styleName, Date date, Date... moreDates) { addTransientStyleToDates(styleName, date); for (Date d : moreDates) { addTransientStyleToDates(styleName, d); } } /** * Adds the given style name to the specified dates, which must be visible. * This is only set until the next time the DatePicker is refreshed. */ public final void addTransientStyleToDates(String styleName, Iterable dates) { for (Date d : dates) { addTransientStyleToDates(styleName, d); } } public HandlerRegistration addValueChangeHandler( ValueChangeHandler handler) { return addHandler(handler, ValueChangeEvent.getType()); } /** * Returns a {@link TakesValueEditor} backed by the DatePicker. */ public LeafValueEditor asEditor() { if (editor == null) { editor = TakesValueEditor.of(this); } return editor; } /** * Gets the current month the date picker is showing. * *

* A datepicker may show days not in the current month. It * must show all days in the current month. *

* * @return the current month * */ public Date getCurrentMonth() { return getModel().getCurrentMonth(); } /** * Returns the first shown date. * * @return the first date. */ // Final because the view should always control the value of the first date. public final Date getFirstDate() { return view.getFirstDate(); } /** * Gets the highlighted date (the one the mouse is hovering over), if any. * * @return the highlighted date */ public final Date getHighlightedDate() { return CalendarUtil.copyDate(highlighted); } /** * Returns the last shown date. * * @return the last date. */ // Final because the view should always control the value of the last date. public final Date getLastDate() { return view.getLastDate(); } /** * Returns the number of year to display in the years selection dropdown. */ public int getVisibleYearCount() { return visibleYearCount; } /** * Gets the style associated with a date (does not include styles set via * {@link #addTransientStyleToDates}). * * @param date the date * @return the styles associated with this date */ public String getStyleOfDate(Date date) { return styler.getStyleName(date); } /** * Returns the selected date, or null if none is selected. * * @return the selected date, or null */ public final Date getValue() { return CalendarUtil.copyDate(value); } /** * Is the visible date enabled? * * @param date the date, which must be visible * * @return is the date enabled? */ public boolean isDateEnabled(Date date) { assert isDateVisible(date) : date + " is not visible"; return getView().isDateEnabled(date); } /** * Is the date currently shown in the date picker? * * @param date * * @return is the date currently shown */ public boolean isDateVisible(Date date) { CalendarView r = getView(); Date first = r.getFirstDate(); Date last = r.getLastDate(); return (date != null && (CalendarUtil.isSameDate(first, date) || CalendarUtil.isSameDate(last, date) || (first.before(date) && last.after(date)))); } /** * Can the user navigate through the years? * * @return is the year navigation is enabled */ public boolean isYearArrowsVisible() { return yearArrowsVisible; } /** * Is the year and month selectable via a dropdown? */ public boolean isYearAndMonthDropdownVisible() { return yearAndMonthDropdownVisible; } @Override public void onLoad() { ShowRangeEvent.fire(this, getFirstDate(), getLastDate()); } /** * Removes the styleName from the given dates (even if it is transient). */ public void removeStyleFromDates(String styleName, Date date) { styler.setStyleName(date, styleName, false); if (isDateVisible(date)) { getView().removeStyleFromDate(styleName, date); } } /** * Removes the styleName from the given dates (even if it is transient). */ public void removeStyleFromDates(String styleName, Date date, Date... moreDates) { removeStyleFromDates(styleName, date); for (Date d : moreDates) { removeStyleFromDates(styleName, d); } } /** * Removes the styleName from the given dates (even if it is transient). */ public void removeStyleFromDates(String styleName, Iterable dates) { for (Date d : dates) { removeStyleFromDates(styleName, d); } } /** * Sets the date picker to show the given month, use {@link #getFirstDate()} * and {@link #getLastDate()} to access the exact date range the date picker * chose to display. *

* A datepicker may show days not in the current month. It * must show all days in the current month. *

* * @param month the month to show */ public void setCurrentMonth(Date month) { getModel().setCurrentMonth(month); refreshAll(); } /** * Set the number of years to display in the years selection dropdown. The range of years will be * centered on the selected date. */ public void setVisibleYearCount(int numberOfYears) { if (numberOfYears <= 0) { throw new IllegalArgumentException("The number of years to display must be positive"); } visibleYearCount = numberOfYears; getMonthSelector().refresh(); } /** * Set if the user can navigate through the years via a set of backward and forward buttons. */ public void setYearArrowsVisible(boolean yearArrowsVisible) { this.yearArrowsVisible = yearArrowsVisible; getMonthSelector().refresh(); } /** * If the dropdownVisible is equal to true, the user will be able to change the current month and * the current year of the date picker via two dropdown lists. */ public void setYearAndMonthDropdownVisible(boolean dropdownVisible) { this.yearAndMonthDropdownVisible = dropdownVisible; getMonthSelector().refresh(); } /** * Sets the date picker style name. */ @Override public void setStyleName(String styleName) { css = new StandardCss(styleName, "datePicker"); super.setStyleName(styleName); } /** * Sets a visible date to be enabled or disabled. This is only set until the * next time the DatePicker is refreshed. */ public final void setTransientEnabledOnDates(boolean enabled, Date date) { assert isDateVisible(date) : date + " must be visible"; getView().setEnabledOnDate(enabled, date); } /** * Sets a visible date to be enabled or disabled. This is only set until the * next time the DatePicker is refreshed. */ public final void setTransientEnabledOnDates(boolean enabled, Date date, Date... moreDates) { setTransientEnabledOnDates(enabled, date); for (Date d : moreDates) { setTransientEnabledOnDates(enabled, d); } } /** * Sets a group of visible dates to be enabled or disabled. This is only set * until the next time the DatePicker is refreshed. */ public final void setTransientEnabledOnDates(boolean enabled, Iterable dates) { for (Date d : dates) { setTransientEnabledOnDates(enabled, d); } } /** * Sets the {@link DatePicker}'s value. * * @param newValue the new value */ public final void setValue(Date newValue) { setValue(newValue, false); } /** * Sets the {@link DatePicker}'s value. * * @param newValue the new value for this date picker * @param fireEvents should events be fired. */ public final void setValue(Date newValue, boolean fireEvents) { Date oldValue = value; if (oldValue != null) { removeStyleFromDates(css().dayIsValue(), oldValue); } value = CalendarUtil.copyDate(newValue); if (value != null) { addStyleToDates(css().dayIsValue(), value); } getView().setAriaSelectedCell(newValue); if (fireEvents) { DateChangeEvent.fireIfNotEqualDates(this, oldValue, newValue); } } /** * Gets the {@link CalendarModel} associated with this date picker. * * @return the model */ protected final CalendarModel getModel() { return model; } /** * Gets the {@link MonthSelector} associated with this date picker. * * @return the month selector */ protected final MonthSelector getMonthSelector() { return monthAndYearSelector; } /** * Gets the {@link CalendarView} associated with this date picker. * * @return the view */ protected final CalendarView getView() { return view; } /** * Refreshes all components of this date picker. */ protected final void refreshAll() { highlighted = null; getModel().refresh(); getView().refresh(); getMonthSelector().refresh(); if (isAttached()) { ShowRangeEvent.fire(this, getFirstDate(), getLastDate()); } getView().setAriaSelectedCell(value); } /** * Sets up the date picker. */ protected void setup() { /* * Use a table (VerticalPanel) to get shrink-to-fit behavior. Divs expand to * fill the available width, so we'd need to give it a size. */ VerticalPanel panel = new VerticalPanel(); initWidget(panel); setStyleName(panel.getElement(), css.datePicker()); setStyleName(css().datePicker()); panel.add(this.getMonthSelector()); panel.add(this.getView()); } /** * Gets the css associated with this date picker for use by extended month and * cell grids. * * @return the css. */ final StandardCss css() { return css; } /** * Sets the highlighted date. * * @param highlighted highlighted date */ void setHighlightedDate(Date highlighted) { this.highlighted = highlighted; fireEvent(new DateHighlightEvent(highlighted)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy