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

org.apache.myfaces.custom.date.HtmlDateRenderer Maven / Gradle / Ivy

Go to download

JSF components and utilities that can be used with any JSF implementation. This library is compatible with both JSF1.1 and JSF1.2; however for JSF1.2 users there is an alternative build of Tomahawk available that takes advantage of JSF1.2 features to offer some additional benefits.

There is a newer version: 1.1.14
Show newest version
/*
 * 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.myfaces.custom.date;

import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.ConverterException;

import org.apache.myfaces.component.UserRoleUtils;
import org.apache.myfaces.custom.calendar.DateBusinessConverter;
import org.apache.myfaces.custom.calendar.DefaultDateBusinessConverter;
import org.apache.myfaces.custom.calendar.FunctionCallProvider;
import org.apache.myfaces.custom.calendar.HtmlCalendarRenderer;
import org.apache.myfaces.custom.calendar.HtmlCalendarRenderer.CalendarDateTimeConverter;
import org.apache.myfaces.custom.date.AbstractHtmlInputDate.UserData;
import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
import org.apache.myfaces.tomahawk.util.Constants;

/**
 * @JSFRenderer
 *   renderKitId = "HTML_BASIC" 
 *   family = "javax.faces.Input"
 *   type = "org.apache.myfaces.Date"
 * 
 * @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
 * @version $Revision: 992388 $ $Date: 2010-09-03 19:30:51 +0200 (Fri, 03 Sep 2010) $
 */
