wip swap out bootstrap datepicker for flatpickr

This commit is contained in:
Mads Rasmussen
2018-11-16 14:07:41 +01:00
parent 31969cd767
commit e84cbc7e19
2 changed files with 130 additions and 145 deletions

View File

@@ -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();
}

View File

@@ -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>