Done. :-)

http://issues.apache.org/jira/browse/MYFACES-569

Bruno Aranda wrote:
Thanks Paul, but could you please open a JIRA issue with the problem
and upload the patch there? Then this will be tested :-) We have to
keep the bugs under control...

Regards,

Bruno

2005/9/15, Paul Klaer <[EMAIL PROTECTED]>:

Hi,

this is definitly a bug. So, here I provide the solution. Can someone
test and commit the files please?

I saw the mail in the dev list from Zhong Li:
---------------
"I found how it happened. I have onload on body tag, even with simplest
one, something like, <body onload="alert('loading');">
...
Then the inputCalendar doesn't work, can't popup. so weired. "
---------------

Since he had the same problem I checked the JavaScript behaviour in
Firefox and debugged a little bit...

This problem occures because the old JavaScript is executed in Firefox
before the body tag "onload" is set during the render phase.
So this variable "var jscalendarOnloadBackup = window.onload;" is only
set to "undefined" and never with the old onload script.

To solve this problem I rewrote the load script as a function in the
"popcalendar.js" and this function is then called just before
"jscalendarSetImageDirectory" is called inside the enclosing "body"
element. At this time the "onload" tag of the "body" element is set.

You can test this if you change the "<body>" element to "<body
onload="alert('test body onload');">" of the "simple/calendar.jsp" example..

Regards,

Paul


Paul Klaer wrote:

Thank you for your tipps and sorry for my late answer. I had much to do
and wanted to check the code before I write something back.
In the meantime we got a new CSS file and the calendar popups are
working fine in IE after resetting some div...

The examples out of the myfaces repository are working on both: Firefox
and IE. There I had no problem with the js script.

I think we have to be careful using css...

But, I have now a problem with Firefox popups to display them and this
is because we use the "onload" tag and some own javascript init
functions for the page.
Now I checked the "popcalendar.js" code and the function
jscalendarInit() is only called if there is no "window.onload" (onload
tag) in the browser specified if no IE is used. This is why the variable
"jscalendarBPageLoaded" still remains with the default value "false" and
Firefox never executes this:

---------
function jscalendarPopUpCalendar(ctl, ctl2, format){
   if (jscalendarBPageLoaded){
   ....
---------

Is this right that I can't use the onload tag using Firefox?


Martin Marinschek wrote:


this occurs with IE only, right?

it's a known bug of the IE - you would need to go through the elements
of the form and render them invisible while displaying the
inputCalendar.

If you prepare a patch for the javaScript of inputCalendar which works
in IE and Firefox we would happily apply it!

regards,

Martin

On 9/9/05, Paul Klaer <[EMAIL PROTECTED]> wrote:


Hi,

I have a problem using the inputCalendar component. The popup window is
shown correctly and works fine but if there are some buttons on my form
the popup window is hidden by the buttons. The popup just appears in the
background.
How can I solve this problem? Using css and the z-index for the buttons
option doesn't solve the problem. How can I set the calendar popup
component to the foreground?
Is it a bug of the inputCalendar component?

Paul






/*
* Copyright 2004 The Apache Software Foundation.
*
* 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 org.apache.myfaces.custom.calendar;

import org.apache.myfaces.component.html.ext.HtmlInputText;
import org.apache.myfaces.component.html.util.AddResource;
import org.apache.myfaces.renderkit.JSFAttr;
import org.apache.myfaces.renderkit.RendererUtils;
import org.apache.myfaces.renderkit.html.HTML;
import org.apache.myfaces.renderkit.html.HtmlRenderer;
import org.apache.myfaces.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.renderkit.html.util.JavascriptUtils;

import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIParameter;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.List;

/**
* @author Martin Marinschek (latest modification by $Author: svieujot $)
* @version $Revision: 239482 $ $Date: 2005-08-24 01:34:01 +0200 (Mi, 24 Aug 
2005) $
*/
public class HtmlCalendarRenderer
       extends HtmlRenderer
{
   private static final String JAVASCRIPT_ENCODED = 
"org.apache.myfaces.calendar.JAVASCRIPT_ENCODED";

   //private static Log log = LogFactory.getLog(HtmlCalendarRenderer.class);

   public void encodeEnd(FacesContext facesContext, UIComponent component)
           throws IOException
   {
       RendererUtils.checkParamValidity(facesContext, component, 
HtmlInputCalendar.class);

       HtmlInputCalendar inputCalendar = (HtmlInputCalendar) component;

       Locale currentLocale = facesContext.getViewRoot().getLocale();


       Date value;

       try
       {
           // value = RendererUtils.getDateValue(inputCalendar);
           Converter converter = getConverter(inputCalendar);
           if (converter instanceof DateConverter)
           {
               value = ((DateConverter) converter).getAsDate(facesContext, 
component);
           }
           else
           {
               value = RendererUtils.getDateValue(inputCalendar);
           }
               }
       catch (IllegalArgumentException illegalArgumentException)
       {
           value = null;
       }


       Calendar timeKeeper = Calendar.getInstance(currentLocale);
       timeKeeper.setTime(value!=null?value:new Date());

       DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);

       String[] weekdays = mapWeekdays(symbols);
       String[] months = mapMonths(symbols);

       if(inputCalendar.isRenderAsPopup())
       {
           if(inputCalendar.isAddResources())
               addScriptAndCSSResources(facesContext, component);

           String dateFormat = 
CalendarDateTimeConverter.createJSPopupFormat(facesContext,
                   inputCalendar.getPopupDateFormat());

           Application application = facesContext.getApplication();

           HtmlInputText inputText = null;

           List li = inputCalendar.getChildren();

           for (int i = 0; i < li.size(); i++)
           {
               UIComponent uiComponent = (UIComponent) li.get(i);

               if(uiComponent instanceof HtmlInputText)
               {
                   inputText = (HtmlInputText) uiComponent;
                   break;
               }
           }

           if(inputText == null)
           {
               inputText = (HtmlInputText) 
application.createComponent(HtmlInputText.COMPONENT_TYPE);
           }

           RendererUtils.copyHtmlInputTextAttributes(inputCalendar, inputText);

           inputText.setConverter(null); // value for this transient component 
will already be converted
           inputText.setTransient(true);

           if (value == null && inputCalendar.getSubmittedValue() != null)
           {
               inputText.setValue(inputCalendar.getSubmittedValue());
           }
           else
           {
               inputText.setValue(getConverter(inputCalendar).getAsString(
                       facesContext,inputCalendar,value));
           }
           inputText.setDisabled(inputCalendar.isDisabled());
           inputText.setReadonly(inputCalendar.isReadonly());
           inputText.setEnabledOnUserRole(inputCalendar.getEnabledOnUserRole());
           inputText.setVisibleOnUserRole(inputCalendar.getVisibleOnUserRole());

           //This is where two components with the same id are in the tree,
           //so make sure that during the rendering the id is unique.

           inputCalendar.setId(inputCalendar.getId()+"tempId");

           inputCalendar.getChildren().add(inputText);

           RendererUtils.renderChild(facesContext, inputText);

           inputCalendar.getChildren().remove(inputText);

           //Set back the correct id to the input calendar
           inputCalendar.setId(inputText.getId());

           if (!inputCalendar.isDisabled())
           {
                   ResponseWriter writer = facesContext.getResponseWriter();

                   writer.startElement(HTML.SCRIPT_ELEM, component);
                   
writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
                   writer.write("<!--\n");
                   writer.writeText(getLocalizedLanguageScript(symbols, months,
                           timeKeeper.getFirstDayOfWeek(),inputCalendar),null);
               writeScriptBtn(facesContext, inputCalendar,
                       dateFormat,inputCalendar.getPopupButtonString());
                   writer.write("\n-->");
                   writer.endElement(HTML.SCRIPT_ELEM);

       /*            writer.startElement(HTML.INPUT_ELEM,null);
                   
writer.writeAttribute(HTML.TYPE_ATTR,HTML.INPUT_TYPE_BUTTON,null);
                   writer.writeAttribute(HTML.ONCLICK_ATTR,"popUpCalendar(this, 
"+inputText.getClientId(facesContext)+
                           ", \\\"dd.mm.yyyy\\\")",null);
                   writer.endElement(HTML.INPUT_TYPE_BUTTON);*/
           }
       }
       else
       {

           int lastDayInMonth = 
timeKeeper.getActualMaximum(Calendar.DAY_OF_MONTH);

           int currentDay = timeKeeper.get(Calendar.DAY_OF_MONTH);

           if (currentDay > lastDayInMonth)
               currentDay = lastDayInMonth;

           timeKeeper.set(Calendar.DAY_OF_MONTH, 1);

           int weekDayOfFirstDayOfMonth = 
mapCalendarDayToCommonDay(timeKeeper.get(Calendar.DAY_OF_WEEK));

           int weekStartsAtDayIndex = 
mapCalendarDayToCommonDay(timeKeeper.getFirstDayOfWeek());

           ResponseWriter writer = facesContext.getResponseWriter();

           HtmlRendererUtils.writePrettyLineSeparator(facesContext);
           HtmlRendererUtils.writePrettyLineSeparator(facesContext);

           writer.startElement(HTML.TABLE_ELEM, component);
           HtmlRendererUtils.renderHTMLAttributes(writer, component, 
HTML.UNIVERSAL_ATTRIBUTES);
           HtmlRendererUtils.renderHTMLAttributes(writer, component, 
HTML.EVENT_HANDLER_ATTRIBUTES);
           writer.flush();

           HtmlRendererUtils.writePrettyLineSeparator(facesContext);

           writer.startElement(HTML.TR_ELEM, component);

           if(inputCalendar.getMonthYearRowClass() != null)
               writer.writeAttribute(HTML.CLASS_ATTR, 
inputCalendar.getMonthYearRowClass(), null);

           writeMonthYearHeader(facesContext, writer, inputCalendar, timeKeeper,
                   currentDay, weekdays, months);

           writer.endElement(HTML.TR_ELEM);

           HtmlRendererUtils.writePrettyLineSeparator(facesContext);

           writer.startElement(HTML.TR_ELEM, component);

           if(inputCalendar.getWeekRowClass() != null)
               writer.writeAttribute(HTML.CLASS_ATTR, 
inputCalendar.getWeekRowClass(), null);

           writeWeekDayNameHeader(weekStartsAtDayIndex, weekdays,
                   facesContext, writer, inputCalendar);

           writer.endElement(HTML.TR_ELEM);

           HtmlRendererUtils.writePrettyLineSeparator(facesContext);

           writeDays(facesContext, writer, inputCalendar, timeKeeper,
                   currentDay, weekStartsAtDayIndex, weekDayOfFirstDayOfMonth,
                   lastDayInMonth, weekdays);

           writer.endElement(HTML.TABLE_ELEM);
       }
   }

   /**
    * Used by the x:inputDate renderer : HTMLDateRenderer
    * @throws IOException
    */
   static public void addScriptAndCSSResources(FacesContext facesContext, 
UIComponent component) throws IOException{
       // check to see if javascript has already been written (which could 
happen if more than one calendar on the same page)
       if 
(facesContext.getExternalContext().getRequestMap().containsKey(JAVASCRIPT_ENCODED))
       {
           return;
       }

       // Add the javascript and CSS pages
       AddResource.addStyleSheet(HtmlCalendarRenderer.class, "WH/theme.css", 
facesContext);
       AddResource.addStyleSheet(HtmlCalendarRenderer.class, "DB/theme.css", 
facesContext);
       AddResource.addJavaScriptToHeader(HtmlCalendarRenderer.class, 
"popcalendar.js", facesContext);

       ResponseWriter writer = facesContext.getResponseWriter();

       writer.startElement(HTML.SCRIPT_ELEM, component);
       writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, 
HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
       writer.write(
               "loadPopupScript();jscalendarSetImageDirectory(\""
                       +JavascriptUtils.encodeString(
                               
AddResource.getResourceMappedPath(HtmlCalendarRenderer.class, "DB/", 
facesContext)
                        )
               +"\")");
       writer.endElement(HTML.SCRIPT_ELEM);

       
facesContext.getExternalContext().getRequestMap().put(JAVASCRIPT_ENCODED, 
Boolean.TRUE);
   }

   public static String getLocalizedLanguageScript(DateFormatSymbols symbols,
           String[] months, int firstDayOfWeek, HtmlInputCalendar inputCalendar)
   {
       int realFirstDayOfWeek = firstDayOfWeek-1/*Java has different 
starting-point*/;

       String[] weekDays;

       if(realFirstDayOfWeek==0)
       {
           weekDays = mapWeekdaysStartingWithSunday(symbols);
       }
       else if(realFirstDayOfWeek==1)
       {
           weekDays = mapWeekdays(symbols);
       }
       else
           throw new IllegalStateException("Week may only start with sunday or 
monday.");

       StringBuffer script = new StringBuffer();
       defineStringArray(script, "jscalendarMonthName", months);
       defineStringArray(script, "jscalendarDayName", weekDays);
       setIntegerVariable(script, "jscalendarStartAt",realFirstDayOfWeek);

       if( inputCalendar != null ){ // To allow null parameter for inputDate 
tag.
               if(inputCalendar.getPopupGotoString()!=null)
                   setStringVariable(script, 
"jscalendarGotoString",inputCalendar.getPopupGotoString());
               if(inputCalendar.getPopupTodayString()!=null)
                   setStringVariable(script, 
"jscalendarTodayString",inputCalendar.getPopupTodayString());
               if(inputCalendar.getPopupWeekString()!=null)
                   setStringVariable(script, 
"jscalendarWeekString",inputCalendar.getPopupWeekString());
               if(inputCalendar.getPopupScrollLeftMessage()!=null)
                   setStringVariable(script, 
"jscalendarScrollLeftMessage",inputCalendar.getPopupScrollLeftMessage());
               if(inputCalendar.getPopupScrollRightMessage()!=null)
                   setStringVariable(script, 
"jscalendarScrollRightMessage",inputCalendar.getPopupScrollRightMessage());
               if(inputCalendar.getPopupSelectMonthMessage()!=null)
                   setStringVariable(script, 
"jscalendarSelectMonthMessage",inputCalendar.getPopupSelectMonthMessage());
               if(inputCalendar.getPopupSelectYearMessage()!=null)
                   setStringVariable(script, 
"jscalendarSelectYearMessage",inputCalendar.getPopupSelectYearMessage());
               if(inputCalendar.getPopupSelectDateMessage()!=null)
                   setStringVariable(script, 
"jscalendarSelectDateMessage",inputCalendar.getPopupSelectDateMessage());
       }

       return script.toString();
   }

   private static void setIntegerVariable(StringBuffer script, String name, int 
value)
   {
       script.append(name);
       script.append(" = ");
       script.append(value);
       script.append(";\n");
   }

   private static void setStringVariable(StringBuffer script, String name, 
String value)
   {
       script.append(name);
       script.append(" = \"");
       script.append(value);
       script.append("\";\n");
   }

   private static void defineStringArray(StringBuffer script, String arrayName, 
String[] array)
   {
       script.append(arrayName);
       script.append(" = new Array(");

       for(int i=0;i<array.length;i++)
       {
           if(i!=0)
               script.append(",");

           script.append("\"");
           script.append(array[i]);
           script.append("\"");
       }

       script.append(");");
   }

   private void writeScriptBtn(FacesContext facesContext, UIComponent 
uiComponent, String dateFormat, String popupButtonString)
       throws IOException
   {
       ResponseWriter writer = facesContext.getResponseWriter();

       HtmlInputCalendar calendar = (HtmlInputCalendar)uiComponent;
       boolean renderButtonAsImage = calendar.isRenderPopupButtonAsImage();

       writer.write("if (!document.layers) {\n");
       writer.write("document.write('");

       if (!renderButtonAsImage) {
           // render the button
           writer.startElement(HTML.INPUT_ELEM, uiComponent);
           writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_BUTTON, null);

           
writeOnclickJsCalendarFunctionCall(facesContext,uiComponent,dateFormat);

           if(popupButtonString==null)
               popupButtonString="...";
           writer.writeAttribute(HTML.VALUE_ATTR, popupButtonString, null);
           /*
           if (renderButtonAsImage) {
               writer.writeAttribute(HTML.ID_ATTR, buttonId, null);
               writer.writeAttribute(HTML.NAME_ATTR, buttonId, null);
               writer.writeAttribute(HTML.STYLE_ATTR, 
"visibility:hidden;",null);
           } else {
               HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, 
HTML.UNIVERSAL_ATTRIBUTES);
           }
           */
           writer.endElement(HTML.INPUT_ELEM);
       } else {
           // render the image
           writer.startElement(HTML.IMG_ELEM, uiComponent);
           writer.writeAttribute(HTML.SRC_ATTR, 
AddResource.getResourceMappedPath(HtmlCalendarRenderer.class, 
"images/calendar.gif", facesContext), null);
           writer.writeAttribute(HTML.STYLE_ATTR, "vertical-align:bottom;", 
null);

           //writer.writeAttribute(HTML.ONCLICK_ATTR, 
"document.getElementById(\\'"+buttonId+"\\').click()",null);
           
writeOnclickJsCalendarFunctionCall(facesContext,uiComponent,dateFormat);
           //writer.writeAttribute(HTML.ONMOUSEOVER_ATTR, 
"this.style.cursor=\\'hand\\';", null);
           //writer.writeAttribute(HTML.ONMOUSEOUT_ATTR, 
"this.style.cursor=\\'default\\';", null);

           writer.endElement(HTML.IMG_ELEM);
       }

       writer.write("');");
       writer.write("\n}");
   }

   private void writeOnclickJsCalendarFunctionCall(FacesContext facesContext, 
UIComponent uiComponent, String dateFormat)
       throws IOException
   {
       String clientId = uiComponent.getClientId(facesContext);

       ResponseWriter writer = facesContext.getResponseWriter();

       String jsCalendarFunctionCall = 
"jscalendarPopUpCalendar(this,document.getElementById(\\'"+clientId+"\\'),\\'"+dateFormat+"\\')";
       writer.writeAttribute(HTML.ONCLICK_ATTR, jsCalendarFunctionCall, null);
   }


   private void writeMonthYearHeader(FacesContext facesContext, ResponseWriter 
writer, UIInput inputComponent, Calendar timeKeeper,
                                     int currentDay, String[] weekdays,
                                     String[] months)
           throws IOException
   {
       Calendar cal = shiftMonth(facesContext, timeKeeper, currentDay, -1);

       writeCell(facesContext, writer, inputComponent, "<", cal.getTime(), 
null);

       writer.startElement(HTML.TD_ELEM, inputComponent);
       writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(weekdays.length - 
2), null);
       writer.writeText(months[timeKeeper.get(Calendar.MONTH)] + " " + 
timeKeeper.get(Calendar.YEAR), null);
       writer.endElement(HTML.TD_ELEM);

       cal = shiftMonth(facesContext, timeKeeper, currentDay, 1);

       writeCell(facesContext, writer, inputComponent, ">", cal.getTime(), 
null);
   }

   private Calendar shiftMonth(FacesContext facesContext,
                               Calendar timeKeeper, int currentDay, int shift)
   {
       Calendar cal = copyCalendar(facesContext, timeKeeper);

       cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + shift);

       if(currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH))
           currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

       cal.set(Calendar.DAY_OF_MONTH, currentDay);
       return cal;
   }

   private Calendar copyCalendar(FacesContext facesContext, Calendar timeKeeper)
   {
       Calendar cal = 
Calendar.getInstance(facesContext.getViewRoot().getLocale());
       cal.set(Calendar.YEAR, timeKeeper.get(Calendar.YEAR));
       cal.set(Calendar.MONTH, timeKeeper.get(Calendar.MONTH));
       cal.set(Calendar.HOUR_OF_DAY, timeKeeper.get(Calendar.HOUR_OF_DAY));
       cal.set(Calendar.MINUTE, timeKeeper.get(Calendar.MINUTE));
       cal.set(Calendar.SECOND, timeKeeper.get(Calendar.SECOND));
       cal.set(Calendar.MILLISECOND, timeKeeper.get(Calendar.MILLISECOND));
       return cal;
   }

   private void writeWeekDayNameHeader(int weekStartsAtDayIndex, String[] 
weekdays, FacesContext facesContext, ResponseWriter writer, UIInput 
inputComponent)
           throws IOException
   {
       for (int i = weekStartsAtDayIndex; i < weekdays.length; i++)
           writeCell(facesContext,
                   writer, inputComponent, weekdays[i], null, null);

       for (int i = 0; i < weekStartsAtDayIndex; i++)
           writeCell(facesContext, writer,
                   inputComponent, weekdays[i], null, null);
   }

   private void writeDays(FacesContext facesContext, ResponseWriter writer,
                          HtmlInputCalendar inputComponent, Calendar 
timeKeeper, int currentDay, int weekStartsAtDayIndex,
                          int weekDayOfFirstDayOfMonth, int lastDayInMonth, 
String[] weekdays)
           throws IOException
   {
       Calendar cal;

       int space = (weekStartsAtDayIndex < weekDayOfFirstDayOfMonth) ? 
(weekDayOfFirstDayOfMonth - weekStartsAtDayIndex)
               : (weekdays.length - weekStartsAtDayIndex + 
weekDayOfFirstDayOfMonth);

       if (space == weekdays.length)
           space = 0;

       int columnIndexCounter = 0;

       for (int i = 0; i < space; i++)
       {
           if (columnIndexCounter == 0)
           {
               writer.startElement(HTML.TR_ELEM, inputComponent);
           }

           writeCell(facesContext, writer, inputComponent, "",
                   null, inputComponent.getDayCellClass());
           columnIndexCounter++;
       }

       for (int i = 0; i < lastDayInMonth; i++)
       {
           if (columnIndexCounter == 0)
           {
               writer.startElement(HTML.TR_ELEM, inputComponent);
           }

           cal = copyCalendar(facesContext, timeKeeper);
           cal.set(Calendar.DAY_OF_MONTH, i + 1);

           String cellStyle = inputComponent.getDayCellClass();

           if((currentDay - 1) == i)
               cellStyle = inputComponent.getCurrentDayCellClass();

           writeCell(facesContext, writer,
                   inputComponent, String.valueOf(i + 1), cal.getTime(),
                   cellStyle);

           columnIndexCounter++;

           if (columnIndexCounter == weekdays.length)
           {
               writer.endElement(HTML.TR_ELEM);
               HtmlRendererUtils.writePrettyLineSeparator(facesContext);
               columnIndexCounter = 0;
           }
       }

       if (columnIndexCounter != 0)
       {
           for (int i = columnIndexCounter; i < weekdays.length; i++)
           {
               writeCell(facesContext, writer,
                       inputComponent, "", null, 
inputComponent.getDayCellClass());
           }

           writer.endElement(HTML.TR_ELEM);
           HtmlRendererUtils.writePrettyLineSeparator(facesContext);
       }
   }

   private void writeCell(FacesContext facesContext,
                          ResponseWriter writer, UIInput component, String 
content,
                          Date valueForLink, String styleClass)
           throws IOException
   {
       writer.startElement(HTML.TD_ELEM, component);

       if (styleClass != null)
           writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);

       if (valueForLink == null)
           writer.writeText(content, JSFAttr.VALUE_ATTR);
       else
       {
           writeLink(content, component, facesContext, valueForLink);
       }

       writer.endElement(HTML.TD_ELEM);
   }

   private void writeLink(String content,
                          UIInput component,
                          FacesContext facesContext,
                          Date valueForLink)
           throws IOException
   {
       Converter converter = getConverter(component);

       Application application = facesContext.getApplication();
       HtmlCommandLink link
               = 
(HtmlCommandLink)application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
       link.setId(component.getId() + "_" + valueForLink.getTime() + "_link");
       link.setTransient(true);
       link.setImmediate(component.isImmediate());

       HtmlOutputText text
               = 
(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
       text.setValue(content);
       text.setId(component.getId() + "_" + valueForLink.getTime() + "_text");
       text.setTransient(true);

       UIParameter parameter
               = 
(UIParameter)application.createComponent(UIParameter.COMPONENT_TYPE);
       parameter.setId(component.getId() + "_" + valueForLink.getTime() + 
"_param");
       parameter.setTransient(true);
       parameter.setName(component.getClientId(facesContext));
       parameter.setValue(converter.getAsString(facesContext, component, 
valueForLink));

       HtmlInputCalendar calendar = (HtmlInputCalendar)component;
       if (calendar.isDisabled() || calendar.isReadonly())
       {
               component.getChildren().add(text);

               RendererUtils.renderChild(facesContext, text);
       }
       else
       {
               component.getChildren().add(link);
           link.getChildren().add(parameter);
           link.getChildren().add(text);

           RendererUtils.renderChild(facesContext, link);
       }
   }

   private Converter getConverter(UIInput component)
   {
       Converter converter = component.getConverter();

       if (converter == null)
       {
           converter = new CalendarDateTimeConverter();
       }
       return converter;
   }

   private int mapCalendarDayToCommonDay(int day)
   {
       switch (day)
       {
           case Calendar.TUESDAY:
               return 1;
           case Calendar.WEDNESDAY:
               return 2;
           case Calendar.THURSDAY:
               return 3;
           case Calendar.FRIDAY:
               return 4;
           case Calendar.SATURDAY:
               return 5;
           case Calendar.SUNDAY:
               return 6;
           default:
               return 0;
       }
   }

   private static String[] mapWeekdays(DateFormatSymbols symbols)
   {
       String[] weekdays = new String[7];

       String[] localeWeekdays = symbols.getShortWeekdays();

       weekdays[0] = localeWeekdays[Calendar.MONDAY];
       weekdays[1] = localeWeekdays[Calendar.TUESDAY];
       weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
       weekdays[3] = localeWeekdays[Calendar.THURSDAY];
       weekdays[4] = localeWeekdays[Calendar.FRIDAY];
       weekdays[5] = localeWeekdays[Calendar.SATURDAY];
       weekdays[6] = localeWeekdays[Calendar.SUNDAY];

       return weekdays;
   }

   private static String[] mapWeekdaysStartingWithSunday(DateFormatSymbols 
symbols)
   {
       String[] weekdays = new String[7];

       String[] localeWeekdays = symbols.getShortWeekdays();

       weekdays[0] = localeWeekdays[Calendar.SUNDAY];
       weekdays[1] = localeWeekdays[Calendar.MONDAY];
       weekdays[2] = localeWeekdays[Calendar.TUESDAY];
       weekdays[3] = localeWeekdays[Calendar.WEDNESDAY];
       weekdays[4] = localeWeekdays[Calendar.THURSDAY];
       weekdays[5] = localeWeekdays[Calendar.FRIDAY];
       weekdays[6] = localeWeekdays[Calendar.SATURDAY];

       return weekdays;
   }

   public static String[] mapMonths(DateFormatSymbols symbols)
   {
       String[] months = new String[12];

       String[] localeMonths = symbols.getMonths();

       months[0] = localeMonths[Calendar.JANUARY];
       months[1] = localeMonths[Calendar.FEBRUARY];
       months[2] = localeMonths[Calendar.MARCH];
       months[3] = localeMonths[Calendar.APRIL];
       months[4] = localeMonths[Calendar.MAY];
       months[5] = localeMonths[Calendar.JUNE];
       months[6] = localeMonths[Calendar.JULY];
       months[7] = localeMonths[Calendar.AUGUST];
       months[8] = localeMonths[Calendar.SEPTEMBER];
       months[9] = localeMonths[Calendar.OCTOBER];
       months[10] = localeMonths[Calendar.NOVEMBER];
       months[11] = localeMonths[Calendar.DECEMBER];

       return months;
   }


   public void decode(FacesContext facesContext, UIComponent component)
   {
       RendererUtils.checkParamValidity(facesContext, component, 
HtmlInputCalendar.class);

       HtmlRendererUtils.decodeUIInput(facesContext, component);
   }

   public Object getConvertedValue(FacesContext facesContext, UIComponent 
uiComponent, Object submittedValue) throws ConverterException
   {
       RendererUtils.checkParamValidity(facesContext, uiComponent, 
HtmlInputCalendar.class);

       UIInput uiInput = (UIInput) uiComponent;

       Converter converter = uiInput.getConverter();

       if(converter==null)
           converter = new CalendarDateTimeConverter();

       if (submittedValue != null && !(submittedValue instanceof String))
       {
           throw new IllegalArgumentException("Submitted value of type String 
expected");
       }

       return converter.getAsObject(facesContext, uiComponent, (String) 
submittedValue);
   }

   public interface DateConverter extends Converter
   {
       public Date getAsDate(FacesContext facesContext, UIComponent 
uiComponent);
   }

       public static class CalendarDateTimeConverter implements DateConverter
   {

       public Object getAsObject(FacesContext facesContext, UIComponent 
uiComponent, String s)
       {
           if(s==null || s.trim().length()==0)
               return null;

           DateFormat dateFormat = null;

           if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) 
uiComponent).isRenderAsPopup())
           {
               String popupDateFormat = ((HtmlInputCalendar) 
uiComponent).getPopupDateFormat();

               dateFormat = new 
SimpleDateFormat(createJSPopupFormat(facesContext, popupDateFormat));
           }
           else
           {
               dateFormat = createStandardDateFormat(facesContext);
           }

           try
           {
               return dateFormat.parse(s);
           }
           catch (ParseException e)
           {
               throw new ConverterException(e);
           }
       }

       public Date getAsDate(FacesContext facesContext, UIComponent uiComponent)
       {
           return RendererUtils.getDateValue(uiComponent);
       }

               public static String createJSPopupFormat(FacesContext 
facesContext, String popupDateFormat)
       {

           if(popupDateFormat == null)
           {
               SimpleDateFormat defaultDateFormat = 
createStandardDateFormat(facesContext);
               popupDateFormat = defaultDateFormat.toPattern();
           }

           StringBuffer jsPopupDateFormat = new StringBuffer();

           for(int i=0;i<popupDateFormat.length();i++)
           {
               char c = popupDateFormat.charAt(i);

               if(c=='M' || c=='d' || c=='y' || c==' ' || c=='.' || c=='/' || 
c=='-')
                   jsPopupDateFormat.append(c);
           }
           return jsPopupDateFormat.toString().trim();
       }

       public String getAsString(FacesContext facesContext, UIComponent 
uiComponent, Object o)
       {
           Date date = (Date) o;

           if(date==null)
               return null;

           DateFormat dateFormat = null;

           if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) 
uiComponent).isRenderAsPopup())
           {
               String popupDateFormat = ((HtmlInputCalendar) 
uiComponent).getPopupDateFormat();

               dateFormat = new 
SimpleDateFormat(createJSPopupFormat(facesContext, popupDateFormat));
           }
           else
           {
               dateFormat = createStandardDateFormat(facesContext);
           }

           return dateFormat.format(date);
       }

       private static SimpleDateFormat createStandardDateFormat(FacesContext 
facesContext)
       {
           DateFormat dateFormat;
           dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, 
DateFormat.SHORT,
                   facesContext.getViewRoot().getLocale());

           if(dateFormat instanceof SimpleDateFormat)
               return (SimpleDateFormat) dateFormat;
           else
               return new SimpleDateFormat("dd.MM.yyyy");
       }

   }
}





Reply via email to