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