Permalink
Browse files

feature(forms): moves datepicker init to AMD and improves dev usability

Datepicker initialization now takes place in an AMD module on per input basis, which allows
plugin to configure datepicker options by passing datepicker_options to the input view.
  • Loading branch information...
hypeJunction committed Dec 13, 2015
1 parent c4fb5eb commit 15c2686b846a82d4a634bcba4e3b7adf99d057b1
View
@@ -37,6 +37,8 @@ elgg.ui.init = function () {
// Allow element to be highlighted using CSS if its id is found from the URL
var elementId = elgg.getSelectorFromUrlFragment(document.URL);
$(elementId).addClass('elgg-state-highlight');
elgg.ui.initDatePicker();
};
/**
@@ -331,39 +333,15 @@ elgg.ui.loginHandler = function(hook, type, params, options) {
* @return void
* @requires jqueryui.datepicker
*/
elgg.ui.initDatePicker = function() {
function loadDatePicker() {
$('.elgg-input-date').datepicker({
// ISO-8601
dateFormat: 'yy-mm-dd',
onSelect: function(dateText) {
if ($(this).is('.elgg-input-timestamp')) {
// convert to unix timestamp
var dateParts = dateText.split("-");
var timestamp = Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]);
timestamp = timestamp / 1000;
var id = $(this).attr('id');
$('input[name="' + id + '"]').val(timestamp);
}
},
nextText: '»',
prevText: '«',
changeMonth: true,
changeYear: true
});
}
if (!$('.elgg-input-date').length) {
elgg.ui.initDatePicker = function () {
var selector = '.elgg-input-date:not([data-datepicker-opts])';
if (!$(selector).length) {
return;
}
// require language module if necessary
var deps = [];
if (elgg.get_language() != 'en') {
deps.push('jquery-ui/i18n/datepicker-'+ elgg.get_language() + '.min');
}
require(deps, loadDatePicker);
elgg.deprecated_notice('elgg.ui.initDatePicker() has been deprecated. Use input/date AMD module instead', '2.1');
require(['input/date'], function (datepicker) {
datepicker.init(selector);
});
};
/**
@@ -476,6 +454,5 @@ elgg.ui.initAccessInputs = function () {
};
elgg.register_hook_handler('init', 'system', elgg.ui.init);
elgg.register_hook_handler('init', 'system', elgg.ui.initDatePicker);
elgg.register_hook_handler('getOptions', 'ui.popup', elgg.ui.loginHandler);
elgg.ui.registerTogglableMenuItems('add-friend', 'remove-friend');
@@ -304,6 +304,7 @@
}
.ui-datepicker-inline {
box-shadow: none;
max-width: 225px;
}
.ui-datepicker-header {
@@ -103,6 +103,23 @@
'label' => 'Date input (.elgg-input-date):',
));
$year = date('Y');
echo elgg_view_input('date', array(
'name' => 'f12-custom',
'id' => 'f12-custom',
'value' => "$year/02/01",
'timestamp' => true,
'datepicker_options' => array(
'dateFormat' => 'yy/mm/dd',
'changeMonth' => false,
'changeYear' => false,
'minDate' => "$year/01/15",
'maxDate' => "$year/02/15",
),
'label' => 'Date input (.elgg-input-date) with custom options:',
'help' => 'Select a date from 15 Jan to 15 Feb',
));
echo elgg_view_input('userpicker', array(
'name' => 'f13',
'id' => 'f13',
@@ -660,6 +660,10 @@
background: #ddd;
}
.ui-datepicker-inline {
max-width: 225px;
}
/* ***************************************
AUTOCOMPLETE
*************************************** */
@@ -302,6 +302,7 @@
}
.ui-datepicker-inline {
box-shadow: none;
max-width: 225px;
}
.ui-datepicker-header {
@@ -0,0 +1,71 @@
define(function (require) {
var elgg = require('elgg');
var $ = require('jquery');
require('jquery-ui');
// the language module may need loading
var i18n_ready = $.Deferred();
if (elgg.get_language() === 'en') {
i18n_ready.resolve();
} else {
require(['jquery-ui/i18n/datepicker-' + elgg.get_language() + '.min'], function () {
i18n_ready.resolve();
}, function () {
// if load fails (e.g. lang code mismatch), carry on with English
i18n_ready.resolve();
});
}
var datepicker = {
/**
* Initialize the date picker on elements defined by the selector
*
* If the class .elgg-input-timestamp is set on the element, the onSelect
* method converts the date text to a UNIX timestamp in seconds. That value is
* stored in a hidden element and submitted with the form. Note that the UNIX
* timestamp is normalized to start of the day at UTC, so you may need to use
* timezone offsets if you expect a different timezone. Timestamp is determined
* by the selected values of the datepicker instance, and is therefore agnostic
* to the dateFormat option.
*
* @param {string} selector Element selector
* @return void
* @requires jqueryui.datepicker
*/
init: function (selector) {
if (!$(selector).length) {
return;
}
var defaults = {
dateFormat: 'yy-mm-dd',
nextText: '»',
prevText: '«',
changeMonth: true,
changeYear: true
};
$(selector).each(function () {
var $elem = $(this);
var opts = $elem.data('datepickerOpts') || {};
opts = $.extend({}, defaults, opts);
opts.onSelect = function (dateText, instance) {
if ($(this).is('.elgg-input-timestamp')) {
// convert to unix timestamp
var timestamp = Date.UTC(instance.selectedYear, instance.selectedMonth, instance.selectedDay);
timestamp = timestamp / 1000;
$('input[rel="' + this.id + '"]').val(timestamp);
}
};
// defer until language loaded
i18n_ready.then(function () {
$elem.datepicker(opts);
});
});
}
};
return datepicker;
});
@@ -14,9 +14,8 @@
* @uses $vars['value'] The current value, if any (as a unix timestamp)
* @uses $vars['class'] Additional CSS class
* @uses $vars['timestamp'] Store as a Unix timestamp in seconds. Default = false
* Note: you cannot use an id with the timestamp option.
* @uses $vars['datepicker_options'] An array of options to pass to the jQuery UI datepicker
*/
$vars['class'] = (array) elgg_extract('class', $vars, []);
$vars['class'][] = 'elgg-input-date';
@@ -36,10 +35,15 @@
unset($vars['timestamp']);
if ($timestamp) {
echo elgg_view('input/hidden', ['name' => $vars['name'], 'value' => $vars['value']]);
if (!isset($vars['id'])) {
$vars['id'] = $vars['name'];
}
echo elgg_view('input/hidden', [
'name' => $vars['name'],
'value' => $vars['value'],
'rel' => $vars['id'],
]);
$vars['class'][] = 'elgg-input-timestamp';
$vars['id'] = $vars['name'];
unset($vars['name']);
}
@@ -48,8 +52,20 @@
$vars['value'] = gmdate('Y-m-d', $vars['value']);
}
$datepicker_options = elgg_extract('datepicker_options', $vars);
$vars['data-datepicker-opts'] = $datepicker_options ? json_encode($datepicker_options) : '';
unset($vars['datepicker_options']);
echo elgg_format_element('input', $vars);
if (elgg_is_xhr()) {
echo elgg_format_element('script', null, 'elgg.ui.initDatePicker();');
if (isset($vars['id'])) {
$selector = "#{$vars['id']}";
} else {
$selector = ".elgg-input-date[name='{$vars['name']}']";
}
?>
<script>
require(['input/date'], function (datepicker) {
datepicker.init(<?= json_encode($selector) ?>);
});
</script>

0 comments on commit 15c2686

Please sign in to comment.