1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
/**
|
3 |
|
|
* @file
|
4 |
|
|
* A module to enable jquery calendar and time entry popups.
|
5 |
|
|
* Requires the Date API.
|
6 |
|
|
*
|
7 |
|
|
* Add a type of #date_popup to any date, time, or datetime field that will
|
8 |
|
|
* use this popup. Set #date_format to the way the date should be presented
|
9 |
|
|
* to the user in the form. Set #default_value to be a date in the local
|
10 |
|
|
* timezone, and note the timezone name in #date_timezone.
|
11 |
|
|
*
|
12 |
|
|
* The element will create two textfields, one for the date and one for the
|
13 |
|
|
* time. The date textfield will include a jQuery popup calendar date picker,
|
14 |
|
|
* and the time textfield uses a jQuery timepicker.
|
15 |
|
|
*
|
16 |
|
|
* If no time elements are included in the format string, only the date
|
17 |
|
|
* textfield will be created. If no date elements are included in the format
|
18 |
|
|
* string, only the time textfield, will be created.
|
19 |
|
|
*/
|
20 |
|
|
|
21 |
|
|
/**
|
22 |
|
|
* Load needed files.
|
23 |
|
|
*
|
24 |
|
|
* Play nice with jQuery UI.
|
25 |
|
|
*/
|
26 |
|
|
function date_popup_add() {
|
27 |
|
|
static $loaded = FALSE;
|
28 |
|
|
if ($loaded) {
|
29 |
|
|
return;
|
30 |
|
|
}
|
31 |
|
|
drupal_add_library('system', 'ui.datepicker');
|
32 |
|
|
drupal_add_library('date_popup', 'timeentry');
|
33 |
|
|
|
34 |
|
|
// Add the wvega-timepicker library if it's available.
|
35 |
|
|
$wvega_path = date_popup_get_wvega_path();
|
36 |
|
|
if ($wvega_path) {
|
37 |
|
|
drupal_add_js($wvega_path . '/jquery.timepicker.js');
|
38 |
|
|
drupal_add_css($wvega_path . '/jquery.timepicker.css');
|
39 |
|
|
}
|
40 |
|
|
$loaded = TRUE;
|
41 |
|
|
}
|
42 |
|
|
|
43 |
|
|
/**
|
44 |
|
|
* Get the location of the Willington Vega timepicker library.
|
45 |
|
|
*
|
46 |
b720ea3e
|
Assos Assos
|
* @return string
|
47 |
85ad3d82
|
Assos Assos
|
* The location of the library, or FALSE if the library isn't installed.
|
48 |
|
|
*/
|
49 |
|
|
function date_popup_get_wvega_path() {
|
50 |
|
|
$path = FALSE;
|
51 |
|
|
if (function_exists('libraries_get_path')) {
|
52 |
|
|
$path = libraries_get_path('wvega-timepicker');
|
53 |
|
|
if (!file_exists($path)) {
|
54 |
|
|
$path = FALSE;
|
55 |
|
|
}
|
56 |
|
|
}
|
57 |
|
|
elseif (file_exists('sites/all/libraries/wvega-timepicker/jquery.timepicker.js')) {
|
58 |
|
|
$path = 'sites/all/libraries/wvega-timepicker';
|
59 |
|
|
}
|
60 |
|
|
return $path;
|
61 |
|
|
}
|
62 |
|
|
|
63 |
|
|
/**
|
64 |
|
|
* Get the name of the preferred default timepicker.
|
65 |
|
|
*
|
66 |
|
|
* If the wvega timepicker is available on the system, default to using that,
|
67 |
|
|
* unless the administrator has specifically chosen otherwise.
|
68 |
|
|
*/
|
69 |
|
|
function date_popup_get_preferred_timepicker() {
|
70 |
|
|
$wvega_available = date_popup_get_wvega_path();
|
71 |
|
|
return $wvega_available ? 'wvega' : 'default';
|
72 |
|
|
}
|
73 |
|
|
|
74 |
|
|
/**
|
75 |
|
|
* Implements hook_library().
|
76 |
|
|
*/
|
77 |
|
|
function date_popup_library() {
|
78 |
|
|
$libraries = array();
|
79 |
|
|
|
80 |
|
|
$path = drupal_get_path('module', 'date_popup');
|
81 |
|
|
$libraries['timeentry'] = array(
|
82 |
|
|
'title' => 'Time Entry',
|
83 |
|
|
'website' => 'http://plugins.jquery.com/project/timeEntry',
|
84 |
|
|
'version' => '1.4.7',
|
85 |
|
|
'js' => array(
|
86 |
|
|
$path . '/jquery.timeentry.pack.js' => array(),
|
87 |
|
|
),
|
88 |
|
|
'css' => array(
|
89 |
|
|
$path . '/themes/jquery.timeentry.css' => array(),
|
90 |
|
|
),
|
91 |
|
|
);
|
92 |
|
|
return $libraries;
|
93 |
|
|
}
|
94 |
|
|
|
95 |
|
|
/**
|
96 |
b720ea3e
|
Assos Assos
|
* Create a unique CSS id name and output a single inline JS block.
|
97 |
|
|
*
|
98 |
|
|
* For each startup function to call and settings array to pass it.
|
99 |
|
|
*
|
100 |
|
|
* This used to create a unique CSS class for each unique combination of
|
101 |
85ad3d82
|
Assos Assos
|
* function and settings, but using classes requires a DOM traversal
|
102 |
|
|
* and is much slower than an id lookup. The new approach returns to
|
103 |
|
|
* requiring a duplicate copy of the settings/code for every element
|
104 |
|
|
* that uses them, but is much faster. We could combine the logic by
|
105 |
|
|
* putting the ids for each unique function/settings combo into
|
106 |
|
|
* Drupal.settings and searching for each listed id.
|
107 |
|
|
*
|
108 |
b720ea3e
|
Assos Assos
|
* @param string $id
|
109 |
85ad3d82
|
Assos Assos
|
* The CSS class prefix to search the DOM for.
|
110 |
|
|
* TODO : unused ?
|
111 |
b720ea3e
|
Assos Assos
|
*
|
112 |
|
|
* @param string $func
|
113 |
|
|
* The jQuery function to invoke on each DOM element
|
114 |
|
|
* containing the returned CSS class.
|
115 |
|
|
*
|
116 |
|
|
* @param array $settings
|
117 |
85ad3d82
|
Assos Assos
|
* The settings array to pass to the jQuery function.
|
118 |
b720ea3e
|
Assos Assos
|
*
|
119 |
85ad3d82
|
Assos Assos
|
* @returns
|
120 |
b720ea3e
|
Assos Assos
|
* The CSS id to assign to the element that should have $func($settings)
|
121 |
|
|
* invoked on it.
|
122 |
85ad3d82
|
Assos Assos
|
*/
|
123 |
|
|
function date_popup_js_settings_id($id, $func, $settings) {
|
124 |
|
|
static $js_added = FALSE;
|
125 |
|
|
static $id_count = array();
|
126 |
|
|
|
127 |
|
|
// Make sure popup date selector grid is in correct year.
|
128 |
|
|
if (!empty($settings['yearRange'])) {
|
129 |
|
|
$parts = explode(':', $settings['yearRange']);
|
130 |
b720ea3e
|
Assos Assos
|
// Set the default date to 0 or the lowest bound if
|
131 |
|
|
// the date ranges do not include the current year.
|
132 |
|
|
// Necessary for the datepicker to render and select dates correctly.
|
133 |
|
|
$default_date = ($parts[0] > 0 || 0 > $parts[1]) ? $parts[0] : 0;
|
134 |
|
|
$settings += array('defaultDate' => (string) $default_date . 'y');
|
135 |
85ad3d82
|
Assos Assos
|
}
|
136 |
|
|
|
137 |
|
|
if (!$js_added) {
|
138 |
b720ea3e
|
Assos Assos
|
drupal_add_js(drupal_get_path('module', 'date_popup') . '/date_popup.js');
|
139 |
85ad3d82
|
Assos Assos
|
$js_added = TRUE;
|
140 |
|
|
}
|
141 |
|
|
|
142 |
|
|
// We use a static array to account for possible multiple form_builder()
|
143 |
|
|
// calls in the same request (form instance on 'Preview').
|
144 |
|
|
if (!isset($id_count[$id])) {
|
145 |
|
|
$id_count[$id] = 0;
|
146 |
|
|
}
|
147 |
|
|
|
148 |
b720ea3e
|
Assos Assos
|
// It looks like we need the additional id_count for this to
|
149 |
|
|
// work correctly when there are multiple values.
|
150 |
|
|
// $return_id = "$id-$func-popup";
|
151 |
|
|
$return_id = "$id-$func-popup-" . $id_count[$id]++;
|
152 |
85ad3d82
|
Assos Assos
|
$js_settings['datePopup'][$return_id] = array(
|
153 |
|
|
'func' => $func,
|
154 |
b720ea3e
|
Assos Assos
|
'settings' => $settings,
|
155 |
85ad3d82
|
Assos Assos
|
);
|
156 |
|
|
drupal_add_js($js_settings, 'setting');
|
157 |
|
|
return $return_id;
|
158 |
|
|
}
|
159 |
|
|
|
160 |
b720ea3e
|
Assos Assos
|
/**
|
161 |
|
|
* Date popup theme handler.
|
162 |
|
|
*/
|
163 |
85ad3d82
|
Assos Assos
|
function date_popup_theme() {
|
164 |
|
|
return array(
|
165 |
b720ea3e
|
Assos Assos
|
'date_popup' => array(
|
166 |
|
|
'render element' => 'element',
|
167 |
|
|
),
|
168 |
|
|
);
|
169 |
85ad3d82
|
Assos Assos
|
}
|
170 |
|
|
|
171 |
|
|
/**
|
172 |
|
|
* Implements hook_element_info().
|
173 |
|
|
*
|
174 |
|
|
* Set the #type to date_popup and fill the element #default_value with
|
175 |
b720ea3e
|
Assos Assos
|
* a date adjusted to the proper local timezone in datetime format
|
176 |
|
|
* (YYYY-MM-DD HH:MM:SS).
|
177 |
85ad3d82
|
Assos Assos
|
*
|
178 |
|
|
* The element will create two textfields, one for the date and one for the
|
179 |
|
|
* time. The date textfield will include a jQuery popup calendar date picker,
|
180 |
|
|
* and the time textfield uses a jQuery timepicker.
|
181 |
|
|
*
|
182 |
|
|
* NOTE - Converting a date stored in the database from UTC to the local zone
|
183 |
|
|
* and converting it back to UTC before storing it is not handled by this
|
184 |
|
|
* element and must be done in pre-form and post-form processing!!
|
185 |
|
|
*
|
186 |
|
|
* #date_timezone
|
187 |
|
|
* The local timezone to be used to create this date.
|
188 |
|
|
*
|
189 |
|
|
* #date_format
|
190 |
|
|
* Unlike earlier versions of this popup, most formats will work.
|
191 |
|
|
*
|
192 |
|
|
* #date_increment
|
193 |
|
|
* Increment minutes and seconds by this amount, default is 1.
|
194 |
|
|
*
|
195 |
|
|
* #date_year_range
|
196 |
|
|
* The number of years to go back and forward in a year selector,
|
197 |
|
|
* default is -3:+3 (3 back and 3 forward).
|
198 |
|
|
*
|
199 |
|
|
* #datepicker_options
|
200 |
|
|
* An associative array representing the jQuery datepicker options you want
|
201 |
|
|
* to set for this element. Use the jQuery datepicker option names as keys.
|
202 |
|
|
* Hard coded defaults are:
|
203 |
|
|
* - changeMonth => TRUE
|
204 |
|
|
* - changeYear => TRUE
|
205 |
|
|
* - autoPopUp => 'focus'
|
206 |
|
|
* - closeAtTop => FALSE
|
207 |
|
|
* - speed => 'immediate'
|
208 |
|
|
*/
|
209 |
|
|
function date_popup_element_info() {
|
210 |
|
|
$timepicker = date_popup_get_preferred_timepicker();
|
211 |
|
|
$type['date_popup'] = array(
|
212 |
|
|
'#input' => TRUE,
|
213 |
|
|
'#tree' => TRUE,
|
214 |
|
|
'#date_timezone' => date_default_timezone(),
|
215 |
|
|
'#date_flexible' => 0,
|
216 |
|
|
'#date_format' => variable_get('date_format_short', 'm/d/Y - H:i'),
|
217 |
|
|
'#datepicker_options' => array(),
|
218 |
|
|
'#timepicker' => variable_get('date_popup_timepicker', $timepicker),
|
219 |
|
|
'#date_increment' => 1,
|
220 |
|
|
'#date_year_range' => '-3:+3',
|
221 |
|
|
'#date_label_position' => 'above',
|
222 |
|
|
'#process' => array('date_popup_element_process'),
|
223 |
|
|
'#value_callback' => 'date_popup_element_value_callback',
|
224 |
|
|
'#theme_wrappers' => array('date_popup'),
|
225 |
|
|
);
|
226 |
|
|
if (module_exists('ctools')) {
|
227 |
|
|
$type['date_popup']['#pre_render'] = array('ctools_dependent_pre_render');
|
228 |
|
|
}
|
229 |
|
|
return $type;
|
230 |
|
|
}
|
231 |
|
|
|
232 |
b720ea3e
|
Assos Assos
|
/**
|
233 |
|
|
* Date popup date granularity.
|
234 |
|
|
*/
|
235 |
85ad3d82
|
Assos Assos
|
function date_popup_date_granularity($element) {
|
236 |
|
|
$granularity = date_format_order($element['#date_format']);
|
237 |
|
|
return array_intersect($granularity, array('month', 'day', 'year'));
|
238 |
|
|
}
|
239 |
|
|
|
240 |
b720ea3e
|
Assos Assos
|
/**
|
241 |
|
|
* Date popup time granularity.
|
242 |
|
|
*/
|
243 |
85ad3d82
|
Assos Assos
|
function date_popup_time_granularity($element) {
|
244 |
|
|
$granularity = date_format_order($element['#date_format']);
|
245 |
|
|
return array_intersect($granularity, array('hour', 'minute', 'second'));
|
246 |
|
|
}
|
247 |
|
|
|
248 |
b720ea3e
|
Assos Assos
|
/**
|
249 |
|
|
* Date popup date format.
|
250 |
|
|
*/
|
251 |
85ad3d82
|
Assos Assos
|
function date_popup_date_format($element) {
|
252 |
|
|
return (date_limit_format($element['#date_format'], date_popup_date_granularity($element)));
|
253 |
|
|
}
|
254 |
|
|
|
255 |
b720ea3e
|
Assos Assos
|
/**
|
256 |
|
|
* Date popup time format.
|
257 |
|
|
*/
|
258 |
85ad3d82
|
Assos Assos
|
function date_popup_time_format($element) {
|
259 |
|
|
return date_popup_format_to_popup_time(date_limit_format($element['#date_format'], date_popup_time_granularity($element)), $element['#timepicker']);
|
260 |
|
|
}
|
261 |
|
|
|
262 |
|
|
/**
|
263 |
|
|
* Element value callback for date_popup element.
|
264 |
|
|
*/
|
265 |
b720ea3e
|
Assos Assos
|
// @codingStandardsIgnoreStart
|
266 |
85ad3d82
|
Assos Assos
|
function date_popup_element_value_callback($element, $input = FALSE, &$form_state) {
|
267 |
|
|
$granularity = date_format_order($element['#date_format']);
|
268 |
|
|
$has_time = date_has_time($granularity);
|
269 |
|
|
$date = NULL;
|
270 |
|
|
$return = $has_time ? array('date' => '', 'time' => '') : array('date' => '');
|
271 |
|
|
// Normal input from submitting the form element.
|
272 |
|
|
// Check is_array() to skip the string input values created by Views pagers.
|
273 |
|
|
// Those string values, if present, should be interpreted as empty input.
|
274 |
|
|
if ($input !== FALSE && is_array($input)) {
|
275 |
|
|
$return = $input;
|
276 |
|
|
$date = date_popup_input_date($element, $input);
|
277 |
|
|
}
|
278 |
|
|
// No input? Try the default value.
|
279 |
|
|
elseif (!empty($element['#default_value'])) {
|
280 |
|
|
$date = date_default_date($element);
|
281 |
|
|
}
|
282 |
|
|
// Date with errors won't re-display.
|
283 |
|
|
if (date_is_date($date)) {
|
284 |
|
|
$return['date'] = !$date->timeOnly ? date_format_date($date, 'custom', date_popup_date_format($element)) : '';
|
285 |
|
|
$return['time'] = $has_time ? date_format_date($date, 'custom', date_popup_time_format($element)) : '';
|
286 |
|
|
}
|
287 |
|
|
elseif (!empty($input)) {
|
288 |
|
|
$return = $input;
|
289 |
|
|
}
|
290 |
|
|
return $return;
|
291 |
|
|
|
292 |
|
|
}
|
293 |
b720ea3e
|
Assos Assos
|
// @codingStandardsIgnoreEnd
|
294 |
85ad3d82
|
Assos Assos
|
|
295 |
|
|
/**
|
296 |
|
|
* Javascript popup element processing.
|
297 |
b720ea3e
|
Assos Assos
|
*
|
298 |
85ad3d82
|
Assos Assos
|
* Add popup attributes to $element.
|
299 |
|
|
*/
|
300 |
|
|
function date_popup_element_process($element, &$form_state, $form) {
|
301 |
|
|
if (date_hidden_element($element)) {
|
302 |
|
|
return $element;
|
303 |
|
|
}
|
304 |
|
|
|
305 |
|
|
date_popup_add();
|
306 |
|
|
module_load_include('inc', 'date_api', 'date_api_elements');
|
307 |
|
|
|
308 |
|
|
$element['#tree'] = TRUE;
|
309 |
|
|
$element['#theme_wrappers'] = array('date_popup');
|
310 |
|
|
|
311 |
|
|
if (!empty($element['#ajax'])) {
|
312 |
|
|
$element['#ajax'] += array(
|
313 |
b720ea3e
|
Assos Assos
|
'trigger_as' => array(
|
314 |
|
|
'name' => $element['#name'],
|
315 |
|
|
),
|
316 |
85ad3d82
|
Assos Assos
|
'event' => 'change',
|
317 |
|
|
);
|
318 |
|
|
}
|
319 |
|
|
|
320 |
|
|
$element['date'] = date_popup_process_date_part($element);
|
321 |
|
|
$element['time'] = date_popup_process_time_part($element);
|
322 |
|
|
|
323 |
b720ea3e
|
Assos Assos
|
// Make changes if instance is set to be rendered as a regular field.
|
324 |
|
|
if (!empty($element['#instance']['widget']['settings']['no_fieldset']) && $element['#field']['cardinality'] == 1) {
|
325 |
|
|
if (!empty($element['date']) && empty($element['time'])) {
|
326 |
|
|
$element['date']['#title'] = check_plain($element['#instance']['label']);
|
327 |
|
|
$element['date']['#required'] = $element['#required'];
|
328 |
|
|
}
|
329 |
|
|
elseif (empty($element['date']) && !empty($element['time'])) {
|
330 |
|
|
$element['time']['#title'] = check_plain($element['#instance']['label']);
|
331 |
|
|
$element['time']['#required'] = $element['#required'];
|
332 |
|
|
}
|
333 |
|
|
}
|
334 |
|
|
|
335 |
85ad3d82
|
Assos Assos
|
if (isset($element['#element_validate'])) {
|
336 |
|
|
array_push($element['#element_validate'], 'date_popup_validate');
|
337 |
|
|
}
|
338 |
|
|
else {
|
339 |
|
|
$element['#element_validate'] = array('date_popup_validate');
|
340 |
|
|
}
|
341 |
|
|
|
342 |
|
|
$context = array(
|
343 |
b720ea3e
|
Assos Assos
|
'form' => $form,
|
344 |
85ad3d82
|
Assos Assos
|
);
|
345 |
|
|
drupal_alter('date_popup_process', $element, $form_state, $context);
|
346 |
|
|
|
347 |
|
|
return $element;
|
348 |
|
|
}
|
349 |
|
|
|
350 |
|
|
/**
|
351 |
|
|
* Process the date portion of the element.
|
352 |
|
|
*/
|
353 |
|
|
function date_popup_process_date_part(&$element) {
|
354 |
|
|
$granularity = date_format_order($element['#date_format']);
|
355 |
|
|
$date_granularity = date_popup_date_granularity($element);
|
356 |
b720ea3e
|
Assos Assos
|
if (empty($date_granularity)) {
|
357 |
|
|
return array();
|
358 |
|
|
}
|
359 |
85ad3d82
|
Assos Assos
|
|
360 |
|
|
// The datepicker can't handle zero or negative values like 0:+1
|
361 |
|
|
// even though the Date API can handle them, so rework the value
|
362 |
|
|
// we pass to the datepicker to use defaults it can accept (such as +0:+1)
|
363 |
|
|
// date_range_string() adds the necessary +/- signs to the range string.
|
364 |
|
|
$this_year = date_format(date_now(), 'Y');
|
365 |
b720ea3e
|
Assos Assos
|
// When used as a Views exposed filter widget, $element['#value'] contains an array instead an string.
|
366 |
|
|
// Fill the 'date' string in this case.
|
367 |
|
|
$mock = NULL;
|
368 |
|
|
$callback_values = date_popup_element_value_callback($element, FALSE, $mock);
|
369 |
|
|
if (!isset($element['#value']['date']) && isset($callback_values['date'])) {
|
370 |
|
|
$element['#value']['date'] = $callback_values['date'];
|
371 |
|
|
}
|
372 |
85ad3d82
|
Assos Assos
|
$date = '';
|
373 |
|
|
if (!empty($element['#value']['date'])) {
|
374 |
|
|
$date = new DateObject($element['#value']['date'], $element['#date_timezone'], date_popup_date_format($element));
|
375 |
|
|
}
|
376 |
|
|
$range = date_range_years($element['#date_year_range'], $date);
|
377 |
|
|
$year_range = date_range_string($range);
|
378 |
|
|
|
379 |
|
|
// Add the dynamic datepicker options. Allow element-specific datepicker
|
380 |
|
|
// preferences to override these options for whatever reason they see fit.
|
381 |
|
|
$settings = $element['#datepicker_options'] + array(
|
382 |
|
|
'changeMonth' => TRUE,
|
383 |
|
|
'changeYear' => TRUE,
|
384 |
|
|
'autoPopUp' => 'focus',
|
385 |
|
|
'closeAtTop' => FALSE,
|
386 |
|
|
'speed' => 'immediate',
|
387 |
|
|
'firstDay' => intval(variable_get('date_first_day', 0)),
|
388 |
b720ea3e
|
Assos Assos
|
// 'buttonImage' => base_path()
|
389 |
|
|
// . drupal_get_path('module', 'date_api') ."/images/calendar.png",
|
390 |
|
|
// 'buttonImageOnly' => TRUE,
|
391 |
85ad3d82
|
Assos Assos
|
'dateFormat' => date_popup_format_to_popup(date_popup_date_format($element), 'datepicker'),
|
392 |
|
|
'yearRange' => $year_range,
|
393 |
|
|
// Custom setting, will be expanded in Drupal.behaviors.date_popup()
|
394 |
|
|
'fromTo' => isset($fromto),
|
395 |
|
|
);
|
396 |
|
|
|
397 |
|
|
// Create a unique id for each set of custom settings.
|
398 |
|
|
$id = date_popup_js_settings_id($element['#id'], 'datepicker', $settings);
|
399 |
|
|
|
400 |
b720ea3e
|
Assos Assos
|
// Manually build this element and set the value -
|
401 |
|
|
// this will prevent corrupting the parent value.
|
402 |
85ad3d82
|
Assos Assos
|
$parents = array_merge($element['#parents'], array('date'));
|
403 |
|
|
$sub_element = array(
|
404 |
|
|
'#type' => 'textfield',
|
405 |
|
|
'#title' => theme('date_part_label_date', array('part_type' => 'date', 'element' => $element)),
|
406 |
|
|
'#title_display' => $element['#date_label_position'] == 'above' ? 'before' : 'invisible',
|
407 |
b720ea3e
|
Assos Assos
|
'#default_value' => date_format_date($date, 'custom', date_popup_date_format($element)),
|
408 |
85ad3d82
|
Assos Assos
|
'#id' => $id,
|
409 |
|
|
'#input' => FALSE,
|
410 |
|
|
'#size' => !empty($element['#size']) ? $element['#size'] : 20,
|
411 |
|
|
'#maxlength' => !empty($element['#maxlength']) ? $element['#maxlength'] : 30,
|
412 |
|
|
'#attributes' => $element['#attributes'],
|
413 |
|
|
'#parents' => $parents,
|
414 |
b720ea3e
|
Assos Assos
|
'#name' => array_shift($parents) . '[' . implode('][', $parents) . ']',
|
415 |
85ad3d82
|
Assos Assos
|
'#ajax' => !empty($element['#ajax']) ? $element['#ajax'] : FALSE,
|
416 |
|
|
);
|
417 |
|
|
$sub_element['#value'] = $sub_element['#default_value'];
|
418 |
b720ea3e
|
Assos Assos
|
// TODO, figure out exactly when we want this description.
|
419 |
|
|
// In many places it is not desired.
|
420 |
|
|
$sub_element['#description'] = ' ' . t('E.g., @date', array(
|
421 |
|
|
'@date' => date_format_date(
|
422 |
|
|
date_example_date(),
|
423 |
|
|
'custom',
|
424 |
|
|
date_popup_date_format($element)
|
425 |
|
|
),
|
426 |
|
|
));
|
427 |
85ad3d82
|
Assos Assos
|
|
428 |
|
|
return $sub_element;
|
429 |
|
|
}
|
430 |
|
|
|
431 |
|
|
/**
|
432 |
|
|
* Process the time portion of the element.
|
433 |
|
|
*/
|
434 |
|
|
function date_popup_process_time_part(&$element) {
|
435 |
|
|
$granularity = date_format_order($element['#date_format']);
|
436 |
|
|
$has_time = date_has_time($granularity);
|
437 |
b720ea3e
|
Assos Assos
|
if (empty($has_time)) {
|
438 |
|
|
return array();
|
439 |
|
|
}
|
440 |
|
|
|
441 |
|
|
// When used as a Views exposed filter widget, $element['#value'] contains an array instead an string.
|
442 |
|
|
// Fill the 'time' string in this case.
|
443 |
|
|
$mock = NULL;
|
444 |
|
|
$callback_values = date_popup_element_value_callback($element, FALSE, $mock);
|
445 |
|
|
if (!isset($element['#value']['time']) && isset($callback_values['time'])) {
|
446 |
|
|
$element['#value']['time'] = $callback_values['time'];
|
447 |
|
|
}
|
448 |
85ad3d82
|
Assos Assos
|
|
449 |
|
|
switch ($element['#timepicker']) {
|
450 |
|
|
case 'default':
|
451 |
|
|
$func = 'timeEntry';
|
452 |
|
|
$settings = array(
|
453 |
|
|
'show24Hours' => strpos($element['#date_format'], 'H') !== FALSE ? TRUE : FALSE,
|
454 |
|
|
'showSeconds' => (in_array('second', $granularity) ? TRUE : FALSE),
|
455 |
b720ea3e
|
Assos Assos
|
'timeSteps' => array(
|
456 |
|
|
1,
|
457 |
|
|
intval($element['#date_increment']),
|
458 |
|
|
(in_array('second', $granularity) ? $element['#date_increment'] : 0),
|
459 |
|
|
),
|
460 |
85ad3d82
|
Assos Assos
|
'spinnerImage' => '',
|
461 |
|
|
'fromTo' => isset($fromto),
|
462 |
b720ea3e
|
Assos Assos
|
);
|
463 |
85ad3d82
|
Assos Assos
|
if (strpos($element['#date_format'], 'a') !== FALSE) {
|
464 |
|
|
// Then we are using lowercase am/pm.
|
465 |
|
|
$settings['ampmNames'] = array('am', 'pm');
|
466 |
|
|
}
|
467 |
|
|
if (strpos($element['#date_format'], ' A') !== FALSE || strpos($element['#date_format'], ' a') !== FALSE) {
|
468 |
|
|
$settings['ampmPrefix'] = ' ';
|
469 |
|
|
}
|
470 |
|
|
break;
|
471 |
b720ea3e
|
Assos Assos
|
|
472 |
85ad3d82
|
Assos Assos
|
case 'wvega':
|
473 |
|
|
$func = 'timepicker';
|
474 |
b720ea3e
|
Assos Assos
|
$grans = array('hour', 'minute', 'second');
|
475 |
|
|
$time_granularity = array_intersect($granularity, $grans);
|
476 |
85ad3d82
|
Assos Assos
|
$format = date_popup_format_to_popup_time(date_limit_format($element['#date_format'], $time_granularity), 'wvega');
|
477 |
|
|
// The first value in the dropdown list should be the same as the element
|
478 |
|
|
// default_value, but it needs to be in JS format (i.e. milliseconds since
|
479 |
|
|
// the epoch).
|
480 |
|
|
$start_time = new DateObject($element['#default_value'], $element['#date_timezone'], DATE_FORMAT_DATETIME);
|
481 |
|
|
date_increment_round($start_time, $element['#date_increment']);
|
482 |
|
|
$start_time = $start_time->format(DATE_FORMAT_UNIX) * 1000;
|
483 |
|
|
$settings = array(
|
484 |
|
|
'timeFormat' => $format,
|
485 |
|
|
'interval' => $element['#date_increment'],
|
486 |
|
|
'startTime' => $start_time,
|
487 |
|
|
'scrollbar' => TRUE,
|
488 |
|
|
);
|
489 |
|
|
break;
|
490 |
b720ea3e
|
Assos Assos
|
|
491 |
85ad3d82
|
Assos Assos
|
default:
|
492 |
|
|
$func = '';
|
493 |
|
|
$settings = array();
|
494 |
|
|
break;
|
495 |
|
|
}
|
496 |
|
|
|
497 |
|
|
// Create a unique id for each set of custom settings.
|
498 |
|
|
$id = date_popup_js_settings_id($element['#id'], $func, $settings);
|
499 |
|
|
|
500 |
b720ea3e
|
Assos Assos
|
// Manually build this element and set the value -
|
501 |
|
|
// this will prevent corrupting the parent value.
|
502 |
85ad3d82
|
Assos Assos
|
$parents = array_merge($element['#parents'], array('time'));
|
503 |
|
|
$sub_element = array(
|
504 |
|
|
'#type' => 'textfield',
|
505 |
|
|
'#title' => theme('date_part_label_time', array('part_type' => 'time', 'element' => $element)),
|
506 |
|
|
'#title_display' => $element['#date_label_position'] == 'above' ? 'before' : 'invisible',
|
507 |
|
|
'#default_value' => $element['#value']['time'],
|
508 |
|
|
'#id' => $id,
|
509 |
|
|
'#size' => 15,
|
510 |
|
|
'#maxlength' => 10,
|
511 |
|
|
'#attributes' => $element['#attributes'],
|
512 |
|
|
'#parents' => $parents,
|
513 |
b720ea3e
|
Assos Assos
|
'#name' => array_shift($parents) . '[' . implode('][', $parents) . ']',
|
514 |
85ad3d82
|
Assos Assos
|
'#ajax' => !empty($element['#ajax']) ? $element['#ajax'] : FALSE,
|
515 |
|
|
);
|
516 |
|
|
|
517 |
|
|
$sub_element['#value'] = $sub_element['#default_value'];
|
518 |
|
|
|
519 |
b720ea3e
|
Assos Assos
|
// TODO, figure out exactly when we want this description.
|
520 |
|
|
// In many places it is not desired.
|
521 |
85ad3d82
|
Assos Assos
|
$example_date = date_now();
|
522 |
|
|
date_increment_round($example_date, $element['#date_increment']);
|
523 |
b720ea3e
|
Assos Assos
|
$sub_element['#description'] = t('E.g., @date', array(
|
524 |
|
|
'@date' => date_format_date(
|
525 |
|
|
$example_date,
|
526 |
|
|
'custom',
|
527 |
|
|
date_popup_time_format($element)
|
528 |
|
|
)));
|
529 |
85ad3d82
|
Assos Assos
|
|
530 |
|
|
return ($sub_element);
|
531 |
|
|
}
|
532 |
|
|
|
533 |
|
|
/**
|
534 |
|
|
* Massage the input values back into a single date.
|
535 |
|
|
*
|
536 |
|
|
* When used as a Views widget, the validation step always gets triggered,
|
537 |
|
|
* even with no form submission. Before form submission $element['#value']
|
538 |
|
|
* contains a string, after submission it contains an array.
|
539 |
|
|
*/
|
540 |
|
|
function date_popup_validate($element, &$form_state) {
|
541 |
|
|
|
542 |
|
|
if (date_hidden_element($element)) {
|
543 |
|
|
return;
|
544 |
|
|
}
|
545 |
|
|
|
546 |
|
|
if (is_string($element['#value'])) {
|
547 |
|
|
return;
|
548 |
|
|
}
|
549 |
|
|
|
550 |
|
|
module_load_include('inc', 'date_api', 'date_api_elements');
|
551 |
|
|
date_popup_add();
|
552 |
|
|
|
553 |
|
|
$input_exists = NULL;
|
554 |
|
|
$input = drupal_array_get_nested_value($form_state['values'], $element['#parents'], $input_exists);
|
555 |
b720ea3e
|
Assos Assos
|
// If the date is a string, it is not considered valid and can cause problems
|
556 |
|
|
// later on, so just exit out now.
|
557 |
|
|
if (is_string($input)) {
|
558 |
|
|
return;
|
559 |
|
|
}
|
560 |
85ad3d82
|
Assos Assos
|
|
561 |
|
|
drupal_alter('date_popup_pre_validate', $element, $form_state, $input);
|
562 |
|
|
|
563 |
|
|
$granularity = date_format_order($element['#date_format']);
|
564 |
|
|
$date_granularity = date_popup_date_granularity($element);
|
565 |
|
|
$time_granularity = date_popup_time_granularity($element);
|
566 |
|
|
$has_time = date_has_time($granularity);
|
567 |
|
|
|
568 |
b720ea3e
|
Assos Assos
|
// @codingStandardsIgnoreStart
|
569 |
|
|
$label = '';
|
570 |
|
|
if (!empty($element['#date_title'])) {
|
571 |
|
|
$label = t($element['#date_title']);
|
572 |
|
|
}
|
573 |
|
|
elseif (!empty($element['#title'])) {
|
574 |
|
|
$label = t($element['#title']);
|
575 |
|
|
}
|
576 |
|
|
// @codingStandardsIgnoreEnd
|
577 |
85ad3d82
|
Assos Assos
|
$date = date_popup_input_date($element, $input);
|
578 |
|
|
|
579 |
|
|
// If the date has errors, display them.
|
580 |
|
|
// If something was input but there is no date, the date is invalid.
|
581 |
|
|
// If the field is empty and required, set error message and return.
|
582 |
|
|
$error_field = implode('][', $element['#parents']);
|
583 |
|
|
if (empty($date) || !empty($date->errors)) {
|
584 |
|
|
if (is_object($date) && !empty($date->errors)) {
|
585 |
|
|
$message = t('The value input for field %field is invalid:', array('%field' => $label));
|
586 |
|
|
$message .= '<br />' . implode('<br />', $date->errors);
|
587 |
|
|
form_set_error($error_field, $message);
|
588 |
|
|
return;
|
589 |
|
|
}
|
590 |
|
|
if (!empty($input['date'])) {
|
591 |
|
|
$message = t('The value input for field %field is invalid.', array('%field' => $label));
|
592 |
|
|
form_set_error($error_field, $message);
|
593 |
|
|
return;
|
594 |
|
|
}
|
595 |
|
|
if ($element['#required']) {
|
596 |
|
|
$message = t('A valid date is required for %title.', array('%title' => $label));
|
597 |
|
|
form_set_error($error_field, $message);
|
598 |
|
|
return;
|
599 |
|
|
}
|
600 |
|
|
}
|
601 |
|
|
|
602 |
|
|
// If the created date is valid, set it.
|
603 |
|
|
$value = !empty($date) ? $date->format(DATE_FORMAT_DATETIME) : NULL;
|
604 |
|
|
form_set_value($element, $value, $form_state);
|
605 |
|
|
}
|
606 |
|
|
|
607 |
|
|
/**
|
608 |
|
|
* Helper function for extracting a date value out of user input.
|
609 |
|
|
*
|
610 |
b720ea3e
|
Assos Assos
|
* @param bool $auto_complete
|
611 |
85ad3d82
|
Assos Assos
|
* Should we add a time value to complete the date if there is no time?
|
612 |
|
|
* Useful anytime the time value is optional.
|
613 |
|
|
*/
|
614 |
|
|
function date_popup_input_date($element, $input, $auto_complete = FALSE) {
|
615 |
|
|
if (empty($input) || !is_array($input) || !array_key_exists('date', $input) || empty($input['date'])) {
|
616 |
|
|
return NULL;
|
617 |
|
|
}
|
618 |
|
|
date_popup_add();
|
619 |
|
|
$granularity = date_format_order($element['#date_format']);
|
620 |
|
|
$has_time = date_has_time($granularity);
|
621 |
|
|
$flexible = !empty($element['#date_flexible']) ? $element['#date_flexible'] : 0;
|
622 |
|
|
|
623 |
|
|
$format = date_popup_date_format($element);
|
624 |
|
|
$format .= $has_time ? ' ' . date_popup_time_format($element) : '';
|
625 |
b720ea3e
|
Assos Assos
|
$datetime = trim($input['date']);
|
626 |
|
|
$datetime .= $has_time ? ' ' . trim($input['time']) : '';
|
627 |
85ad3d82
|
Assos Assos
|
$date = new DateObject($datetime, $element['#date_timezone'], $format);
|
628 |
|
|
if (is_object($date)) {
|
629 |
|
|
$date->limitGranularity($granularity);
|
630 |
|
|
if ($date->validGranularity($granularity, $flexible)) {
|
631 |
|
|
date_increment_round($date, $element['#date_increment']);
|
632 |
|
|
}
|
633 |
|
|
return $date;
|
634 |
|
|
}
|
635 |
|
|
return NULL;
|
636 |
|
|
}
|
637 |
|
|
|
638 |
|
|
/**
|
639 |
|
|
* Allowable time formats.
|
640 |
|
|
*/
|
641 |
|
|
function date_popup_time_formats($with_seconds = FALSE) {
|
642 |
|
|
return array(
|
643 |
|
|
'H:i:s',
|
644 |
|
|
'h:i:sA',
|
645 |
b720ea3e
|
Assos Assos
|
);
|
646 |
85ad3d82
|
Assos Assos
|
}
|
647 |
|
|
|
648 |
|
|
/**
|
649 |
|
|
* Format options array.
|
650 |
|
|
*
|
651 |
|
|
* TODO Remove any formats not supported by the widget, if any.
|
652 |
|
|
*/
|
653 |
|
|
function date_popup_formats() {
|
654 |
b720ea3e
|
Assos Assos
|
// Load short date formats.
|
655 |
|
|
$formats = system_get_date_formats('short');
|
656 |
|
|
|
657 |
|
|
// Load custom date formats.
|
658 |
|
|
if ($formats_custom = system_get_date_formats('custom')) {
|
659 |
|
|
$formats = array_merge($formats, $formats_custom);
|
660 |
|
|
}
|
661 |
|
|
|
662 |
|
|
$formats = str_replace('i', 'i:s', array_keys($formats));
|
663 |
85ad3d82
|
Assos Assos
|
$formats = drupal_map_assoc($formats);
|
664 |
b720ea3e
|
Assos Assos
|
|
665 |
85ad3d82
|
Assos Assos
|
return $formats;
|
666 |
|
|
}
|
667 |
|
|
|
668 |
|
|
/**
|
669 |
|
|
* Recreate a date format string so it has the values popup expects.
|
670 |
|
|
*
|
671 |
|
|
* @param string $format
|
672 |
b720ea3e
|
Assos Assos
|
* A normal date format string, like Y-m-d
|
673 |
|
|
*
|
674 |
85ad3d82
|
Assos Assos
|
* @return string
|
675 |
|
|
* A format string in popup format, like YMD-, for the
|
676 |
|
|
* earlier 'calendar' version, or m/d/Y for the later 'datepicker'
|
677 |
|
|
* version.
|
678 |
|
|
*/
|
679 |
|
|
function date_popup_format_to_popup($format) {
|
680 |
|
|
if (empty($format)) {
|
681 |
|
|
$format = 'Y-m-d';
|
682 |
|
|
}
|
683 |
|
|
$replace = date_popup_datepicker_format_replacements();
|
684 |
|
|
return strtr($format, $replace);
|
685 |
|
|
}
|
686 |
|
|
|
687 |
|
|
/**
|
688 |
|
|
* Recreate a time format string so it has the values popup expects.
|
689 |
|
|
*
|
690 |
|
|
* @param string $format
|
691 |
b720ea3e
|
Assos Assos
|
* A normal time format string, like h:i (a)
|
692 |
|
|
*
|
693 |
85ad3d82
|
Assos Assos
|
* @return string
|
694 |
b720ea3e
|
Assos Assos
|
* A format string that the popup can accept like h:i a
|
695 |
85ad3d82
|
Assos Assos
|
*/
|
696 |
|
|
function date_popup_format_to_popup_time($format, $timepicker = NULL) {
|
697 |
|
|
if (empty($format)) {
|
698 |
|
|
$format = 'H:i';
|
699 |
|
|
}
|
700 |
b720ea3e
|
Assos Assos
|
$symbols = array(
|
701 |
|
|
'/',
|
702 |
|
|
'-',
|
703 |
|
|
' .',
|
704 |
|
|
',',
|
705 |
|
|
'F',
|
706 |
|
|
'M',
|
707 |
|
|
'l',
|
708 |
|
|
'z',
|
709 |
|
|
'w',
|
710 |
|
|
'W',
|
711 |
|
|
'd',
|
712 |
|
|
'j',
|
713 |
|
|
'm',
|
714 |
|
|
'n',
|
715 |
|
|
'y',
|
716 |
|
|
'Y',
|
717 |
|
|
);
|
718 |
|
|
$format = str_replace($symbols, '', $format);
|
719 |
85ad3d82
|
Assos Assos
|
$format = strtr($format, date_popup_timepicker_format_replacements($timepicker));
|
720 |
|
|
return $format;
|
721 |
|
|
}
|
722 |
|
|
|
723 |
|
|
/**
|
724 |
|
|
* Reconstruct popup format string into normal format string.
|
725 |
|
|
*
|
726 |
|
|
* @param string $format
|
727 |
b720ea3e
|
Assos Assos
|
* A string in popup format, like YMD-
|
728 |
|
|
*
|
729 |
85ad3d82
|
Assos Assos
|
* @return string
|
730 |
b720ea3e
|
Assos Assos
|
* A normal date format string, like Y-m-d
|
731 |
85ad3d82
|
Assos Assos
|
*/
|
732 |
|
|
function date_popup_popup_to_format($format) {
|
733 |
|
|
$replace = array_flip(date_popup_datepicker_format_replacements());
|
734 |
|
|
return strtr($format, $replace);
|
735 |
|
|
}
|
736 |
|
|
|
737 |
|
|
/**
|
738 |
|
|
* Return a map of format replacements required for a given timepicker.
|
739 |
|
|
*
|
740 |
|
|
* Client-side time entry plugins don't support all possible date formats.
|
741 |
|
|
* This function returns a map of format replacements required to change any
|
742 |
|
|
* input format into one that the given timepicker can support.
|
743 |
|
|
*
|
744 |
b720ea3e
|
Assos Assos
|
* @param string $timepicker
|
745 |
85ad3d82
|
Assos Assos
|
* The time entry plugin being used: either 'wvega' or 'default'.
|
746 |
b720ea3e
|
Assos Assos
|
*
|
747 |
|
|
* @return array
|
748 |
85ad3d82
|
Assos Assos
|
* A map of replacements.
|
749 |
|
|
*/
|
750 |
|
|
function date_popup_timepicker_format_replacements($timepicker = 'default') {
|
751 |
|
|
switch ($timepicker) {
|
752 |
|
|
case 'wvega':
|
753 |
b720ea3e
|
Assos Assos
|
// The wvega timepicker only supports uppercase AM/PM.
|
754 |
|
|
return array('a' => 'A');
|
755 |
|
|
|
756 |
85ad3d82
|
Assos Assos
|
default:
|
757 |
b720ea3e
|
Assos Assos
|
// The default timeEntry plugin requires leading zeros.
|
758 |
|
|
return array('G' => 'H', 'g' => 'h');
|
759 |
85ad3d82
|
Assos Assos
|
}
|
760 |
|
|
}
|
761 |
|
|
|
762 |
|
|
/**
|
763 |
|
|
* The format replacement patterns for the new datepicker.
|
764 |
|
|
*/
|
765 |
|
|
function date_popup_datepicker_format_replacements() {
|
766 |
|
|
return array(
|
767 |
b720ea3e
|
Assos Assos
|
'd' => 'dd',
|
768 |
|
|
'j' => 'd',
|
769 |
|
|
'l' => 'DD',
|
770 |
|
|
'D' => 'D',
|
771 |
|
|
'm' => 'mm',
|
772 |
|
|
'n' => 'm',
|
773 |
|
|
'F' => 'MM',
|
774 |
|
|
'M' => 'M',
|
775 |
|
|
'Y' => 'yy',
|
776 |
|
|
'y' => 'y',
|
777 |
85ad3d82
|
Assos Assos
|
);
|
778 |
|
|
}
|
779 |
|
|
|
780 |
|
|
/**
|
781 |
|
|
* Format a date popup element.
|
782 |
|
|
*
|
783 |
|
|
* Use a class that will float date and time next to each other.
|
784 |
|
|
*/
|
785 |
|
|
function theme_date_popup($vars) {
|
786 |
|
|
$element = $vars['element'];
|
787 |
|
|
$attributes = !empty($element['#wrapper_attributes']) ? $element['#wrapper_attributes'] : array('class' => array());
|
788 |
|
|
$attributes['class'][] = 'container-inline-date';
|
789 |
b720ea3e
|
Assos Assos
|
// If there is no description, the floating date
|
790 |
|
|
// elements need some extra padding below them.
|
791 |
85ad3d82
|
Assos Assos
|
$wrapper_attributes = array('class' => array('date-padding'));
|
792 |
|
|
if (empty($element['date']['#description'])) {
|
793 |
|
|
$wrapper_attributes['class'][] = 'clearfix';
|
794 |
|
|
}
|
795 |
b720ea3e
|
Assos Assos
|
// Add an wrapper to mimic the way a single value field works,
|
796 |
|
|
// for ease in using #states.
|
797 |
85ad3d82
|
Assos Assos
|
if (isset($element['#children'])) {
|
798 |
b720ea3e
|
Assos Assos
|
$element['#children'] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($wrapper_attributes) . '>' . $element['#children'] . '</div>';
|
799 |
85ad3d82
|
Assos Assos
|
}
|
800 |
b720ea3e
|
Assos Assos
|
return '<div ' . drupal_attributes($attributes) . '>' . theme('form_element', $element) . '</div>';
|
801 |
85ad3d82
|
Assos Assos
|
}
|
802 |
|
|
|
803 |
|
|
/**
|
804 |
|
|
* Implements hook_menu().
|
805 |
|
|
*/
|
806 |
|
|
function date_popup_menu() {
|
807 |
|
|
$items = array();
|
808 |
|
|
// TODO Fix this later.
|
809 |
|
|
$items['admin/config/date/date_popup'] = array(
|
810 |
|
|
'title' => 'Date Popup',
|
811 |
|
|
'description' => 'Configure the Date Popup settings.',
|
812 |
|
|
'page callback' => 'drupal_get_form',
|
813 |
|
|
'page arguments' => array('date_popup_settings'),
|
814 |
|
|
'access callback' => 'user_access',
|
815 |
|
|
'access arguments' => array('administer site configuration'),
|
816 |
|
|
);
|
817 |
|
|
return $items;
|
818 |
|
|
}
|
819 |
|
|
/**
|
820 |
|
|
* General configuration form for controlling the Date Popup behaviour.
|
821 |
|
|
*/
|
822 |
|
|
function date_popup_settings() {
|
823 |
|
|
$wvega_available = date_popup_get_wvega_path();
|
824 |
|
|
$preferred_timepicker = date_popup_get_preferred_timepicker();
|
825 |
|
|
|
826 |
|
|
$form['#prefix'] = t('<p>The Date Popup module allows for manual time entry or use of a jQuery timepicker plugin. The Date module comes with a default jQuery timepicker which is already installed. The module also supports a dropdown timepicker that must be downloaded separately. The dropdown timepicker will not appear as an option until the code is available in the libraries folder. If you do not want to use a jQuery timepicker, you can choose the "Manual time entry" option below and users will get a regular textfield instead.</p>');
|
827 |
|
|
$form['date_popup_timepicker'] = array(
|
828 |
|
|
'#type' => 'select',
|
829 |
|
|
'#options' => array(
|
830 |
|
|
'default' => t('Use default jQuery timepicker'),
|
831 |
b720ea3e
|
Assos Assos
|
'wvega' => t('Use dropdown timepicker'),
|
832 |
|
|
'none' => t('Manual time entry, no jQuery timepicker'),
|
833 |
85ad3d82
|
Assos Assos
|
),
|
834 |
|
|
'#title' => t('Timepicker'),
|
835 |
|
|
'#default_value' => variable_get('date_popup_timepicker', $preferred_timepicker),
|
836 |
|
|
);
|
837 |
|
|
|
838 |
|
|
if (!$wvega_available) {
|
839 |
|
|
$form['#prefix'] .= t('<p>To install the dropdown timepicker, create a <code>!directory</code> directory in your site installation. Then visit <a href="@download">@download</a>, download the latest copy and unzip it. You will see files with names like jquery.timepicker-1.1.2.js and jquery.timepicker-1.1.2.css. Rename them to jquery.timepicker.js and jquery.timepicker.css and copy them into <code>!directory</code>.</p>', array('!directory' => 'sites/all/libraries/wvega-timepicker', '@download' => 'https://github.com/wvega/timepicker/archives/master'));
|
840 |
|
|
unset($form['date_popup_timepicker']['#options']['wvega']);
|
841 |
|
|
}
|
842 |
|
|
|
843 |
|
|
$css = <<<EOM
|
844 |
|
|
/* ___________ IE6 IFRAME FIX ________ */
|
845 |
|
|
.ui-datepicker-cover {
|
846 |
|
|
display: none; /*sorry for IE5*/
|
847 |
|
|
display/**/: block; /*sorry for IE5*/
|
848 |
|
|
position: absolute; /*must have*/
|
849 |
|
|
z-index: -1; /*must have*/
|
850 |
|
|
filter: mask(); /*must have*/
|
851 |
|
|
top: -4px; /*must have*/
|
852 |
|
|
left: -4px; /*must have*/ /* LTR */
|
853 |
|
|
width: 200px; /*must have*/
|
854 |
|
|
height: 200px; /*must have*/
|
855 |
|
|
}
|
856 |
|
|
EOM;
|
857 |
|
|
|
858 |
b720ea3e
|
Assos Assos
|
$form['#suffix'] = t('<p>The Date Popup calendar includes some css for IE6 that breaks css validation. Since IE 6 is now superceded by IE 7, 8, and 9, the special css for IE 6 has been removed from the regular css used by the Date Popup. If you find you need that css after all, you can add it back in your theme. Look at the way the Garland theme adds special IE-only css in in its page.tpl.php file. The css you need is:</p>') . '<blockquote><PRE>' . $css . '</PRE></blockquote>';
|
859 |
85ad3d82
|
Assos Assos
|
|
860 |
|
|
return system_settings_form($form);
|
861 |
|
|
} |