public class HtmlDateRenderer extends HtmlRenderer {
    /**
     * 

The message identifier of the {@link FacesMessage} to be created if * the input is not a valid date.

*/ public static final String DATE_MESSAGE_ID = "org.apache.myfaces.Date.INVALID"; private static final String ID_DAY_POSTFIX = ".day"; private static final String ID_MONTH_POSTFIX = ".month"; private static final String ID_YEAR_POSTFIX = ".year"; private static final String ID_HOURS_POSTFIX = ".hours"; private static final String ID_MINUTES_POSTFIX = ".minutes"; private static final String ID_SECONDS_POSTFIX = ".seconds"; private static final String ID_AMPM_POSTFIX = ".ampm"; static public String getClientIdForDaySubcomponent(String clientId) { return clientId + ID_DAY_POSTFIX; } protected boolean isDisabled(FacesContext facesContext, HtmlInputDate inputDate) { if( !UserRoleUtils.isEnabledOnUserRole(inputDate) ) return false; return inputDate.isDisabled(); } public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException { RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputDate.class); HtmlInputDate inputDate = (HtmlInputDate) uiComponent; Locale currentLocale = facesContext.getViewRoot().getLocale(); UserData userData = null; String type = inputDate.getType(); boolean ampm = inputDate.isAmpm(); String clientId = uiComponent.getClientId(facesContext); if (null == inputDate.getConverter()) { userData = (UserData) inputDate.getSubmittedValue(); if( userData == null ) userData = inputDate.getUserData(currentLocale); } else { //Use converter to get the value as string and //create a UserData decoding it. String value = org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils.getStringValue(facesContext, inputDate); //Create a UserData bean userData = inputDate.getUserData(currentLocale); if (null != value) { StringTokenizer st = new StringTokenizer(value,"\n"); while(st.hasMoreTokens()) { String token = st.nextToken(); if (token.startsWith("year=")) { userData.setYear(token.substring(5)); } if (token.startsWith("month=")) { userData.setMonth(token.substring(6)); } if (token.startsWith("day=")) { userData.setDay(token.substring(4)); } if (token.startsWith("hours=")) { userData.setHours(token.substring(6)); } if (token.startsWith("minutes=")) { userData.setMinutes(token.substring(8)); } if (token.startsWith("seconds=")) { userData.setSeconds(token.substring(8)); } if (token.startsWith("ampm=")) { userData.setAmpm(token.substring(5)); } } } } boolean disabled = isDisabled(facesContext, inputDate); boolean readonly = inputDate.isReadonly(); ResponseWriter writer = facesContext.getResponseWriter(); HtmlRendererUtils.writePrettyLineSeparator(facesContext); writer.startElement(HTML.SPAN_ELEM, uiComponent); writer.writeAttribute(HTML.ID_ATTR, clientId, null); if( ! (type.equals("time") || type.equals("short_time"))){ encodeInputDay(inputDate, writer, clientId, userData, disabled, readonly); encodeInputMonth(inputDate, writer, clientId, userData, currentLocale, disabled, readonly); encodeInputYear(inputDate, writer, clientId, userData, disabled, readonly); if( inputDate.isPopupCalendar() && ! disabled && ! readonly ) encodePopupCalendarButton(facesContext, uiComponent, writer, clientId, currentLocale); } if( type.equals("both") || type.equals("full")){ writer.write(" "); } if( ! type.equals("date")){ encodeInputHours(uiComponent, writer, clientId, userData, disabled, readonly); writer.write(":"); encodeInputMinutes(uiComponent, writer, clientId, userData, disabled, readonly); if (type.equals("full")|| type.equals("time")) { writer.write(":"); encodeInputSeconds(uiComponent, writer, clientId, userData, disabled, readonly); } if (ampm) { encodeInputAmpm(uiComponent, writer, clientId, userData, disabled, readonly, currentLocale); } } writer.endElement(HTML.SPAN_ELEM); } protected void encodeInputField(UIComponent uiComponent, ResponseWriter writer, String id, String value, int size, boolean disabled, boolean readonly) throws IOException { writer.startElement(HTML.INPUT_ELEM, uiComponent); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.UNIVERSAL_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.EVENT_HANDLER_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.COMMON_FIELD_EVENT_ATTRIBUTES); if (disabled) { writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null); } if( readonly ) { writer.writeAttribute(HTML.READONLY_ATTR, Boolean.TRUE, null); } writer.writeAttribute(HTML.ID_ATTR, id, null); writer.writeAttribute(HTML.NAME_ATTR, id, null); writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null); writer.writeAttribute(HTML.MAXLENGTH_ATTR, Integer.toString(size), null); if (value != null) { writer.writeAttribute(HTML.VALUE_ATTR, value, null); } writer.endElement(HTML.INPUT_ELEM); } protected void encodeInputDay(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly) throws IOException { encodeInputField(uiComponent, writer, getClientIdForDaySubcomponent(clientId), userData.getDay(), 2, disabled, readonly); } protected void encodeInputMonth(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, Locale currentLocale, boolean disabled, boolean readonly) throws IOException { writer.startElement(HTML.SELECT_ELEM, uiComponent); writer.writeAttribute(HTML.ID_ATTR, clientId + ID_MONTH_POSTFIX, null); writer.writeAttribute(HTML.NAME_ATTR, clientId + ID_MONTH_POSTFIX, null); writer.writeAttribute(HTML.SIZE_ATTR, "1", null); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.UNIVERSAL_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.EVENT_HANDLER_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.COMMON_FIELD_EVENT_ATTRIBUTES); if (disabled) { writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null); } if (readonly) { writer.writeAttribute(HTML.READONLY_ATTR, Boolean.TRUE, null); } int selectedMonth = userData.getMonth() == null ? -1 : Integer.parseInt(userData.getMonth())-1; String[] months = HtmlCalendarRenderer.mapMonths(new DateFormatSymbols(currentLocale)); encodeEmptyInputMonthSelection(uiComponent, writer, selectedMonth); for (int i = 0; i < months.length; i++) { String monthName = months[i]; String monthNumber = Integer.toString(i+1); writer.write("\t\t"); writer.startElement(HTML.OPTION_ELEM, uiComponent); writer.writeAttribute(HTML.VALUE_ATTR, monthNumber, null); if (i == selectedMonth) writer.writeAttribute(HTML.SELECTED_ATTR, HTML.SELECTED_ATTR, null); writer.writeText(monthName, null); writer.endElement(HTML.OPTION_ELEM); } // bug #970747: force separate end tag writer.writeText("", null); writer.endElement(HTML.SELECT_ELEM); } protected void encodeEmptyInputMonthSelection(UIComponent component, ResponseWriter writer, int selectedMonth) throws IOException{ writer.startElement(HTML.OPTION_ELEM, component); writer.writeAttribute(HTML.VALUE_ATTR, "-1", null); if(selectedMonth == -1) writer.writeAttribute(HTML.SELECTED_ATTR, HTML.SELECTED_ATTR, null); writer.writeText(((HtmlInputDate)component).getEmptyMonthSelection(), null); writer.endElement(HTML.OPTION_ELEM); } protected void encodeInputYear(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly) throws IOException { encodeInputField(uiComponent, writer, clientId + ID_YEAR_POSTFIX, userData.getYear(), 4, disabled, readonly); } protected void encodeInputHours(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly) throws IOException { encodeInputField(uiComponent, writer, clientId + ID_HOURS_POSTFIX, userData.getHours(), 2, disabled, readonly); } protected void encodeInputMinutes(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly) throws IOException { encodeInputField(uiComponent, writer, clientId + ID_MINUTES_POSTFIX, userData.getMinutes(), 2, disabled, readonly); } protected void encodeInputSeconds(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly) throws IOException { encodeInputField(uiComponent, writer, clientId + ID_SECONDS_POSTFIX, userData.getSeconds(), 2, disabled, readonly); } protected void encodeAmpmChoice(DateFormatSymbols symbols, UIComponent uiComponent, ResponseWriter writer, int calendar_ampm, int selected) throws IOException { String[] ampm_choices = symbols.getAmPmStrings(); writer.write("\t\t"); writer.startElement(HTML.OPTION_ELEM, uiComponent); writer.writeAttribute(HTML.VALUE_ATTR, new Integer(calendar_ampm), null); if (calendar_ampm == selected) writer.writeAttribute(HTML.SELECTED_ATTR, HTML.SELECTED_ATTR, null); writer.writeText(ampm_choices[calendar_ampm], null); writer.endElement(HTML.OPTION_ELEM); } protected void encodeInputAmpm(UIComponent uiComponent, ResponseWriter writer, String clientId, UserData userData, boolean disabled, boolean readonly, Locale currentLocale) throws IOException { writer.startElement(HTML.SELECT_ELEM, uiComponent); writer.writeAttribute(HTML.ID_ATTR, clientId + ID_AMPM_POSTFIX, null); writer.writeAttribute(HTML.NAME_ATTR, clientId + ID_AMPM_POSTFIX, null); writer.writeAttribute(HTML.SIZE_ATTR, "1", null); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.UNIVERSAL_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.EVENT_HANDLER_ATTRIBUTES); HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.COMMON_FIELD_EVENT_ATTRIBUTES); if (disabled) { writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null); } if (readonly) { writer.writeAttribute(HTML.READONLY_ATTR, Boolean.TRUE, null); } DateFormatSymbols symbols = new DateFormatSymbols(currentLocale); int selectedAmpm = userData.getAmpm() == null ? -1 : Integer.parseInt(userData.getAmpm()); encodeEmtypAmpmChoice(uiComponent, writer, selectedAmpm); encodeAmpmChoice(symbols, uiComponent, writer, Calendar.AM, selectedAmpm); encodeAmpmChoice(symbols, uiComponent, writer, Calendar.PM, selectedAmpm); // bug #970747: force separate end tag writer.writeText("", null); writer.endElement(HTML.SELECT_ELEM); } protected void encodeEmtypAmpmChoice(UIComponent component, ResponseWriter writer, int selectedAmpm) throws IOException{ writer.startElement(HTML.OPTION_ELEM, component); writer.writeAttribute(HTML.VALUE_ATTR, "-1", null); if(selectedAmpm == -1) writer.writeAttribute(HTML.SELECTED_ATTR, HTML.SELECTED_ATTR, null); writer.writeText(((HtmlInputDate)component).getEmptyAmpmSelection(), null); writer.endElement(HTML.OPTION_ELEM); } protected void encodePopupCalendarButton(FacesContext facesContext, UIComponent uiComponent, ResponseWriter writer, String clientId, Locale currentLocale) throws IOException{ DateFormatSymbols symbols = new DateFormatSymbols(currentLocale); HtmlCalendarRenderer.addScriptAndCSSResources(facesContext,uiComponent); String calendarVar = JavascriptUtils.getValidJavascriptName( uiComponent.getClientId(facesContext)+"CalendarVar",false); String dateFormat = CalendarDateTimeConverter.createJSPopupFormat(facesContext, null); String localizedLanguageScript = HtmlCalendarRenderer.getLocalizedLanguageScript(facesContext, symbols,Calendar.getInstance(currentLocale).getFirstDayOfWeek(), uiComponent,calendarVar); writer.startElement(HTML.SPAN_ELEM,uiComponent); writer.writeAttribute(HTML.ID_ATTR,uiComponent.getClientId(facesContext)+"Span", JSFAttr.ID_ATTR); writer.endElement(HTML.SPAN_ELEM); writer.startElement(HTML.SCRIPT_ELEM,uiComponent); writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null); writer.writeText("var "+calendarVar+"=new org_apache_myfaces_PopupCalendar();\n",null); writer.write(localizedLanguageScript); writer.writeText(calendarVar+".init(document.getElementById('"+ uiComponent.getClientId(facesContext)+"Span"+"'));\n",null); writer.endElement(HTML.SCRIPT_ELEM); HtmlCalendarRenderer.getScriptBtn(writer, facesContext, uiComponent, dateFormat,"...",new FunctionCallProvider(){ public String getFunctionCall(FacesContext facesContext, UIComponent uiComponent, String dateFormat) { String clientId = uiComponent.getClientId(facesContext); String clientVar = JavascriptUtils.getValidJavascriptName(clientId+"CalendarVar",true); return clientVar+"._popUpCalendarForInputDate('"+clientId+"','"+dateFormat+"');"; } }); } public void decode(FacesContext facesContext, UIComponent uiComponent) { RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputDate.class); HtmlInputDate inputDate = (HtmlInputDate) uiComponent; if( isDisabled(facesContext, inputDate) ) // For safety, do not set the submited value if the component is disabled. return; if (null != inputDate.getConverter()) { //Instead of use a custom object to encode data, //we have to encode all info in a String, so the converter //can convert it to a String if the value //is invalid. String clientId = inputDate.getClientId(facesContext); String type = inputDate.getType(); Map requestMap = facesContext.getExternalContext().getRequestParameterMap(); StringBuffer submittedValue = new StringBuffer(); if( ! (type.equals( "time" ) || type.equals( "short_time" )) ) { submittedValue.append("year="); submittedValue.append((String) requestMap.get(clientId + ID_YEAR_POSTFIX) ); submittedValue.append("\n"); submittedValue.append("month="); submittedValue.append((String) requestMap.get(clientId + ID_MONTH_POSTFIX)); submittedValue.append("\n"); submittedValue.append("day="); submittedValue.append((String) requestMap.get(getClientIdForDaySubcomponent(clientId)) ); submittedValue.append("\n"); } if( ! type.equals( "date" ) ) { submittedValue.append("hours="); submittedValue.append((String) requestMap.get(clientId + ID_HOURS_POSTFIX) ); submittedValue.append("\n"); submittedValue.append("minutes="); submittedValue.append((String) requestMap.get(clientId + ID_MINUTES_POSTFIX) ); submittedValue.append("\n"); if (type.equals("full") || type.equals("time")) { submittedValue.append("seconds="); submittedValue.append((String) requestMap.get(clientId + ID_SECONDS_POSTFIX) ); submittedValue.append("\n"); } if (inputDate.isAmpm()) { submittedValue.append("ampm="); submittedValue.append((String) requestMap.get(clientId + ID_AMPM_POSTFIX) ); submittedValue.append("\n"); } } if (submittedValue.charAt(submittedValue.length()-1) == '\n' ) { submittedValue.deleteCharAt(submittedValue.length()-1); } inputDate.setSubmittedValue( submittedValue.toString() ); } else { //Use AbstractHtmlInputDate.UserData to save submitted value Locale currentLocale = facesContext.getViewRoot().getLocale(); UserData userData = (UserData) inputDate.getSubmittedValue(); if( userData == null ) userData = inputDate.getUserData(currentLocale); String clientId = inputDate.getClientId(facesContext); String type = inputDate.getType(); Map requestMap = facesContext.getExternalContext().getRequestParameterMap(); if( ! (type.equals( "time" ) || type.equals( "short_time" )) ){ userData.setDay( (String) requestMap.get(getClientIdForDaySubcomponent(clientId)) ); userData.setMonth( (String) requestMap.get(clientId + ID_MONTH_POSTFIX) ); userData.setYear( (String) requestMap.get(clientId + ID_YEAR_POSTFIX) ); } if( ! type.equals( "date" ) ){ userData.setHours( (String) requestMap.get(clientId + ID_HOURS_POSTFIX) ); userData.setMinutes( (String) requestMap.get(clientId + ID_MINUTES_POSTFIX) ); if (type.equals("full") || type.equals("time")) userData.setSeconds( (String) requestMap.get(clientId + ID_SECONDS_POSTFIX) ); if (inputDate.isAmpm()) { userData.setAmpm( (String) requestMap.get(clientId + ID_AMPM_POSTFIX) ); } } inputDate.setSubmittedValue( userData ); } } private DateBusinessConverter getDateBusinessConverter(AbstractHtmlInputDate component) { DateBusinessConverter dateBusinessConverter = component.getDateBusinessConverter(); if (dateBusinessConverter == null) { dateBusinessConverter = new DefaultDateBusinessConverter(); } return dateBusinessConverter; } public Object getConvertedValue(FacesContext context, UIComponent uiComponent, Object submittedValue) throws ConverterException { HtmlInputDate inputDate = (HtmlInputDate) uiComponent; if (inputDate.getConverter() == null) { UserData userData = (UserData) submittedValue; Date date = null; try { date = userData.parse(); } catch (ParseException e) { Object[] args = {uiComponent.getId()}; throw new ConverterException(MessageUtils.getMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE, FacesMessage.SEVERITY_ERROR, DATE_MESSAGE_ID, args, context)); } return getDateBusinessConverter(inputDate).getBusinessValue(context, inputDate, date); } else { if (submittedValue != null && !(submittedValue instanceof String)) { if (RendererUtils.NOTHING.equals(submittedValue)) { return null; } throw new IllegalArgumentException("Submitted value of type String for component : " + RendererUtils.getPathToComponent(inputDate) + "expected"); } return inputDate.getConverter().getAsObject(context, inputDate, (String) submittedValue); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy