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