/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.isis.viewer.wicket.ui.components.scalars.datepicker; import de.agilecoders.wicket.jquery.AbstractConfig; import de.agilecoders.wicket.jquery.IKey; import java.io.IOException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.wicket.util.lang.Args; import org.apache.wicket.util.string.Strings; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * Configuration holder for all {@link TextFieldWithDateTimePicker} configurations. * Provides settings for <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">Bootstrap Datetime picker</a> * JavaScript widget */ public class DateTimeConfig extends AbstractConfig { /** * The earliest date that may be selected; all earlier dates will be disabled. */ private static final IKey<String> StartDate = newKey("startDate", null); /** * The latest date that may be selected; all later dates will be disabled. */ private static final IKey<String> EndDate = newKey("endDate", null); /** * The view that the datepicker should show when it is opened. Accepts values of * 0 or 'month' for month view (the default); 1 or 'year' for the 12-month overview, * and 2 or 'decade' for the 10-year overview. Useful for date-of-birth datepickers. */ private static final IKey<String> _ViewMode = newKey("viewMode", ViewMode.days.name()); /** * If true, displays a "Today" button at the bottom of the datepicker to select * the current date. If true, the "Today" button will only move the current date * into view; */ private static final IKey<TodayButton> ShowTodayButton = newKey("todayBtn", TodayButton.FALSE); /** * Whether or not to allow date navigation by arrow keys. */ private static final IKey<Boolean> KeyboardNavigation = newKey("keyboardNavigation", true); /** * show the date and time picker side by side */ private static final IKey<Boolean> SideBySide = newKey("sideBySide", false); /** * @see <a href="http://eonasdan.github.io/bootstrap-datetimepicker/Options/#usecurrent">online reference</a> */ private static final IKey<Boolean> UseCurrent = newKey("useCurrent", true); /** * @see <a href="http://eonasdan.github.io/bootstrap-datetimepicker/Options/#mindate">online reference</a> */ private static final IKey<String> MinDate = newKey("minDate", null); /** * @see <a href="http://eonasdan.github.io/bootstrap-datetimepicker/Options/#maxdate">online reference</a> */ private static final IKey<String> MaxDate = newKey("maxDate", null); /** * The two-letter code of the language to use for month and day names. * These will also be used as the input's value (and subsequently sent to the * server in the case of form submissions). Currently ships with English ('en'); * German ('de'), Brazilian ('br'), and Spanish ('es') translations, but others * can be added (see I18N below). If an unknown language code is given, English * will be used. */ private static final IKey<String> Language = newKey("language", "en"); /** * The date format, combination of d, dd, m, mm, M, MM, yy, yyyy. */ private static final IKey<String> Format = newKey("format", null); /** * Day of the week start. 0 (Sunday) to 6 (Saturday) */ private static final IKey<Integer> WeekStart = newKey("weekStart", 0); /** * If true, highlights the current date. */ private static final IKey<Boolean> HighlightToday = newKey("todayHighlight", false); /** * Whether or not to close the datepicker immediately when a date is selected. */ private static final IKey<Boolean> AutoClose = newKey("autoclose", false); /** * Whether or not to force parsing of the input value when the picker is closed. * That is, when an invalid date is left in the input field by the user, the picker * will forcibly parse that value, and set the input's value to the new, valid date, * conforming to the given format. */ private static final IKey<Boolean> ForceParse = newKey("forceParse", true); /** * Whether or not to show the clear button. */ private static final IKey<Boolean> ClearButton = newKey("clearBtn", false); /** * Whether or not to show week numbers to the left of week rows. */ private static final IKey<Boolean> CalendarWeeks = newKey("calendarWeeks", false); /** * holds all week days in a specific sort order. */ public enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } /** * holds all view options. */ public enum ViewMode { months, years, days } /** * Construct. */ public DateTimeConfig() { super(); } /** * @return the date format as string */ public String getFormat() { return getString(Format); } /** * @return the language to use */ public String getLanguage() { return getString(Language); } /** * @return true if default language should be used. */ public boolean isDefaultLanguageSet() { return Language.isDefaultValue(getLanguage()); } /** * The earliest date that may be selected; all earlier dates will be disabled. * * @param value the earliest start date * @return this instance for chaining */ public DateTimeConfig withStartDate(final DateTime value) { String format = getFormat(); String startDate; if (Strings.isEmpty(format)) { startDate = value.toString(); } else { DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format); startDate = dateTimeFormatter.print(value); } put(StartDate, startDate); return this; } /** * The latest date that may be selected; all later dates will be disabled. * * @param value the latest end date * @return this instance for chaining */ public DateTimeConfig withEndDate(final DateTime value) { Args.notNull(value, "value"); String format = getFormat(); String endDate; if (Strings.isEmpty(format)) { endDate = value.toString(); } else { DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format); endDate = dateTimeFormatter.print(value); } put(EndDate, endDate); return this; } /** * The two-letter code of the language to use for month and day names. * These will also be used as the input's value (and subsequently sent to the * server in the case of form submissions). Currently ships with English ('en'), * German ('de'), Brazilian ('br'), and Spanish ('es') translations, but others * can be added (see I18N below). If an unknown language code is given, English * will be used. * * @param value two letter language code (optional 5 letter code like de_DE) * @return this instance for chaining */ public DateTimeConfig withLanguage(final String value) { put(Language, value); return this; } /** * The default view to display when the picker is shown. * Useful for date-of-birth datepicker. * * @param value the start view to use * @return this instance for chaining */ public DateTimeConfig withView(final ViewMode value) { put(_ViewMode, value.name()); return this; } /** * The date format (java style), combination of d, dd, m, mm, M, MM, yy, yyyy. * * @param value The date format value (java style) * @return this instance for chaining */ public DateTimeConfig withFormat(final String value) { put(Format, value); return this; } /** * Day of the week start. 0 (Sunday) to 6 (Saturday) * * @param value the {@link Day} the week starts * @return this instance for chaining */ public DateTimeConfig withWeekStart(final Day value) { put(WeekStart, value.ordinal()); return this; } /** * Whether or not to allow date navigation by arrow keys. * * @param value true, if keyboard navigation is allowed * @return this instance for chaining */ public DateTimeConfig allowKeyboardNavigation(final boolean value) { put(KeyboardNavigation, value); return this; } public DateTimeConfig sideBySide(final boolean value) { put(SideBySide, value); return this; } /** * If true, highlights the current date. * * @param value If true, highlights the current date. * @return this instance for chaining */ public DateTimeConfig highlightToday(final boolean value) { put(HighlightToday, value); return this; } /** * If true, displays a "Today" button at the bottom of the datepicker to select * the current date. If true, the "Today" button will only move the current date * into view; * * @param value whether to show today button or not * @return this instance for chaining */ public DateTimeConfig showTodayButton(final TodayButton value) { put(ShowTodayButton, value); return this; } /** * Whether or not to force parsing of the input value when the picker is closed. * That is, when an invalid date is left in the input field by the user, the picker * will forcibly parse that value, and set the input's value to the new, valid date, * conforming to the given format. * * @param value Whether or not to force parsing of the input value when the picker is closed * @return this instance for chaining */ public DateTimeConfig forceParse(final boolean value) { put(ForceParse, value); return this; } /** * @param value Whether or not to display a 'clear' button, which allows for clearing the input field. * @return this instance for chaining */ public DateTimeConfig clearButton(final boolean value) { put(ClearButton, value); return this; } /** * @param value Whether or not to show week numbers to the left of week rows. * @return this instance for chaining */ public DateTimeConfig calendarWeeks(final boolean value) { put(CalendarWeeks, value); return this; } public DateTimeConfig useCurrent(final boolean value) { put(UseCurrent, value); return this; } public DateTimeConfig minDate(final String value) { put(MinDate, value); return this; } public DateTimeConfig maxDate(final String value) { put(MaxDate, value); return this; } /** * Whether or not to close the datepicker immediately when a date is selected. * * @param value true, if datepicker should close immediately when date is selected. * @return this instance for chaining */ public DateTimeConfig autoClose(final boolean value) { put(AutoClose, value); return this; } /** * See <a href="http://bootstrap-datepicker.readthedocs.org/en/latest/options.html#todaybtn">docs</a>. * Today button could be a boolean or string <em>"linked"</em>: * <cite>If true or “linked”, displays a “Today” button at the bottom of the datepicker to select the * current date. If true, the “Today” button will only move the current date into view; if “linked”, * the current date will also be selected.</cite> */ @JsonSerialize(using = TodayButtonSerializer.class) public static enum TodayButton { TRUE, FALSE, LINKED } /** * Serializer for TodayButton */ private static class TodayButtonSerializer extends JsonSerializer<TodayButton> { @Override public void serialize(TodayButton value, JsonGenerator jgen, SerializerProvider provider) throws IOException { switch (value) { case TRUE: jgen.writeBoolean(true); break; case FALSE: jgen.writeBoolean(false); break; case LINKED: jgen.writeString("linked"); break; } } } }