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 org.apache.myfaces.tobago.TobagoConstants; 021 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ALT; 022 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_CALENDAR_DATE_INPUT_ID; 023 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_COLUMNS; 024 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LABEL; 025 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_POPUP_RESET; 026 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ROWS; 027 import static org.apache.myfaces.tobago.TobagoConstants.FACET_LAYOUT; 028 import static org.apache.myfaces.tobago.TobagoConstants.FACET_PICKER_POPUP; 029 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_BOX; 030 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_BUTTON; 031 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_CALENDAR; 032 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_GRID_LAYOUT; 033 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_HIDDEN; 034 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_IMAGE; 035 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_PANEL; 036 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_POPUP; 037 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_TIME; 038 import org.apache.myfaces.tobago.context.ResourceManagerUtil; 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 * Date: 30.05.2006 049 * Time: 19:22:40 050 */ 051 public class UIDatePicker extends UILinkCommand implements OnComponentCreated { 052 053 public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.DatePicker"; 054 055 public static final String OPEN_POPUP = "openPopup"; 056 public static final String CLOSE_POPUP = "closePopup"; 057 058 private String forComponent; 059 060 public Object saveState(FacesContext context) { 061 Object[] values = new Object[2]; 062 values[0] = super.saveState(context); 063 values[1] = forComponent; 064 return values; 065 } 066 067 public void restoreState(FacesContext context, Object savedState) { 068 Object[] values = (Object[]) savedState; 069 super.restoreState(context, values[0]); 070 forComponent = (String) values[1]; 071 } 072 073 private UIComponent getUIDateInput(UIComponent parent) { 074 for (Object object : parent.getChildren()) { 075 UIComponent child = (UIComponent) object; 076 if (child instanceof UIDateInput) { 077 return child; 078 } 079 } 080 return null; 081 } 082 083 public String getFor() { 084 if ("@auto".equals(forComponent)) { 085 UIComponent component = getUIDateInput(getParent()); 086 if (component == null && getParent() instanceof UIForm) { 087 component = getUIDateInput(getParent().getParent()); 088 } 089 if (component != null) { 090 return component.getId(); 091 } 092 } 093 return forComponent; 094 } 095 096 public UIComponent getForComponent() { 097 if ("@auto".equals(forComponent)) { 098 UIComponent component = getUIDateInput(getParent()); 099 if (component == null && getParent() instanceof UIForm) { 100 component = getUIDateInput(getParent().getParent()); 101 } 102 return component; 103 } else { 104 return findComponent(forComponent); 105 } 106 } 107 108 public void setFor(String forComponent) { 109 this.forComponent = forComponent; 110 } 111 112 public void broadcast(FacesEvent facesEvent) { 113 FacesContext facesContext = FacesContext.getCurrentInstance(); 114 UIPopup popup = (UIPopup) getFacets().get(FACET_PICKER_POPUP); 115 String clientId = getForComponent().getClientId(facesContext); 116 UIComponent box = popup.findComponent("box"); 117 UIComponent calendar = box.findComponent("calendar"); 118 calendar.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId); 119 UIComponent time = box.findComponent("time"); 120 if (time != null) { 121 time.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId); 122 } 123 super.broadcast(facesEvent); 124 } 125 126 public void onComponentCreated() { 127 preparePicker(this); 128 } 129 130 public void preparePicker(UIDatePicker link) { 131 FacesContext facesContext = FacesContext.getCurrentInstance(); 132 133 if (forComponent == null) { 134 link.setFor("@auto"); 135 } 136 link.setImmediate(true); 137 String linkId = link.getId(); 138 javax.faces.component.UIViewRoot viewRoot = facesContext.getViewRoot(); 139 UIHiddenInput hidden = 140 (UIHiddenInput) ComponentUtil.createComponent(facesContext, 141 UIHiddenInput.COMPONENT_TYPE, RENDERER_TYPE_HIDDEN, 142 (linkId != null ? linkId + "hidden" : viewRoot.createUniqueId())); 143 link.getChildren().add(hidden); 144 145 // create popup 146 final UIPopup popup = 147 (UIPopup) ComponentUtil.createComponent(facesContext, UIPopup.COMPONENT_TYPE, 148 RENDERER_TYPE_POPUP, (linkId != null ? linkId + "popup" : viewRoot.createUniqueId())); 149 popup.getAttributes().put(TobagoConstants.ATTR_ZINDEX, 10); 150 151 link.getFacets().put(FACET_PICKER_POPUP, popup); 152 153 popup.setRendered(false); 154 155 Map<String, Object> attributes = popup.getAttributes(); 156 attributes.put(ATTR_POPUP_RESET, Boolean.TRUE); 157 //int popupHeight = ThemeConfig.getValue(facesContext, link, "CalendarPopupHeight"); 158 //attributes.put(ATTR_HEIGHT, String.valueOf(popupHeight)); 159 final UIComponent box = ComponentUtil.createComponent( 160 facesContext, UIBox.COMPONENT_TYPE, RENDERER_TYPE_BOX); 161 popup.getChildren().add(box); 162 box.setId("box"); 163 // TODO: set string resources in renderer 164 box.getAttributes().put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull( 165 facesContext, "tobago", "datePickerTitle")); 166 UIComponent layout = ComponentUtil.createComponent( 167 facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT, "layout"); 168 box.getFacets().put(FACET_LAYOUT, layout); 169 layout.getAttributes().put(ATTR_ROWS, "*;fixed;fixed"); 170 // layout.getAttributes().put(TobagoConstants.ATTR_BORDER, "1"); 171 172 final UIComponent calendar = ComponentUtil.createComponent( 173 facesContext, javax.faces.component.UIOutput.COMPONENT_TYPE, 174 RENDERER_TYPE_CALENDAR, "calendar"); 175 box.getChildren().add(calendar); 176 177 // add time input 178 final UIComponent timePanel = ComponentUtil.createComponent( 179 facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL, "timePanel"); 180 box.getChildren().add(timePanel); 181 layout = ComponentUtil.createComponent( 182 facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT, "timePanelLayout"); 183 timePanel.getFacets().put(FACET_LAYOUT, layout); 184 layout.getAttributes().put(ATTR_COLUMNS, "1*;fixed;1*"); 185 UIComponent cell = ComponentUtil.createComponent( 186 facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL, "cell1"); 187 timePanel.getChildren().add(cell); 188 189 final UIComponent time = ComponentUtil.createComponent( 190 facesContext, 191 org.apache.myfaces.tobago.component.UITimeInput.COMPONENT_TYPE, 192 RENDERER_TYPE_TIME, "time"); 193 timePanel.getChildren().add(time); 194 195 cell = ComponentUtil.createComponent( 196 facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL, "cell2"); 197 timePanel.getChildren().add(cell); 198 199 200 UIComponent buttonPanel = ComponentUtil.createComponent( 201 facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL, "buttonPanel"); 202 layout = ComponentUtil.createComponent( 203 facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT, "buttonPanelLayout"); 204 buttonPanel.getFacets().put(FACET_LAYOUT, layout); 205 layout.getAttributes().put(ATTR_COLUMNS, "*;*"); 206 // layout.getAttributes().put(TobagoConstants.ATTR_BORDER, "1"); 207 208 box.getChildren().add(buttonPanel); 209 210 final UICommand okButton = 211 (UICommand) ComponentUtil.createComponent(facesContext, 212 org.apache.myfaces.tobago.component.UIButtonCommand.COMPONENT_TYPE, 213 RENDERER_TYPE_BUTTON, "ok" + CLOSE_POPUP); 214 buttonPanel.getChildren().add(okButton); 215 attributes = okButton.getAttributes(); 216 attributes.put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull( 217 facesContext, "tobago", "datePickerOk")); 218 219 final UICommand cancelButton = 220 (UICommand) ComponentUtil.createComponent(facesContext, 221 org.apache.myfaces.tobago.component.UIButtonCommand.COMPONENT_TYPE, 222 RENDERER_TYPE_BUTTON, CLOSE_POPUP); 223 buttonPanel.getChildren().add(cancelButton); 224 attributes = cancelButton.getAttributes(); 225 attributes.put(ATTR_LABEL, ResourceManagerUtil.getPropertyNotNull( 226 facesContext, "tobago", "datePickerCancel")); 227 228 // create image 229 UIGraphic image = (UIGraphic) ComponentUtil.createComponent( 230 facesContext, UIGraphic.COMPONENT_TYPE, RENDERER_TYPE_IMAGE, 231 (linkId != null ? linkId + "image" : viewRoot.createUniqueId())); 232 image.setRendered(true); 233 image.setValue("image/date.gif"); 234 image.getAttributes().put(ATTR_ALT, ""); //TODO: i18n 235 StyleClasses.ensureStyleClasses(image).addFullQualifiedClass("tobago-input-picker"); // XXX not a standard name 236 link.getChildren().add(image); 237 } 238 239 }