Merge pull request #11092 from seamuslee001/CRM-20397-popup
[civicrm-core.git] / ang / crmMailing / RadioDate.js
1 (function(angular, $, _) {
2 // Represent a datetime field as if it were a radio ('schedule.mode') and a datetime ('schedule.datetime').
3 // example: <div crm-mailing-radio-date="mySchedule" ng-model="mailing.scheduled_date">...</div>
4 angular.module('crmMailing').directive('crmMailingRadioDate', function(crmUiAlert) {
5 return {
6 require: 'ngModel',
7 link: function($scope, element, attrs, ngModel) {
8 var lastAlert = null;
9
10 var schedule = $scope[attrs.crmMailingRadioDate] = {
11 mode: 'now',
12 datetime: ''
13 };
14
15 ngModel.$render = function $render() {
16 var sched = ngModel.$viewValue;
17 if (!_.isEmpty(sched)) {
18 schedule.mode = 'at';
19 schedule.datetime = sched;
20 }
21 else {
22 schedule.mode = 'now';
23 schedule.datetime = '';
24 }
25 };
26
27 var updateParent = (function() {
28 switch (schedule.mode) {
29 case 'now':
30 ngModel.$setViewValue(null);
31 schedule.datetime = '';
32 break;
33 case 'at':
34 schedule.datetime = schedule.datetime || '?';
35 ngModel.$setViewValue(schedule.datetime);
36 break;
37 default:
38 throw 'Unrecognized schedule mode: ' + schedule.mode;
39 }
40 });
41
42 element
43 // Open datepicker when clicking "At" radio
44 .on('click', ':radio[value=at]', function() {
45 $('.crm-form-date', element).focus();
46 })
47 // Reset mode if user entered an invalid date
48 .on('change', '.crm-hidden-date', function(e, context) {
49 if (context === 'userInput' && $(this).val() === '' && $(this).siblings('.crm-form-date').val().length) {
50 schedule.mode = 'at';
51 schedule.datetime = '?';
52 } else {
53 var d = new Date(),
54 month = '' + (d.getMonth() + 1),
55 day = '' + d.getDate(),
56 year = d.getFullYear(),
57 hours = '' + d.getHours(),
58 minutes = '' + d.getMinutes();
59 var submittedDate = $(this).val();
60 if (month.length < 2) month = '0' + month;
61 if (day.length < 2) day = '0' + day;
62 if (hours.length < 2) hours = '0' + hours;
63 if (minutes.length < 2) minutes = '0' + minutes;
64 date = [year, month, day].join('-');
65 time = [hours, minutes, "00"].join(':');
66 currentDate = date + ' ' + time;
67 var isInPast = ($(this).val().length && submittedDate < currentDate);
68 ngModel.$setValidity('dateTimeInThePast', !isInPast);
69 if (lastAlert && lastAlert.isOpen) {
70 lastAlert.close();
71 }
72 if (isInPast) {
73 lastAlert = crmUiAlert({
74 text: ts('The scheduled date and time is in the past'),
75 title: ts('Error')
76 });
77 }
78 }
79 });
80
81 $scope.$watch(attrs.crmMailingRadioDate + '.mode', updateParent);
82 $scope.$watch(attrs.crmMailingRadioDate + '.datetime', function(newValue, oldValue) {
83 // automatically switch mode based on datetime entry
84 if (typeof oldValue === 'undefined') {
85 oldValue = '';
86 }
87 if (typeof newValue === 'undefined') {
88 newValue = '';
89 }
90 if (oldValue !== newValue) {
91 if (_.isEmpty(newValue)) {
92 schedule.mode = 'now';
93 }
94 else {
95 schedule.mode = 'at';
96 }
97 }
98 updateParent();
99 });
100 }
101 };
102 });
103 })(angular, CRM.$, CRM._);