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 * 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 private String forComponent; 056 057 public Object saveState(FacesContext context) { 058 Object[] values = new Object[2]; 059 values[0] = super.saveState(context); 060 values[1] = forComponent; 061 return values; 062 } 063 064 public void restoreState(FacesContext context, Object savedState) { 065 Object[] values = (Object[]) savedState; 066 super.restoreState(context, values[0]); 067 forComponent = (String) values[1]; 068 } 069 070 private UIComponent getUIDateInput(UIComponent parent) { 071 for (Object object : parent.getChildren()) { 072 UIComponent child = (UIComponent) object; 073 if (child instanceof UIDateInput) { 074 return child; 075 } 076 } 077 return null; 078 } 079 080 public String getFor() { 081 if ("@auto".equals(forComponent)) { 082 UIComponent component = getUIDateInput(getParent()); 083 if (component == null && getParent() instanceof UIForm) { 084 component = getUIDateInput(getParent().getParent()); 085 } 086 if (component != null) { 087 return component.getId(); 088 } 089 } 090 return forComponent; 091 } 092 093 public UIComponent getForComponent() { 094 if ("@auto".equals(forComponent)) { 095 UIComponent component = getUIDateInput(getParent()); 096 if (component == null && getParent() instanceof UIForm) { 097 component = getUIDateInput(getParent().getParent()); 098 } 099 return component; 100 } else { 101 return findComponent(forComponent); 102 } 103 } 104 105 public void setFor(String forComponent) { 106 this.forComponent = forComponent; 107 } 108 109 public void broadcast(FacesEvent facesEvent) { 110 FacesContext facesContext = FacesContext.getCurrentInstance(); 111 UIPopup popup = (UIPopup) getFacets().get(FACET_PICKER_POPUP); 112 String clientId = getForComponent().getClientId(facesContext); 113 UIComponent box = popup.findComponent("box"); 114 UIComponent calendar = box.findComponent("calendar"); 115 calendar.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId); 116 UIComponent time = box.findComponent("time"); 117 if (time != null) { 118 time.getAttributes().put(ATTR_CALENDAR_DATE_INPUT_ID, clientId); 119 } 120 super.broadcast(facesEvent); 121 } 122 123 public void onComponentCreated() { 124 preparePicker(this); 125 } 126 127 public void preparePicker(UIDatePicker link) { 128 FacesContext facesContext = FacesContext.getCurrentInstance(); 129 130 if (forComponent == null) { 131 link.setFor("@auto"); 132 } 133 link.setImmediate(true); 134 135 UIHiddenInput hidden = 136 (UIHiddenInput) ComponentUtil.createComponent(facesContext, 137 UIHiddenInput.COMPONENT_TYPE, RENDERER_TYPE_HIDDEN); 138 hidden.setId(facesContext.getViewRoot().createUniqueId()); 139 link.getChildren().add(hidden); 140 141 // create popup 142 final UIPopup popup = 143 (UIPopup) ComponentUtil.createComponent(facesContext, UIPopup.COMPONENT_TYPE, 144 RENDERER_TYPE_POPUP); 145 146 popup.setId(facesContext.getViewRoot().createUniqueId()); 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, UIBox.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.UITimeInput.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 UIComponent buttonPanel = ComponentUtil.createComponent( 205 facesContext, UIPanel.COMPONENT_TYPE, RENDERER_TYPE_PANEL); 206 buttonPanel.setId("buttonPanel"); 207 layout = ComponentUtil.createComponent( 208 facesContext, UIGridLayout.COMPONENT_TYPE, RENDERER_TYPE_GRID_LAYOUT); 209 layout.setId("buttonPanelLayout"); 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.setId(facesContext.getViewRoot().createUniqueId()); 241 image.setValue("image/date.gif"); 242 image.getAttributes().put(ATTR_ALT, ""); //TODO: i18n 243 StyleClasses.ensureStyleClasses(image).addFullQualifiedClass("tobago-input-picker"); // XXX not a standard name 244 link.getChildren().add(image); 245 } 246 247 }