1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.primefaces.extensions.component.timepicker;
23
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.Map.Entry;
30
31 import javax.faces.application.ResourceDependency;
32 import javax.faces.context.FacesContext;
33 import javax.faces.event.AjaxBehaviorEvent;
34 import javax.faces.event.FacesEvent;
35 import javax.faces.event.PhaseId;
36
37 import org.primefaces.component.api.AbstractPrimeHtmlInputText;
38 import org.primefaces.component.api.InputHolder;
39 import org.primefaces.component.api.Widget;
40 import org.primefaces.extensions.event.BeforeShowEvent;
41 import org.primefaces.extensions.event.CloseEvent;
42 import org.primefaces.extensions.event.TimeSelectEvent;
43 import org.primefaces.util.Constants;
44 import org.primefaces.util.LangUtils;
45 import org.primefaces.util.LocaleUtils;
46
47
48
49
50
51
52
53
54 @ResourceDependency(library = "primefaces", name = "components.css")
55 @ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
56 @ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
57 @ResourceDependency(library = "primefaces", name = "core.js")
58 @ResourceDependency(library = "primefaces-extensions", name = "primefaces-extensions.js")
59 @ResourceDependency(library = "primefaces-extensions", name = "timepicker/timepicker.css")
60 @ResourceDependency(library = "primefaces-extensions", name = "timepicker/timepicker.js")
61 public class TimePicker extends AbstractPrimeHtmlInputText implements Widget, InputHolder {
62
63 public static final String CONTAINER_CLASS = "pe-timepicker ui-widget ui-corner-all";
64 public static final String INPUT_CLASS = "ui-inputfield ui-state-default ui-corner-all";
65 public static final String UP_BUTTON_CLASS = "ui-spinner-button ui-spinner-up ui-corner-tr ui-button ui-widget ui-state-default";
66 public static final String DOWN_BUTTON_CLASS = "ui-spinner-button ui-spinner-down ui-corner-br ui-button ui-widget ui-state-default";
67 public static final String UP_ICON_CLASS = "ui-icon ui-icon-triangle-1-n";
68 public static final String DOWN_ICON_CLASS = "ui-icon ui-icon-triangle-1-s";
69 public static final String BUTTON_TRIGGER_CLASS = "pe-timepicker-trigger ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only";
70 public static final String BUTTON_TRIGGER_ICON_CLASS = "ui-button-icon-left ui-icon ui-icon-clock";
71 public static final String BUTTON_TRIGGER_TEXT_CLASS = "ui-button-text";
72
73 public static final String TIME_MESSAGE_KEY = "javax.faces.converter.DateTimeConverter.TIME";
74 public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.TimePicker";
75 public static final String COMPONENT_FAMILY = "org.primefaces.extensions.component";
76 public static final String DEFAULT_RENDERER = "org.primefaces.extensions.component.TimePickerRenderer";
77
78 private static final List<String> UNOBSTRUSIVE_EVENT_NAMES = LangUtils.unmodifiableList(BeforeShowEvent.NAME,
79 TimeSelectEvent.NAME, CloseEvent.NAME);
80 private static final Collection<String> EVENT_NAMES = LangUtils.concat(AbstractPrimeHtmlInputText.EVENT_NAMES, UNOBSTRUSIVE_EVENT_NAMES);
81
82 private final Map<String, AjaxBehaviorEvent> customEvents = new HashMap<>();
83 private Locale appropriateLocale;
84
85 @SuppressWarnings("java:S115")
86 protected enum PropertyKeys {
87
88
89 widgetVar,
90 timeSeparator,
91 showPeriod,
92 dialogPosition,
93 inputPosition,
94 mode ,
95 startHours,
96 endHours,
97 startMinutes,
98 endMinutes,
99 intervalMinutes,
100 rows,
101 showHours,
102 showMinutes,
103 showCloseButton,
104 showNowButton,
105 showDeselectButton,
106 onHourShow,
107 onMinuteShow,
108 showOn,
109 locale,
110 minHour,
111 minMinute,
112 maxHour,
113 maxMinute,
114 readonlyInput,
115 size
116
117 }
118
119 public TimePicker() {
120 setRendererType(DEFAULT_RENDERER);
121 }
122
123 @Override
124 public String getFamily() {
125 return COMPONENT_FAMILY;
126 }
127
128 @Override
129 public String getInputClientId() {
130 return getClientId(getFacesContext()) + "_input";
131 }
132
133 @Override
134 public String getValidatableInputClientId() {
135 return getInputClientId();
136 }
137
138 @Override
139 public String getLabelledBy() {
140 return (String) getStateHelper().get("labelledby");
141 }
142
143 @Override
144 public void setLabelledBy(String labelledBy) {
145 getStateHelper().put("labelledby", labelledBy);
146 }
147
148 public String getWidgetVar() {
149 return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);
150 }
151
152 public void setWidgetVar(final String widgetVar) {
153 getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
154 }
155
156 public String getTimeSeparator() {
157 return (String) getStateHelper().eval(PropertyKeys.timeSeparator, ":");
158 }
159
160 public void setTimeSeparator(final String timeSeparator) {
161 getStateHelper().put(PropertyKeys.timeSeparator, timeSeparator);
162 }
163
164 public boolean isShowPeriod() {
165 return (Boolean) getStateHelper().eval(PropertyKeys.showPeriod, false);
166 }
167
168 public void setShowPeriod(final boolean showPeriod) {
169 getStateHelper().put(PropertyKeys.showPeriod, showPeriod);
170 }
171
172 public String getMode() {
173 return (String) getStateHelper().eval(PropertyKeys.mode, "spinner");
174 }
175
176 public void setMode(final String mode) {
177 getStateHelper().put(PropertyKeys.mode, mode);
178 }
179
180 public String getDialogPosition() {
181 return (String) getStateHelper().eval(PropertyKeys.dialogPosition, "left top");
182 }
183
184 public void setDialogPosition(final String dialogPosition) {
185 getStateHelper().put(PropertyKeys.dialogPosition, dialogPosition);
186 }
187
188 public String getInputPosition() {
189 return (String) getStateHelper().eval(PropertyKeys.inputPosition, "left bottom");
190 }
191
192 public void setInputPosition(final String inputPosition) {
193 getStateHelper().put(PropertyKeys.inputPosition, inputPosition);
194 }
195
196 public int getStartHours() {
197 return (Integer) getStateHelper().eval(PropertyKeys.startHours, 0);
198 }
199
200 public void setStartHours(final int startHours) {
201 getStateHelper().put(PropertyKeys.startHours, startHours);
202 }
203
204 public int getEndHours() {
205 return (Integer) getStateHelper().eval(PropertyKeys.endHours, 23);
206 }
207
208 public void setEndHours(final int endHours) {
209 getStateHelper().put(PropertyKeys.endHours, endHours);
210 }
211
212 public int getStartMinutes() {
213 return (Integer) getStateHelper().eval(PropertyKeys.startMinutes, 0);
214 }
215
216 public void setStartMinutes(final int startMinutes) {
217 getStateHelper().put(PropertyKeys.startMinutes, startMinutes);
218 }
219
220 public int getEndMinutes() {
221 return (Integer) getStateHelper().eval(PropertyKeys.endMinutes, 55);
222 }
223
224 public void setEndMinutes(final int endMinutes) {
225 getStateHelper().put(PropertyKeys.endMinutes, endMinutes);
226 }
227
228 public int getIntervalMinutes() {
229 return (Integer) getStateHelper().eval(PropertyKeys.intervalMinutes, 5);
230 }
231
232 public void setIntervalMinutes(final int intervalMinutes) {
233 getStateHelper().put(PropertyKeys.intervalMinutes, intervalMinutes);
234 }
235
236 public int getRows() {
237 return (Integer) getStateHelper().eval(PropertyKeys.rows, 4);
238 }
239
240 public void setRows(final int rows) {
241 getStateHelper().put(PropertyKeys.rows, rows);
242 }
243
244 public boolean isShowHours() {
245 return (Boolean) getStateHelper().eval(PropertyKeys.showHours, true);
246 }
247
248 public void setShowHours(final boolean showHours) {
249 getStateHelper().put(PropertyKeys.showHours, showHours);
250 }
251
252 public boolean isShowMinutes() {
253 return (Boolean) getStateHelper().eval(PropertyKeys.showMinutes, true);
254 }
255
256 public void setShowMinutes(final boolean showMinutes) {
257 getStateHelper().put(PropertyKeys.showMinutes, showMinutes);
258 }
259
260 public boolean isShowCloseButton() {
261 return (Boolean) getStateHelper().eval(PropertyKeys.showCloseButton, false);
262 }
263
264 public void setShowCloseButton(final boolean showCloseButton) {
265 getStateHelper().put(PropertyKeys.showCloseButton, showCloseButton);
266 }
267
268 public boolean isShowDeselectButton() {
269 return (Boolean) getStateHelper().eval(PropertyKeys.showDeselectButton, false);
270 }
271
272 public void setShowDeselectButton(final boolean showDeselectButton) {
273 getStateHelper().put(PropertyKeys.showDeselectButton, showDeselectButton);
274 }
275
276 public boolean isShowNowButton() {
277 return (Boolean) getStateHelper().eval(PropertyKeys.showNowButton, false);
278 }
279
280 public void setShowNowButton(final boolean showNowButton) {
281 getStateHelper().put(PropertyKeys.showNowButton, showNowButton);
282 }
283
284 public String getOnHourShow() {
285 return (String) getStateHelper().eval(PropertyKeys.onHourShow, null);
286 }
287
288 public void setOnHourShow(final String onHourShow) {
289 getStateHelper().put(PropertyKeys.onHourShow, onHourShow);
290 }
291
292 public String getOnMinuteShow() {
293 return (String) getStateHelper().eval(PropertyKeys.onMinuteShow, null);
294 }
295
296 public void setOnMinuteShow(final String onMinuteShow) {
297 getStateHelper().put(PropertyKeys.onMinuteShow, onMinuteShow);
298 }
299
300 public String getShowOn() {
301 return (String) getStateHelper().eval(PropertyKeys.showOn, "focus");
302 }
303
304 public void setShowOn(final String showOn) {
305 getStateHelper().put(PropertyKeys.showOn, showOn);
306 }
307
308 public Object getLocale() {
309 return getStateHelper().eval(PropertyKeys.locale, null);
310 }
311
312 public void setLocale(final Object locale) {
313 getStateHelper().put(PropertyKeys.locale, locale);
314 }
315
316 public Integer getMinHour() {
317 return (Integer) getStateHelper().eval(PropertyKeys.minHour, null);
318 }
319
320 public void setMinHour(final Integer minHour) {
321 getStateHelper().put(PropertyKeys.minHour, minHour);
322 }
323
324 public Integer getMinMinute() {
325 return (Integer) getStateHelper().eval(PropertyKeys.minMinute, null);
326 }
327
328 public void setMinMinute(final Integer minMinute) {
329 getStateHelper().put(PropertyKeys.minMinute, minMinute);
330 }
331
332 public Integer getMaxHour() {
333 return (Integer) getStateHelper().eval(PropertyKeys.maxHour, null);
334 }
335
336 public void setMaxHour(final Integer maxHour) {
337 getStateHelper().put(PropertyKeys.maxHour, maxHour);
338 }
339
340 public Integer getMaxMinute() {
341 return (Integer) getStateHelper().eval(PropertyKeys.maxMinute, null);
342 }
343
344 public void setMaxMinute(final Integer maxMinute) {
345 getStateHelper().put(PropertyKeys.maxMinute, maxMinute);
346 }
347
348 public boolean isReadonlyInput() {
349 return (Boolean) getStateHelper().eval(PropertyKeys.readonlyInput, false);
350 }
351
352 public void setReadonlyInput(final boolean _readonlyInput) {
353 getStateHelper().put(PropertyKeys.readonlyInput, _readonlyInput);
354 }
355
356 @Override
357 public int getSize() {
358 return (Integer) getStateHelper().eval(PropertyKeys.size, 5);
359 }
360
361 @Override
362 public void setSize(final int size) {
363 getStateHelper().put(PropertyKeys.size, size);
364 }
365
366 public Locale calculateLocale() {
367 if (appropriateLocale == null) {
368 final FacesContext fc = FacesContext.getCurrentInstance();
369 appropriateLocale = LocaleUtils.resolveLocale(fc, getLocale(), getClientId(fc));
370 }
371 return appropriateLocale;
372 }
373
374 public boolean isInline() {
375 return getMode().equalsIgnoreCase("inline");
376 }
377
378 public boolean isSpinner() {
379 return getMode().equalsIgnoreCase("spinner");
380 }
381
382 public boolean isShowOnButton() {
383 return !"focus".equals(getShowOn());
384 }
385
386 @Override
387 public Collection<String> getEventNames() {
388 return EVENT_NAMES;
389 }
390
391 @Override
392 public void queueEvent(final FacesEvent event) {
393 final FacesContext fc = FacesContext.getCurrentInstance();
394 final String eventName = fc.getExternalContext().getRequestParameterMap()
395 .get(Constants.RequestParams.PARTIAL_BEHAVIOR_EVENT_PARAM);
396
397 if (isSelfRequest(fc) && event instanceof AjaxBehaviorEvent) {
398 if (TimeSelectEvent.NAME.equals(eventName)) {
399 customEvents.put(TimeSelectEvent.NAME, (AjaxBehaviorEvent) event);
400
401 return;
402 }
403 else if (BeforeShowEvent.NAME.equals(eventName)) {
404 final BeforeShowEvent beforeShowEvent = new BeforeShowEvent(this,
405 ((AjaxBehaviorEvent) event).getBehavior());
406 beforeShowEvent.setPhaseId(event.getPhaseId());
407 super.queueEvent(beforeShowEvent);
408
409 return;
410 }
411 else if (CloseEvent.NAME.equals(eventName)) {
412 final CloseEvent closeEvent = new CloseEvent(this, ((AjaxBehaviorEvent) event).getBehavior());
413 closeEvent.setPhaseId(event.getPhaseId());
414 super.queueEvent(closeEvent);
415
416 return;
417 }
418 }
419
420 super.queueEvent(event);
421 }
422
423 @Override
424 public void validate(final FacesContext fc) {
425 super.validate(fc);
426
427 if (isValid()) {
428 for (final Entry<String, AjaxBehaviorEvent> entry : customEvents.entrySet()) {
429 final AjaxBehaviorEvent behaviorEvent = entry.getValue();
430 final TimeSelectEvent<Object> timeSelectEvent = new TimeSelectEvent<>(this, behaviorEvent.getBehavior(), getValue());
431
432 if (behaviorEvent.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {
433 timeSelectEvent.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
434 }
435 else {
436 timeSelectEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
437 }
438
439 super.queueEvent(timeSelectEvent);
440 }
441 }
442 }
443
444 public String getTimePatternWithoutHours() {
445 return "mm";
446 }
447
448 public String getTimePatternWithoutMinutes() {
449 return isShowPeriod() ? "hh" : "HH";
450 }
451
452 public String getTimePattern24() {
453 return "HH" + getTimeSeparator() + "mm";
454 }
455
456 public String getTimePattern12() {
457 return "hh" + getTimeSeparator() + "mm a";
458 }
459
460 private boolean isSelfRequest(final FacesContext fc) {
461 return getClientId(fc).equals(
462 fc.getExternalContext().getRequestParameterMap().get(Constants.RequestParams.PARTIAL_SOURCE_PARAM));
463 }
464
465 @Override
466 public Object saveState(FacesContext context) {
467
468 appropriateLocale = null;
469 customEvents.clear();
470
471 return super.saveState(context);
472 }
473 }