fng-bootstrap-datetime 0.12.0-beta.36 → 0.12.0-beta.360

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,7 +55,7 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
55
55
  hiddenDate: "=",
56
56
  datepickerTemplateUrl: "@",
57
57
  datepickerPopupTemplateUrl: "@",
58
- timepickerTemplateUrl: "@"
58
+ timepickerTemplateUrl: "@",
59
59
  },
60
60
  template: function (elem, attrs) {
61
61
  function dashCase(name) {
@@ -67,9 +67,10 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
67
67
  function createAttr(innerAttr, dateTimeAttrOpt) {
68
68
  var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
69
69
  if (attrs[dateTimeAttr]) {
70
- return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
71
- } else if (dateTimeAttr in attrs) { // attribute with an empty value such as "required"
72
- return dateTimeAttr + " ";
70
+ return `${dashCase(innerAttr)}="${attrs[dateTimeAttr]}" `;
71
+ } else if (dateTimeAttr in attrs) {
72
+ // attribute with an empty value such as "required"
73
+ return `${dateTimeAttr} `;
73
74
  } else {
74
75
  return '';
75
76
  }
@@ -78,18 +79,18 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
78
79
  function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt, defaultImpl) {
79
80
  var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
80
81
  if (attrs[dateTimeAttr]) {
81
- return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
82
+ return `${dashCase(innerAttr)}="${dateTimeAttr}({${funcArgs}})" `;
82
83
  } else {
83
- return angular.isDefined(defaultImpl) ? dashCase(innerAttr) + "=\"" + defaultImpl + "\"" : "";
84
+ return angular.isDefined(defaultImpl) ? `${dashCase(innerAttr)}="${defaultImpl}" ` : "";
84
85
  }
85
86
  }
86
87
 
87
88
  function createEvalAttr(innerAttr, dateTimeAttrOpt) {
88
89
  var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
89
90
  if (attrs[dateTimeAttr]) {
90
- return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
91
+ return `${dashCase(innerAttr)}="${attrs[dateTimeAttr]}" `;
91
92
  } else {
92
- return dashCase(innerAttr) + " ";
93
+ return `${dashCase(innerAttr)} `;
93
94
  }
94
95
  }
95
96
 
@@ -98,8 +99,11 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
98
99
  }
99
100
 
100
101
  var dateTmpl = "<div class=\"datetimepicker-wrapper\">" +
101
- "<input class=\"form-control\" type=\"text\" " +
102
+ "<input class=\"form-control\" " +
103
+ "type=\"text\" " +
102
104
  "name=\"datepicker\"" +
105
+ "autocomplete=\"off\"" +
106
+ 'aria-label="' + (attrs.name || attrs.ngModel).replace(/[\.,-]/g, ' ') + '"' +
103
107
  "ng-change=\"date_change($event)\" " +
104
108
  "is-open=\"innerDateOpened\" " +
105
109
  "datepicker-options=\"dateOptions\" " +
@@ -114,9 +118,9 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
114
118
  ["yearRange"],
115
119
  ["required"],
116
120
  ["showButtonBar"],
117
- ["ngHide", "hiddenDate"],
118
- ["ngReadonly", "readonlyDate"],
119
- ["ngDisabled", "disabledDate"]
121
+ ["ngHide", "hiddendate"],
122
+ ["ngReadonly", "readonlydate"],
123
+ ["ngDisabled", "disableddate"]
120
124
  ].reduce(createAttrConcat, '') +
121
125
  createFuncAttr("ngClick",
122
126
  "$event: $event, opened: opened",
@@ -143,8 +147,8 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
143
147
  ["required"],
144
148
  ["meredians"],
145
149
  ["mousewheel"],
146
- ["ngHide", "hiddenTime"],
147
- ["ngDisabled", "readonlyTime"]
150
+ ["ngHide", "hiddentime"],
151
+ ["ngDisabled", "readonlytime"]
148
152
  ].reduce(createAttrConcat, '') +
149
153
  createEvalAttr("showSpinners", "showSpinners") +
150
154
  createEvalAttr("templateUrl", "timepickerTemplateUrl") +
@@ -156,10 +160,10 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
156
160
  },
157
161
  controller: ['$scope', '$attrs',
158
162
  function ($scope, $attrs) {
159
- let form;
163
+ var form;
160
164
  function getForm() {
161
165
  if (!form) {
162
- let workingScope = $scope;
166
+ var workingScope = $scope;
163
167
  while (typeof workingScope.topLevelFormName !== "string" && workingScope.$parent) {
164
168
  workingScope = workingScope.$parent;
165
169
  }
@@ -167,6 +171,24 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
167
171
  }
168
172
  }
169
173
  getForm();
174
+ // ****************************************************
175
+ // HACK RIGHT HERE!
176
+ // For cases where formsAngular.elemSecurityFuncBinding is set to either "one-time" or "normal", the
177
+ // result of the call to handleReadOnlyDisabled() made by the fngUiBootstrapDatetimePicker directive might
178
+ // include reference(s) to two functions which our ancestor form scope should have been decorated with -
179
+ // isSecurelyDisabled and requiresDisabledChildren. Because our scope is isolated, these will be
180
+ // inaccessible to us unless we do the following...:
181
+ if (formsAngular.disabledSecurityFuncName) {
182
+ $scope.isSecurelyDisabled = $scope.$parent.isSecurelyDisabled;
183
+ $scope.requiresDisabledChildren = $scope.$parent.requiresDisabledChildren;
184
+ }
185
+ // as this is only going to work for disabled state arising from fng security, and not the case
186
+ // where an fng field has a string-valued readonly attribute that refers to a function on the parent
187
+ // scope, it's only a partial solution. the general solution would presumably be to replace our isolated
188
+ // scope definition with "scope:true", thus giving it full ancestor access. however, I gave
189
+ // that a quick try and found that it broke things, and it doesn't seem worth spending any more time
190
+ // on that right now.
191
+ // ****************************************************
170
192
  $scope.date_change = function () {
171
193
  // If we changed the date only, set the time (h,m) on it.
172
194
  // This is important in case the previous date was null.
@@ -177,13 +199,19 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
177
199
  $scope.ngModel.setHours(time.getHours(), time.getMinutes(), 0, 0);
178
200
  $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
179
201
  }
180
- form.$setDirty();
202
+ getForm();
203
+ if (form) {
204
+ form.$setDirty();
205
+ }
181
206
  };
182
207
  $scope.time_change = function () {
183
208
  if ($scope.ngModel && $scope.time) {
184
209
  $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes(), 0, 0);
185
210
  $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
186
- form.$setDirty();
211
+ getForm();
212
+ if (form) {
213
+ form.$setDirty();
214
+ }
187
215
  } // else the time is invalid, keep the current Date value in datepicker
188
216
  };
