angular.module('crmMailing').controller('EmailAddrCtrl', function EmailAddrCtrl($scope, crmFromAddresses) {
$scope.crmFromAddresses = crmFromAddresses;
});
+
+ var lastEmailTokenAlert = null;
+ angular.module('crmMailing').controller('EmailBodyCtrl', function EmailBodyCtrl($scope, crmMailingMgr) {
+ var ts = CRM.ts(null);
+
+ $scope.hasAllTokens = function hasMissingTokens(mailing, field) {
+ return _.isEmpty(crmMailingMgr.findMissingTokens(mailing, field));
+ };
+
+ $scope.checkTokens = function checkTokens(mailing) {
+ if (lastEmailTokenAlert) {
+ lastEmailTokenAlert.close();
+ }
+ var missing = angular.extend(
+ {},
+ crmMailingMgr.findMissingTokens(mailing, 'body_html'),
+ crmMailingMgr.findMissingTokens(mailing, 'body_text')
+ );
+ if (!_.isEmpty(missing) > 0) {
+ var buf = '<p>'
+ + ts('Before submitting this mailing, you must include an address token and an action token as part of the mailing body, mailing header, or mailing footer.')
+ + '</p><ul>';
+ angular.forEach(missing, function(msg, token) {
+ // FIXME LTR RTL
+ buf = buf + '<li>{' + token + '} - <em>' + msg + '</em></li>'
+ });
+ buf += '</ul>';
+ lastEmailTokenAlert = CRM.alert(buf, undefined, 'error');
+ }
+ }
+ });
})(angular, CRM.$, CRM._);
}
},
+ // Search the body, header, and footer for required tokens.
+ // ex: var msgs = findMissingTokens(mailing, 'body_html');
+ findMissingTokens: function(mailing, field) {
+ var missing = {};
+ if (!_.isEmpty(mailing[field])) {
+ var body = '';
+ if (mailing.footer_id) {
+ var footer = _.where(CRM.crmMailing.headerfooterList, {id: mailing.footer_id});
+ body = body + footer[0][field];
+
+ }
+ body = body + mailing[field];
+ if (mailing.header_id) {
+ var header = _.where(CRM.crmMailing.headerfooterList, {id: mailing.header_id});
+ body = body + header[0][field];
+ }
+
+ angular.forEach(CRM.crmMailing.requiredTokens, function(value, token) {
+ if (!_.isObject(value)) {
+ if (body.indexOf('{' + token + '}') < 0) {
+ missing[token] = value;
+ }
+ }
+ else {
+ var count = 0;
+ angular.forEach(value, function(nestedValue, nestedToken) {
+ if (body.indexOf('{' + nestedToken + '}') >= 0) {
+ count++;
+ }
+ });
+ if (count == 0) {
+ angular.extend(missing, value);
+ }
+ }
+ });
+ }
+ return missing;
+ },
+
// Copy all data fields in (mailingFrom) to (mailingTgt) -- except for (excludes)
// ex: crmMailingMgr.mergeInto(newMailing, mailingTemplate, ['subject']);
mergeInto: function mergeInto(mailingTgt, mailingFrom, excludes) {
<input crm-mailing-token crm-for="htmlForm.body_html"/>
</div>
- <textarea crm-ui-id="htmlForm.body_html" crm-ui-richtext name="body_html" ng-model="mailing.body_html"></textarea>
-</div>
\ No newline at end of file
+ <div ng-controller="EmailBodyCtrl">
+ <textarea crm-ui-id="htmlForm.body_html" crm-ui-richtext name="body_html" ng-model="mailing.body_html" ng-blur="checkTokens(mailing)"></textarea>
+ <span ng-model="body_html_tokens" crm-ui-validate="hasAllTokens(mailing, 'body_html')"></span>
+ </div>
+</div>
<div style="float: right;">
<input crm-mailing-token crm-for="textForm.body_text"/>
</div>
- <textarea crm-ui-id="textForm.body_text" name="body_text" ng-model="mailing.body_text"></textarea>
+ <div ng-controller="EmailBodyCtrl">
+ <textarea crm-ui-id="textForm.body_text" name="body_text" ng-model="mailing.body_text" ng-blur="checkTokens(mailing)"></textarea>
+ <span ng-model="body_text_tokens" crm-ui-validate="hasAllTokens(mailing, 'body_text')"></span>
+ </div>
</div>
Required vars: mailing, crmMailingConst
-->
<div class="crm-block" ng-form="subform" crm-ui-id-scope>
- <div class="crm-group">
+ <div class="crm-group" ng-controller="EmailBodyCtrl">
<div crm-ui-field="subform.header_id" crm-title="ts('Mailing Header')">
<select
crm-ui-id="subform.header_id"
name="header_id"
ui-jq="select2"
ui-options="{dropdownAutoWidth : true, allowClear: true}"
+ ng-change="checkTokens(mailing)"
ng-model="mailing.header_id"
ng-options="mc.id as mc.name for mc in crmMailingConst.headerfooterList | filter:{component_type: 'Header'}">
<option value=""></option>
name="footer_id"
ui-jq="select2"
ui-options="{dropdownAutoWidth : true, allowClear: true}"
+ ng-change="checkTokens(mailing)"
ng-model="mailing.footer_id"
ng-options="mc.id as mc.name for mc in crmMailingConst.headerfooterList | filter:{component_type: 'Footer'}">
<option value=""></option>