001    package org.apache.myfaces.tobago.component;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ALT;
021    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_CALENDAR_DATE_INPUT_ID;
022    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_COLUMNS;
023    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LABEL;
024    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_POPUP_RESET;
025    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ROWS;
026    import static org.apache.myfaces.tobago.TobagoConstants.FACET_LAYOUT;
027    import static org.apache.myfaces.tobago.TobagoConstants.FACET_PICKER_POPUP;
028    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_BOX;
029    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_BUTTON;
030    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_CALENDAR;
031    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_GRID_LAYOUT;
032    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_HIDDEN;
033    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_IMAGE;
034    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_PANEL;
035    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_POPUP;
036    import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_TIME;
037    import org.apache.myfaces.tobago.context.ResourceManagerUtil;
038    import org.apache.myfaces.tobago.event.DatePickerController;
039    import org.apache.myfaces.tobago.renderkit.html.StyleClasses;
040    
041    import javax.faces.component.UIComponent;
042    import javax.faces.component.UIGraphic;
043    import javax.faces.context.FacesContext;
044    import javax.faces.event.FacesEvent;
045    import java.util.Map;
046    
047    /*
048     * Created by IntelliJ IDEA.
049     * User: bommel
050     * Date: 30.05.2006
051     * Time: 19:22:40
052     */
053    public class UIDatePicker extends UILinkCommand implements OnComponentCreated {
054    
055      public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.DatePicker";
056    
057      private String forComponent;
058    
059      public Object saveState(FacesContext context) {
060        Object[] values = new Object[2];
061        values[0] = super.saveState(context);
062        values[1] = forComponent;
063        return values;
064      }
065    
066      public void restoreState(FacesContext context, Object savedState) {
067        Object[] values = (Object[]) savedState;
068        super.restoreState(context, values[0]);
069        forComponent = (String) values[1];
070      }
071    
072      private UIComponent getUIDateInput(UIComponent parent) {
073        for (Object object : parent.getChildren()) {
074          UIComponent child = (UIComponent) object;
075          if (child instanceof UIDateInput) {
076            return child;
077          }
078        }
079        return null;
080      }
081    
082      public String getFor() {
083        if ("@auto".equals(forComponent)) {
084          UIComponent component = getUIDateInput(getParent());
085          if (component == null && getParent() instanceof UIForm) {
086            component = getUIDateInput(getParent().getParent());
087          }
088          if (component != null) {
089            return component.getId();
090          }
091        }
092        return forComponent;
093      }
094    
095      public UIComponent getForComponent() {
096        if ("@auto".equals(forComponent)) {
097          UIComponent component = getUIDateInput(getParent());
098          if (component == null && getParent() instanceof UIForm) {
099            component = getUIDateInput(getParent().getParent());
100          }
101          return component;
102        } else {
103          return findComponent(forComponent);
104        }
105      }
106    
107      public void setFor(String forComponent) {
108        this.forComponent = forComponent;
109      }
110    
111      public void broadcast(FacesEvent facesEvent) {
112        FacesContext facesContext = FacesContext.getCurrentInstance();
113        UIPopup popup = (UIPopup) getFacets().get(FACET_PICKER_POPUP);
114        String clientId = getForComponent().getClientId(facesContext);
115        UIComponent box = popup.findComponent("box");
116        UIComponent calendar = box.findComponent("calendar");
117        calendar.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId);
118        UIComponent time = box.findComponent("time");
119        if (time != null) {
120          time.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId);
121        }
122        super.broadcast(facesEvent);
123      }
124    
125      public void onComponentCreated() {
126        preparePicker(this);
127      }
128    
129      public void preparePicker(UIDatePicker link) {
130        FacesContext facesContext = FacesContext.getCurrentInstance();
131    
132        if (forComponent == null) {
133          link.setFor("@auto");
134        }
135        link.setImmediate(true);
136    
137        UIHiddenInput hidden =
138            (UIHiddenInput) ComponentUtil.createComponent(facesContext,
139                UIHiddenInput.COMPONENT_TYPE, RENDERER_TYPE_HIDDEN);
140        link.getChildren().add(hidden);
141    
142        // create popup
143        final UIPopup popup =
144            (UIPopup) ComponentUtil.createComponent(facesContext, UIPopup.COMPONENT_TYPE,
145                RENDERER_TYPE_POPUP);
146        //popup.setId(link.getId() + "popup");
147        link.getFacets().put(FACET_PICKER_POPUP, popup);
148    
149        popup.setRendered(false);
150    
151        Map<String, Object> attributes = popup.getAttributes();
152        attributes.put(ATTR_POPUP_RESET, Boolean.TRUE);
153        //int popupHeight = ThemeConfig.getValue(facesContext, link, "CalendarPopupHeight");
154        //attributes.put(ATTR_HEIGHT, String.valueOf(popupHeight));
155        final UIComponent box = ComponentUtil.createComponent(
156            facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_BOX);
157        popup.getChildren().add(box);
158        box.setId("box");
159        // TODO: set string resources in renderer
160        box.getAttributes().put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull(
161            facesContext, "tobago", "datePickerTitle"));
162        UIComponent layout = ComponentUtil.createComponent(
163            facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT);
164        box.getFacets().put(FACET_LAYOUT, layout);
165        layout.setId("layout");
166        layout.getAttributes().put(ATTR_ROWS, "*;fixed;fixed");
167    //    layout.getAttributes().put(TobagoConstants.ATTR_BORDER, "1");
168    
169        final UIComponent calendar = ComponentUtil.createComponent(
170            facesContext, javax.faces.component.UIOutput.COMPONENT_TYPE,
171            RENDERER_TYPE_CALENDAR);
172    
173        calendar.setId("calendar");
174        box.getChildren().add(calendar);
175    
176        // add time input
177        final UIComponent timePanel = ComponentUtil.createComponent(
178            facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL);
179        timePanel.setId("timePanel");
180        box.getChildren().add(timePanel);
181        layout = ComponentUtil.createComponent(
182            facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT);
183        timePanel.getFacets().put(FACET_LAYOUT, layout);
184        layout.setId("timePanelLayout");
185        layout.getAttributes().put(ATTR_COLUMNS, "1*;fixed;1*");
186        UIComponent cell = ComponentUtil.createComponent(
187            facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL);
188        cell.setId("cell1");
189        timePanel.getChildren().add(cell);
190    
191        final UIComponent time = ComponentUtil.createComponent(
192            facesContext,
193            org.apache.myfaces.tobago.component.UIInput.COMPONENT_TYPE,
194            RENDERER_TYPE_TIME);
195        timePanel.getChildren().add(time);
196        time.setId("time");
197    
198        cell = ComponentUtil.createComponent(
199            facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL);
200        cell.setId("cell2");
201        timePanel.getChildren().add(cell);
202    
203        
204    
205        UIComponent buttonPanel = ComponentUtil.createComponent(
206            facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL);
207        buttonPanel.setId("buttonPanel");
208        layout = ComponentUtil.createComponent(
209            facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT);
210        buttonPanel.getFacets().put(FACET_LAYOUT, layout);
211        layout.getAttributes().put(ATTR_COLUMNS, "*;*");
212    //    layout.getAttributes().put(TobagoConstants.ATTR_BORDER, "1");
213    
214        box.getChildren().add(buttonPanel);
215    
216        final UICommand okButton =
217            (UICommand) ComponentUtil.createComponent(facesContext,
218                org.apache.myfaces.tobago.component.UIButtonCommand.COMPONENT_TYPE,
219                RENDERER_TYPE_BUTTON);
220        buttonPanel.getChildren().add(okButton);
221        okButton.setId("ok" + DatePickerController.CLOSE_POPUP);
222        attributes = okButton.getAttributes();
223        attributes.put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull(
224            facesContext, "tobago", "datePickerOk"));
225    
226        final UICommand cancelButton =
227            (UICommand) ComponentUtil.createComponent(facesContext,
228                org.apache.myfaces.tobago.component.UIButtonCommand.COMPONENT_TYPE,
229                RENDERER_TYPE_BUTTON);
230        buttonPanel.getChildren().add(cancelButton);
231        attributes = cancelButton.getAttributes();
232        attributes.put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull(
233            facesContext, "tobago", "datePickerCancel"));
234        cancelButton.setId(DatePickerController.CLOSE_POPUP);
235    
236        // create image
237        UIGraphic image = (UIGraphic) ComponentUtil.createComponent(
238            facesContext, UIGraphic.COMPONENT_TYPE, RENDERER_TYPE_IMAGE);
239        image.setRendered(true);
240        image.setValue("image/date.gif");
241        image.getAttributes().put(ATTR_ALT, ""); //TODO: i18n
242        StyleClasses.ensureStyleClasses(image).addFullQualifiedClass("tobago-input-picker"); // XXX not a standard name
243        link.getChildren().add(image);
244      }
245    
246    }