189
217
  $scope.open = function ($event) {
@@ -362,8 +390,8 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
362
390
  uiBootstrapDateModule.controller('fngUiBootstrapDatetimePickerCtrl',['$scope', function($scope) {
363
391
  $scope.dateOptions = {};
364
392
  }])
365
- .directive('fngUiBootstrapDatetimePicker', ['$compile', '$filter', 'pluginHelper', 'formMarkupHelper', 'cssFrameworkService',
366
- function ($compile, $filter, pluginHelper) {
393
+ .directive('fngUiBootstrapDatetimePicker', ['$compile', 'PluginHelperService',
394
+ function ($compile, PluginHelperService) {
367
395
  return {
368
396
  restrict: 'E',
369
397
  replace: true,
@@ -371,8 +399,8 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
371
399
  priority: 1,
372
400
  link: function (scope, element, attrs) {
373
401
  var template;
374
- var processedAttr = pluginHelper.extractFromAttr(attrs, 'fngUiBootstrapDatetimePicker');
375
- var overRiddenDefaults = {
402
+ var processedAttrs = PluginHelperService.extractFromAttr(attrs, 'fngUiBootstrapDatetimePicker', scope);
403
+ var overriddenDefaults = {
376
404
  'show-button-bar': false,
377
405
  'show-meridian': false,
378
406
  'date-format': 'dd/MM/yyyy'
@@ -381,35 +409,62 @@ angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bo
381
409
  // Set form to dirty when required. Works OK with existing records - hopefully new records will have other field types
382
410
  var watchField = attrs.model + '.' + attrs.fngFldName;
383
411
  var formName = attrs.fngOptName;
412
+ // The model value is normally a string or a Date, but can be something else (e.g. a number, or an invalid Date
413
+ // whose toISOString() throws), so compare on a representation that can always be produced
414
+ function comparable(val) {
415
+ if (typeof val === 'string') {
416
+ return val;
417
+ }
418
+ if (typeof val.toISOString === 'function') {
419
+ try {
420
+ return val.toISOString();
421
+ } catch (e) {
422
+ // Invalid Date - fall through
423
+ }
424
+ }
425
+ return String(val);
426
+ }
384
427
  scope.$watch(watchField, function (newVal, oldVal) {
385
428
  if (scope[formName] && newVal && oldVal && newVal !== oldVal) {
386
- var newComp = (typeof newVal === 'string') ? newVal : newVal.toISOString();
387
- var oldComp = (typeof oldVal === 'string') ? oldVal : oldVal.toISOString();
429
+ var newComp = comparable(newVal);
430
+ var oldComp = comparable(oldVal);
388
431
  if (newComp !== oldComp) {
389
432
  scope[formName].$setDirty();
390
433
  }
391
434
  }
392
435
  });
393
436
 
394
- overRiddenDefaults = Object.assign({}, overRiddenDefaults, processedAttr.directiveOptions);
395
- var overRiddenDateDefaults = {
437
+ overriddenDefaults = Object.assign({}, overriddenDefaults, processedAttrs.directiveOptions);
438
+ var overriddenDateDefaults = {
396
439
  showWeeks: false
397
440
  };
398
441
  var jsonDateOptions = {};
399
- if (processedAttr.directiveOptions['date-options']) {
400
- jsonDateOptions = JSON.parse(processedAttr.directiveOptions['date-options'].replace(/'/g, '"'));
442
+ if (processedAttrs.directiveOptions['date-options']) {
443
+ jsonDateOptions = JSON.parse(processedAttrs.directiveOptions['date-options'].replace(/'/g, '"'));
401
444
  }
402
- scope.dateOptions = Object.assign({}, overRiddenDateDefaults, jsonDateOptions);
403
- template = pluginHelper.buildInputMarkup(scope, attrs.model, processedAttr.info, processedAttr.options, false, false, function (buildingBlocks) {
404
- var str = '<div class="dtwrap"><datetimepicker ' + buildingBlocks.common;
405
- for (var opt in overRiddenDefaults) {
406
- if (opt !== 'date-options') {
407
- str += ' ' + opt + '="' + overRiddenDefaults[opt] + '"';
445
+ scope.dateOptions = Object.assign({}, overriddenDateDefaults, jsonDateOptions);
446
+
447
+ const isArray = processedAttrs.info.array;
448
+ template = PluginHelperService.buildInputMarkup(
449
+ scope,
450
+ attrs,
451
+ {
452
+ processedAttrs,
453
+ addButtons: isArray,
454
+ needsX: isArray,
455
+ },
456
+ function (buildingBlocks) {
457
+ var str = '<div class="dtwrap"><datetimepicker ' + buildingBlocks.common.trim();
458
+ for (var opt in overriddenDefaults) {
459
+ if (opt !== 'date-options') {
460
+ str += ` ${opt}="${overriddenDefaults[opt]}"`;
461
+ }
408
462
  }
463
+ str += " " + PluginHelperService.genDateTimePickerDisabledStr(scope, processedAttrs, "");
464
+ str += ' date-options="dateOptions"></datetimepicker></div>';
465
+ return str;
409
466
  }
410
- str += ' date-options="dateOptions"></datetimepicker></div>';
411
- return str;
412
- });
467
+ );
413
468
  element.replaceWith($compile(template)(scope));
414
469
  }
415
470
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fng-bootstrap-datetime",
3
- "version": "0.12.0-beta.36",
3
+ "version": "0.12.0-beta.360",
4
4
  "description": "datetime input plugin for forms-angular",
5
5
  "main": "fng-bootstrap-datetime.js",
6
6
  "scripts": {