wip swap out bootstrap datepicker for flatpickr
This commit is contained in:
@@ -1,38 +1,84 @@
|
||||
function dateTimePickerController($scope, notificationsService, assetsService, angularHelper, userService, $element, dateHelper) {
|
||||
|
||||
//setup the default config
|
||||
var config = {
|
||||
pickDate: true,
|
||||
pickTime: true,
|
||||
useSeconds: true,
|
||||
format: "YYYY-MM-DD HH:mm:ss",
|
||||
icons: {
|
||||
time: "icon-time",
|
||||
date: "icon-calendar",
|
||||
up: "icon-chevron-up",
|
||||
down: "icon-chevron-down"
|
||||
}
|
||||
let flatPickr = null;
|
||||
|
||||
};
|
||||
function onInit() {
|
||||
|
||||
$scope.hasDatetimePickerValue = $scope.model.value ? true : false;
|
||||
$scope.model.datetimePickerValue = null;
|
||||
$scope.serverTime = null;
|
||||
$scope.serverTimeNeedsOffsetting = false;
|
||||
|
||||
// setup the default config
|
||||
var config = {
|
||||
pickDate: true,
|
||||
pickTime: true,
|
||||
useSeconds: true,
|
||||
format: "YYYY-MM-DD HH:mm:ss",
|
||||
icons: {
|
||||
time: "icon-time",
|
||||
date: "icon-calendar",
|
||||
up: "icon-chevron-up",
|
||||
down: "icon-chevron-down"
|
||||
}
|
||||
};
|
||||
|
||||
// map the user config
|
||||
$scope.model.config = angular.extend(config, $scope.model.config);
|
||||
|
||||
// ensure the format doesn't get overwritten with an empty string
|
||||
if ($scope.model.config.format === "" || $scope.model.config.format === undefined || $scope.model.config.format === null) {
|
||||
$scope.model.config.format = $scope.model.config.pickTime ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD";
|
||||
}
|
||||
|
||||
// check whether a server time offset is needed
|
||||
if (Umbraco.Sys.ServerVariables.application.serverTimeOffset !== undefined) {
|
||||
// Will return something like 120
|
||||
var serverOffset = Umbraco.Sys.ServerVariables.application.serverTimeOffset;
|
||||
|
||||
// Will return something like -120
|
||||
var localOffset = new Date().getTimezoneOffset();
|
||||
|
||||
// If these aren't equal then offsetting is needed
|
||||
// note the minus in front of serverOffset needed
|
||||
// because C# and javascript return the inverse offset
|
||||
$scope.serverTimeNeedsOffsetting = (-serverOffset !== localOffset);
|
||||
}
|
||||
|
||||
//get the current user to see if we can localize this picker
|
||||
userService.getCurrentUser().then(function (user) {
|
||||
|
||||
const dateFormat = $scope.model.config.pickTime ? "Y-m-d H:i:S" : "Y-m-d";
|
||||
|
||||
// date picker config
|
||||
$scope.datePickerConfig = {
|
||||
enableTime: $scope.model.config.pickTime,
|
||||
dateFormat: dateFormat,
|
||||
time_24hr: true
|
||||
};
|
||||
|
||||
$scope.model.config.language = user.locale;
|
||||
|
||||
setDatePickerVal();
|
||||
|
||||
});
|
||||
|
||||
//map the user config
|
||||
$scope.model.config = angular.extend(config, $scope.model.config);
|
||||
//ensure the format doesn't get overwritten with an empty string
|
||||
if ($scope.model.config.format === "" || $scope.model.config.format === undefined || $scope.model.config.format === null) {
|
||||
$scope.model.config.format = $scope.model.config.pickTime ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD";
|
||||
}
|
||||
|
||||
$scope.hasDatetimePickerValue = $scope.model.value ? true : false;
|
||||
$scope.datetimePickerValue = null;
|
||||
$scope.clearDate = function() {
|
||||
$scope.hasDatetimePickerValue = false;
|
||||
$scope.model.datetimePickerValue = null;
|
||||
$scope.model.value = null;
|
||||
$scope.datePickerForm.datepicker.$setValidity("pickerError", true);
|
||||
}
|
||||
|
||||
//hide picker if clicking on the document
|
||||
$scope.hidePicker = function () {
|
||||
//$element.find("div:first").datetimepicker("hide");
|
||||
// Sometimes the statement above fails and generates errors in the browser console. The following statements fix that.
|
||||
var dtp = $element.find("div:first");
|
||||
if (dtp && dtp.datetimepicker) {
|
||||
dtp.datetimepicker("hide");
|
||||
}
|
||||
$scope.datePickerSetup = function(instance) {
|
||||
flatPickr = instance;
|
||||
};
|
||||
|
||||
$scope.datePickerChange = function(date) {
|
||||
setDate(date);
|
||||
setDatePickerVal();
|
||||
};
|
||||
|
||||
//here we declare a special method which will be called whenever the value has changed from the server
|
||||
@@ -44,53 +90,45 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
|
||||
var newDate = moment(newVal);
|
||||
|
||||
if (newDate.isAfter(minDate)) {
|
||||
applyDate({ date: moment(newVal) });
|
||||
setDate(newVal);
|
||||
} else {
|
||||
$scope.clearDate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//handles the date changing via the date picker
|
||||
function applyDate(e) {
|
||||
|
||||
function setDate(date) {
|
||||
const momentDate = moment(date);
|
||||
angularHelper.safeApply($scope, function() {
|
||||
// when a date is changed, update the model
|
||||
if (e.date && e.date.isValid()) {
|
||||
if (momentDate && momentDate.isValid()) {
|
||||
$scope.datePickerForm.datepicker.$setValidity("pickerError", true);
|
||||
$scope.hasDatetimePickerValue = true;
|
||||
$scope.datetimePickerValue = e.date.format($scope.model.config.format);
|
||||
$scope.model.datetimePickerValue = momentDate.format($scope.model.config.format);
|
||||
}
|
||||
else {
|
||||
$scope.hasDatetimePickerValue = false;
|
||||
$scope.datetimePickerValue = null;
|
||||
}
|
||||
|
||||
setModelValue();
|
||||
|
||||
if (!$scope.model.config.pickTime) {
|
||||
$element.find("div:first").datetimepicker("hide", 0);
|
||||
$scope.model.datetimePickerValue = null;
|
||||
}
|
||||
updateModelValue(date);
|
||||
});
|
||||
}
|
||||
|
||||
//sets the scope model value accordingly - this is the value to be sent up to the server and depends on
|
||||
// if the picker is configured to offset time. We always format the date/time in a specific format for sending
|
||||
// to the server, this is different from the format used to display the date/time.
|
||||
function setModelValue() {
|
||||
function updateModelValue(date) {
|
||||
const momentDate = moment(date);
|
||||
if ($scope.hasDatetimePickerValue) {
|
||||
var elementData = $element.find("div:first").data().DateTimePicker;
|
||||
if ($scope.model.config.pickTime) {
|
||||
//check if we are supposed to offset the time
|
||||
if ($scope.model.value && Object.toBoolean($scope.model.config.offsetTime) && Umbraco.Sys.ServerVariables.application.serverTimeOffset !== undefined) {
|
||||
$scope.model.value = dateHelper.convertToServerStringTime(elementData.getDate(), Umbraco.Sys.ServerVariables.application.serverTimeOffset);
|
||||
$scope.serverTime = dateHelper.convertToServerStringTime(elementData.getDate(), Umbraco.Sys.ServerVariables.application.serverTimeOffset, "YYYY-MM-DD HH:mm:ss Z");
|
||||
$scope.model.value = dateHelper.convertToServerStringTime(momentDate, Umbraco.Sys.ServerVariables.application.serverTimeOffset);
|
||||
$scope.serverTime = dateHelper.convertToServerStringTime(momentDate, Umbraco.Sys.ServerVariables.application.serverTimeOffset, "YYYY-MM-DD HH:mm:ss Z");
|
||||
}
|
||||
else {
|
||||
$scope.model.value = elementData.getDate().format("YYYY-MM-DD HH:mm:ss");
|
||||
$scope.model.value = momentDate.format("YYYY-MM-DD HH:mm:ss");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$scope.model.value = elementData.getDate().format("YYYY-MM-DD");
|
||||
$scope.model.value = momentDate.format("YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -99,7 +137,7 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
|
||||
}
|
||||
|
||||
/** Sets the value of the date picker control adn associated viewModel objects based on the model value */
|
||||
function setDatePickerVal(element) {
|
||||
function setDatePickerVal() {
|
||||
if ($scope.model.value) {
|
||||
var dateVal;
|
||||
//check if we are supposed to offset the time
|
||||
@@ -112,98 +150,21 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
|
||||
//create a normal moment , no offset required
|
||||
var dateVal = $scope.model.value ? moment($scope.model.value, "YYYY-MM-DD HH:mm:ss") : moment();
|
||||
}
|
||||
|
||||
element.datetimepicker("setValue", dateVal);
|
||||
$scope.datetimePickerValue = dateVal.format($scope.model.config.format);
|
||||
$scope.model.datetimePickerValue = dateVal.format($scope.model.config.format);
|
||||
}
|
||||
else {
|
||||
$scope.clearDate();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.clearDate = function() {
|
||||
$scope.hasDatetimePickerValue = false;
|
||||
$scope.datetimePickerValue = null;
|
||||
$scope.model.value = null;
|
||||
$scope.datePickerForm.datepicker.$setValidity("pickerError", true);
|
||||
}
|
||||
|
||||
$scope.serverTime = null;
|
||||
$scope.serverTimeNeedsOffsetting = false;
|
||||
if (Umbraco.Sys.ServerVariables.application.serverTimeOffset !== undefined) {
|
||||
// Will return something like 120
|
||||
var serverOffset = Umbraco.Sys.ServerVariables.application.serverTimeOffset;
|
||||
|
||||
// Will return something like -120
|
||||
var localOffset = new Date().getTimezoneOffset();
|
||||
|
||||
// If these aren't equal then offsetting is needed
|
||||
// note the minus in front of serverOffset needed
|
||||
// because C# and javascript return the inverse offset
|
||||
$scope.serverTimeNeedsOffsetting = (-serverOffset !== localOffset);
|
||||
}
|
||||
|
||||
//get the current user to see if we can localize this picker
|
||||
userService.getCurrentUser().then(function (user) {
|
||||
|
||||
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', $scope).then(function() {
|
||||
|
||||
var filesToLoad = ["lib/datetimepicker/bootstrap-datetimepicker.js"];
|
||||
|
||||
|
||||
$scope.model.config.language = user.locale;
|
||||
|
||||
|
||||
assetsService.load(filesToLoad, $scope).then(
|
||||
function () {
|
||||
//The Datepicker js and css files are available and all components are ready to use.
|
||||
|
||||
// Get the id of the datepicker button that was clicked
|
||||
var pickerId = $scope.model.alias;
|
||||
|
||||
var element = $element.find("div:first");
|
||||
|
||||
// Create the datepicker and add a changeDate eventlistener
|
||||
element
|
||||
.datetimepicker(angular.extend({ useCurrent: true }, $scope.model.config))
|
||||
.on("dp.change", applyDate)
|
||||
.on("dp.error", function(a, b, c) {
|
||||
$scope.hasDatetimePickerValue = false;
|
||||
$scope.datePickerForm.datepicker.$setValidity("pickerError", false);
|
||||
});
|
||||
|
||||
$(document).bind("click", $scope.hidePicker);
|
||||
|
||||
setDatePickerVal(element);
|
||||
|
||||
element.find("input").bind("blur", function() {
|
||||
//we need to force an apply here
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
$scope.$watch("model.value", function(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
$scope.hasDatetimePickerValue = newVal ? true : false;
|
||||
setDatePickerVal(element);
|
||||
}
|
||||
});
|
||||
|
||||
var unsubscribe = $scope.$on("formSubmitting", function (ev, args) {
|
||||
setModelValue();
|
||||
});
|
||||
|
||||
//Ensure to remove the event handler when this instance is destroyted
|
||||
$scope.$on('$destroy', function () {
|
||||
element.find("input").unbind("blur");
|
||||
element.datetimepicker("destroy");
|
||||
unsubscribe();
|
||||
$(document).unbind("click", $scope.hidePicker);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$watch("model.value", function(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
$scope.hasDatetimePickerValue = newVal ? true : false;
|
||||
setDatePickerVal();
|
||||
}
|
||||
});
|
||||
|
||||
onInit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
<div class="umb-property-editor umb-datepicker" ng-controller="Umbraco.PropertyEditors.DatepickerController">
|
||||
|
||||
<ng-form name="datePickerForm">
|
||||
<div class="input-append date datepicker" style="position: relative;" id="datepicker{{model.alias}}">
|
||||
|
||||
<input name="datepicker" data-format="{{model.config.format}}" id="{{model.alias}}" type="text"
|
||||
ng-model="datetimePickerValue"
|
||||
ng-required="model.validation.mandatory"
|
||||
val-server="value"
|
||||
class="datepickerinput" />
|
||||
<div id="datepicker{{model.alias}}">
|
||||
|
||||
<span class="add-on">
|
||||
<i class="icon-calendar"></i>
|
||||
</span>
|
||||
<umb-flatpickr
|
||||
ng-model="model.value"
|
||||
options="datePickerConfig"
|
||||
on-setup="datePickerSetup(fpItem)"
|
||||
on-change="datePickerChange(dateStr)">
|
||||
|
||||
<div class="input-append">
|
||||
<input
|
||||
name="datepicker"
|
||||
id="{{model.alias}}"
|
||||
type="text"
|
||||
ng-model="model.datetimePickerValue"
|
||||
ng-required="model.validation.mandatory"
|
||||
val-server="value"
|
||||
class="datepickerinput">
|
||||
<span class="add-on">
|
||||
<i class="icon-calendar"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</umb-flatpickr>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -29,5 +42,16 @@
|
||||
<a href ng-click="clearDate()"><i class="icon-delete"></i><small><localize key="content_removeDate">Clear date</localize></small></a>
|
||||
</p>
|
||||
|
||||
<div style="margin-top: 10px;">
|
||||
<div>
|
||||
<div class="bold">model.value</div>
|
||||
{{model.value}}
|
||||
</div>
|
||||
<div>
|
||||
<div class="bold">Date time picker value</div>
|
||||
{{model.datetimePickerValue}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user