CRM-15578 - Extract crmUiId
[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
35 crmMailing2.directive('crmMailingToken', function () {
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) {
47 if (console.log)
48 console.log('crmMailingToken cannot be matched to input element. Expected to find one form and one input.', form.length, crmForEl.length);
49 return;
50 }
51
52 // 2. Setup the token selector
53 $(element).select2({width: "10em",
54 dropdownAutoWidth: true,
55 data: CRM.crmMailing.mailTokens,
56 placeholder: ts('Insert')
57 });
58 $(element).on('select2-selecting', function (e) {
59 var origVal = crmForEl.val();
60 var origPos = crmForEl[0].selectionStart;
61 var newVal = origVal.substring(0, origPos) + e.val + origVal.substring(origPos, origVal.length);
62 crmForEl.val(newVal);
63 var newPos = (origPos + e.val.length);
64 crmForEl[0].selectionStart = newPos;
65 crmForEl[0].selectionEnd = newPos;
66
67 $(element).select2('close').select2('val', '');
68 crmForEl.triggerHandler('change');
69 crmForEl.focus();
70
71 e.preventDefault();
72 });
73 }
74 };
75 });
76
b0461279
TO
77 // example: <select multiple crm-mailing-recipients crm-mailing="mymailing" crm-avail-groups="myGroups" crm-avail-mailings="myMailings"></select>
78 crmMailing2.directive('crmMailingRecipients', function () {
79 return {
80 restrict: 'AE',
81 scope: {
82 crmAvailGroups: '@', // available groups
83 crmAvailMailings: '@', // available mailings
84 crmMailing: '@' // the mailing for which we are choosing recipients
85 },
86 templateUrl: partialUrl('directive/recipients.html'),
87 link: function (scope, element, attrs) {
88 scope.mailing = scope.$parent.$eval(attrs.crmMailing);
89 scope.groups = scope.$parent.$eval(attrs.crmAvailGroups);
90 scope.mailings = scope.$parent.$eval(attrs.crmAvailMailings);
91
92 scope.ts = CRM.ts('CiviMail');
93
94 /// Convert MySQL date ("yyyy-mm-dd hh:mm:ss") to JS date object
95 scope.parseDate = function (date) {
96 if (!angular.isString(date))
97 return date;
98 var p = date.split(/[\- :]/);
99 return new Date(p[0], p[1], p[2], p[3], p[4], p[5]);
100 };
101
102 /// Remove {value} from {array}
103 function arrayRemove(array, value) {
104 var idx = array.indexOf(value);
105 if (idx >= 0) {
106 array.splice(idx, 1);
107 }
108 }
109
110 // @param string id an encoded string like "4 civicrm_mailing include"
111 // @return Object keys: entity_id, entity_type, mode
112 function convertValueToObj(id) {
113 var a = id.split(" ");
114 return {entity_id: parseInt(a[0]), entity_type: a[1], mode: a[2]};
115 }
116
117 // @param Object mailing
118 // @return array list of values like "4 civicrm_mailing include"
119 function convertMailingToValues(mailing) {
120 var r = [];
121 angular.forEach(mailing.groups.include, function (v) {
122 r.push(v + " civicrm_group include");
123 });
124 angular.forEach(mailing.groups.exclude, function (v) {
125 r.push(v + " civicrm_group exclude");
126 });
127 angular.forEach(mailing.mailings.include, function (v) {
128 r.push(v + " civicrm_mailing include");
129 });
130 angular.forEach(mailing.mailings.exclude, function (v) {
131 r.push(v + " civicrm_mailing exclude");
132 });
133 return r;
134 }
135
136 // Update $(element) view based on latest data
137 function refreshUI() {
138 $(element).select2('val', convertMailingToValues(scope.mailing));
139 }
140
141 /// @return string HTML representingn an option
142 function formatItem(item) {
143 if (!item.id) {
144 // return `text` for optgroup
145 return item.text;
146 }
147 var option = convertValueToObj(item.id);
148 var icon = (option.entity_type === 'civicrm_mailing') ? 'EnvelopeIn.gif' : 'group.png';
149 var spanClass = (option.mode == 'exclude') ? 'crmMailing2-exclude' : 'crmMailing2-include';
150 return "<img src='../../sites/all/modules/civicrm/i/" + icon + "' height=12 width=12 /> <span class='" + spanClass + "'>" + item.text + "</span>";
151 }
152
153 $(element).select2({
154 dropdownAutoWidth: true,
155 placeholder: "Groups or Past Recipients",
156 formatResult: formatItem,
157 formatSelection: formatItem,
158 escapeMarkup: function (m) {
159 return m;
160 },
161 });
162
163 $(element).on('select2-selecting', function (e) {
164 var option = convertValueToObj(e.val);
165 var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups';
166 if (option.mode == 'exclude') {
167 scope.mailing[typeKey].exclude.push(option.entity_id);
168 arrayRemove(scope.mailing[typeKey].include, option.entity_id);
169 } else {
170 scope.mailing[typeKey].include.push(option.entity_id);
171 arrayRemove(scope.mailing[typeKey].exclude, option.entity_id);
172 }
173 scope.$apply();
174 $(element).select2('close');
175 e.preventDefault();
176 });
177
178 $(element).on("select2-removing", function (e) {
179 var option = convertValueToObj(e.val);
180 var typeKey = option.entity_type == 'civicrm_mailing' ? 'mailings' : 'groups';
89a50c67
TO
181 scope.$parent.$apply(function(){
182 arrayRemove(scope.mailing[typeKey][option.mode], option.entity_id);
183 });
b0461279
TO
184 e.preventDefault();
185 });
186
187 scope.$watchCollection(attrs.crmMailing + ".groups.include", refreshUI);
188 scope.$watchCollection(attrs.crmMailing + ".groups.exclude", refreshUI);
189 scope.$watchCollection(attrs.crmMailing + ".mailings.include", refreshUI);
190 scope.$watchCollection(attrs.crmMailing + ".mailings.exclude", refreshUI);
191 setTimeout(refreshUI, 50);
192 }
193 };
194 });
195
5d72b4e2 196})(angular, CRM.$, CRM._);