001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.corelib.components;
014
015import org.apache.tapestry5.BindingConstants;
016import org.apache.tapestry5.ComponentResources;
017import org.apache.tapestry5.MarkupWriter;
018import org.apache.tapestry5.annotations.Environmental;
019import org.apache.tapestry5.annotations.Parameter;
020import org.apache.tapestry5.annotations.SupportsInformalParameters;
021import org.apache.tapestry5.ioc.annotations.Inject;
022import org.apache.tapestry5.services.DateUtilities;
023import org.apache.tapestry5.services.javascript.JavaScriptSupport;
024
025import java.util.Date;
026
027/**
028 * Used to present a date, formatted in the time zone of the client browser.
029 * This is based on the <a href="http://momentjs.com/">Moment</a> JavaScript library.
030 *
031 * If the value parameter is non-null, then this component will render an element
032 * wrapping the value (formatted in ISO-8601). The element will match the template element,
033 * or a "span" if the template did not provide an element. Informal parameters will be rendered
034 * into the element.
035 *
036 * When a date is rendered, it is rendered in an element, used to specify the client-side formatting.
037 * The element's content will be the ISO-8601 format. The client-side will
038 * immediately rewrite the content to the formatted value, in the client browser's time
039 * zone.
040 *
041 * @tapestrydoc
042 * @see TimeInterval
043 * @since 5.4
044 */
045@SupportsInformalParameters
046public class LocalDate
047{
048    /**
049     * The format to use, as defined by <a href="http://momentjs.com/docs/#/displaying/format/">Moment.js</a>.
050     * The factory default is "lll", which is a short form of the month, day, year, hour, minute and am/pm,
051     * e.g. "Sep 4 1986 8:30 PM".
052     */
053    @Parameter(defaultPrefix = BindingConstants.LITERAL, allowNull = false, value = "message:private-default-localdate-format")
054    String format;
055
056    /**
057     * The date value to render.  If this value is null, then nothing is rendered at all.
058     */
059    @Parameter
060    Date value;
061
062    @Inject
063    ComponentResources resources;
064
065    @Environmental
066    JavaScriptSupport javaScriptSupport;
067
068    @Inject
069    DateUtilities dateUtilities;
070
071    boolean beginRender(MarkupWriter writer)
072    {
073        if (value != null)
074        {
075            writer.element(resources.getElementName("span"),
076                    "data-localdate-format", format);
077
078            resources.renderInformalParameters(writer);
079
080            writer.write(dateUtilities.formatISO8601(value));
081
082            writer.end();
083
084            javaScriptSupport.require("t5/core/localdate");
085        }
086
087        // Skip the body regardless.
088        return false;
089    }
090}