attachments.html - Remove one level of indirection
[civicrm-core.git] / js / angular-crmMailing2-directives.js
CommitLineData
5d72b4e2
TO
1(function (angular, $, _) {
2 var partialUrl = function (relPath) {
3 return CRM.resourceUrls['civicrm'] + '/partials/crmMailing2/' + relPath;
4 };
5
6 var crmMailing2 = angular.module('crmMailing2');
7
47bacc20
TO
8 crmMailing2.directive('crmMailingReviewBool', function(){
9 return {
10 scope: {
11 crmOn: '@',
12 crmTitle: '@'
13 },
14 template: '<span ng-class="spanClasses"><span class="icon" ng-class="iconClasses"></span>{{crmTitle}} </span>',
15 link: function(scope, element, attrs){
16 function refresh() {
17 if (scope.$parent.$eval(attrs.crmOn)) {
18 scope.spanClasses = {'crmMailing2-active': true};
19 scope.iconClasses = {'ui-icon-check': true};
20 } else {
21 scope.spanClasses = {'crmMailing2-inactive': true};
22 scope.iconClasses = {'ui-icon-close': true};
23 }
24 scope.crmTitle = scope.$parent.$eval(attrs.crmTitle);
25 }
26 refresh();
27 scope.$parent.$watch(attrs.crmOn, refresh);
28 scope.$parent.$watch(attrs.crmTitle, refresh);
29 }
30 };
31 });
32
5d72b4e2
TO
33 // example: <input name="subject" /> <input crm-mailing-token crm-for="subject"/>
34 // WISHLIST: Instead of global CRM.crmMailing.mailTokens, accept token list as an input
38737af8 35 crmMailing2.directive('crmMailingToken', function (crmUiId) {
5d72b4e2
TO
36 return {
37 scope: {
38 crmFor: '@'
39 },
40 template: '<input type="text" class="crmMailingToken" />',
41 link: function (scope, element, attrs) {
42 // 1. Find the corresponding input element (crmFor)
43
44 var form = $(element).closest('form');
45 var crmForEl = $('input[name="' + attrs.crmFor + '"],textarea[name="' + attrs.crmFor + '"]', form);
46 if (form.length != 1 || crmForEl.length != 1) {
38737af8 47 if (console.log) {
5d72b4e2 48 console.log('crmMailingToken cannot be matched to input element. Expected to find one form and one input.', form.length, crmForEl.length);
38737af8 49 }
5d72b4e2
TO
50 return;
51 }
52
53 // 2. Setup the token selector
38737af8
TO
54 $(element).select2({
55 width: "10em",
5d72b4e2
TO
56 dropdownAutoWidth: true,
57 data: CRM.crmMailing.mailTokens,
58 placeholder: ts('Insert')
59 });
60 $(element).on('select2-selecting', function (e) {
38737af8
TO
61 var id = crmUiId(crmForEl);
62 if (CKEDITOR.instances[id]) {
63 CKEDITOR.instances[id].insertText(e.val);
64 $(element).select2('close').select2('val', '');
65 CKEDITOR.instances[id].focus();
66 }
67 else {
68 var origVal = crmForEl.val();
69 var origPos = crmForEl[0].selectionStart;
70 var newVal = origVal.substring(0, origPos) + e.val + origVal.substring(origPos, origVal.length);
71 crmForEl.val(newVal);
72 var newPos = (origPos + e.val.length);
73 crmForEl[0].selectionStart = newPos;
74 crmForEl[0].selectionEnd = newPos;
5d72b4e2 75
38737af8
TO
76 $(element).select2('close').select2('val', '');
77 crmForEl.triggerHandler('change');
78 crmForEl.focus();
79 }
5d72b4e2
TO
80
81 e.preventDefault();
82 });
83 }
84 };
85 });
86
b0461279
TO
87 // example: <select multiple crm-mailing-recipients crm-mailing="mymailing" crm-avail-groups="myGroups" crm-avail-mailings="myMailings"></select>
88 crmMailing2.directive('crmMailingRecipients', function () {
89 return {
90 restrict: 'AE',
91 scope: {
92 crmAvailGroups: '@', // available groups
93 crmAvailMailings: '@', // available mailings
94 crmMailing: '@' // the mailing for which we are choosing recipients
95 },
96 templateUrl: partialUrl('directive/recipients.html'),
97 link: function (scope, element, attrs) {
98 scope.mailing = scope.$parent.$eval(attrs.crmMailing);
99 scope.groups = scope.$parent.$eval(attrs.crmAvailGroups);
100 scope.mailings = scope.$parent.$eval(attrs.crmAvailMailings);
101
102 scope.ts = CRM.ts('CiviMail');
103
104 /// Convert MySQL date ("yyyy-mm-dd hh:mm:ss") to JS date object
105 scope.parseDate = function (date) {
106 if (!angular.isString(date))
107 return date;
108 var p = date.split(/[\- :]/);
109 return new Date(p[0], p[1], p[2], p[3], p[4], p[5]);
110 };
111
112 /// Remove {value} from {array}
113 function arrayRemove(array, value) {
114 var idx = array.indexOf(value);
115 if (idx >= 0) {
116 array.splice(idx, 1);
117 }
118 }
119
120 // @param string id an encoded string like "4 civicrm_mailing include"
121 // @return Object keys: entity_id, entity_type, mode
122 function convertValueToObj(id) {
123 var a = id.split(" ");
124 return {entity_id: parseInt(a[0]), entity_type: a[1], mode: a[2]};
125 }
126
127 // @param Object mailing
128 // @return array list of values like "4 civicrm_mailing include"
129 function convertMailingToValues(mailing) {
130 var r = [];
131 angular.forEach(mailing.groups.include, function (v) {
132 r.push(v + " civicrm_group include");
133 });
134 angular.forEach(mailing.groups.exclude, function (v) {
135 r.push(v + " civicrm_group exclude");
136 });
137 angular.forEach(mailing.mailings.include, function (v) {
138 r.push(v + " civicrm_mailing include");
139 });
140 angular.forEach(mailing.mailings.exclude, function (v) {
141 r.push(v + " civicrm_mailing exclude");
142 });
143 return r;
144 }
145
146 // Update $(element) view based on latest data
147 function refreshUI() {
148 $(element).select2('val', convertMailingToValues(scope.mailing));
149 }
150
151 /// @return string HTML representingn an option
152 function formatItem(item) {
153 if (!item.id) {
154 // return `text` for optgroup
155 return item.text;
156 }
157 var option = convertValueToObj(item.id);
158 var icon = (option.entity_type === 'civicrm_mailing') ? 'EnvelopeIn.gif' : 'group.png';
159 var spanClass = (option.mode == 'exclude') ? 'crmMailing2-exclude' : 'crmMailing2-include';
160 return "<img src='../../sites/all/modules/civicrm/i/" + icon + "' height=12 width=12 /> <span class='" + spanClass + "'>" + item.text + "</span>";
161 }
162
163 $(element).select2({
164 dropdownAutoWidth: true,
165 placeholder: "Groups or Past Recipients",
166 formatResult: formatItem,
167 formatSelection: formatItem,
168 escapeMarkup: function (m) {
169 return m;
170 },
171 });
172
173 $(element).on('select2-selecting', function (e) {
174 var option = convertValueToObj(e.val);
175 var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups';
176 if (option.mode == 'exclude') {
177 scope.mailing[typeKey].exclude.push(option.entity_id);
178 arrayRemove(scope.mailing[typeKey].include, option.entity_id);
179 } else {
180 scope.mailing[typeKey].include.push(option.entity_id);
181 arrayRemove(scope.mailing[typeKey].exclude, option.entity_id);
182 }
183 scope.$apply();
184 $(element).select2('close');
185 e.preventDefault();
186 });
187
188 $(element).on("select2-removing", function (e) {
189 var option = convertValueToObj(e.val);
190 var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups';
89a50c67
TO
191 scope.$parent.$apply(function(){
192 arrayRemove(scope.mailing[typeKey][option.mode], option.entity_id);
193 });
b0461279
TO
194 e.preventDefault();
195 });
196
197 scope.$watchCollection(attrs.crmMailing + ".groups.include", refreshUI);
198 scope.$watchCollection(attrs.crmMailing + ".groups.exclude", refreshUI);
199 scope.$watchCollection(attrs.crmMailing + ".mailings.include", refreshUI);
200 scope.$watchCollection(attrs.crmMailing + ".mailings.exclude", refreshUI);
201 setTimeout(refreshUI, 50);
202 }
203 };
204 });
205
5d72b4e2 206})(angular, CRM.$, CRM._);