diff --git a/application/Espo/Resources/i18n/en_US/EmailAddress.json b/application/Espo/Resources/i18n/en_US/EmailAddress.json
new file mode 100644
index 0000000000..2f9d2aa22c
--- /dev/null
+++ b/application/Espo/Resources/i18n/en_US/EmailAddress.json
@@ -0,0 +1,7 @@
+{
+ "labels": {
+ "Primary": "Primary",
+ "Opted Out": "Opted Out",
+ "Invalid": "Invalid"
+ }
+}
diff --git a/application/Espo/Resources/metadata/fields/email.json b/application/Espo/Resources/metadata/fields/email.json
index 3c26ae96b7..f17ea8f40b 100644
--- a/application/Espo/Resources/metadata/fields/email.json
+++ b/application/Espo/Resources/metadata/fields/email.json
@@ -4,10 +4,6 @@
"name":"required",
"type":"bool",
"default":false
- },
- {
- "name":"maxLength",
- "type":"int"
}
],
"notCreatable": true,
diff --git a/frontend/client/res/templates/fields/email/edit.tpl b/frontend/client/res/templates/fields/email/edit.tpl
index 5493852128..f3dfe50f7e 100644
--- a/frontend/client/res/templates/fields/email/edit.tpl
+++ b/frontend/client/res/templates/fields/email/edit.tpl
@@ -1,4 +1,20 @@
-
+{{#each emailAddressData}}
+
+
+
+
+
+
+
+
+{{/each}}
+
diff --git a/frontend/client/src/views/fields/email.js b/frontend/client/src/views/fields/email.js
index dc87165482..3f5476208e 100644
--- a/frontend/client/src/views/fields/email.js
+++ b/frontend/client/src/views/fields/email.js
@@ -31,10 +31,10 @@ Espo.define('Views.Fields.Email', 'Views.Fields.Base', function (Dep) {
listTemplate: 'fields.email.detail',
- validations: ['required', 'email'],
+ validations: ['required', 'emailData'],
validateEmail: function () {
- if (this.model.get(this.name)) {
+ if (this.model.get(this.name)) {
var re = /\S+@+\S+/;
if (!re.test(this.model.get(this.name))) {
var msg = this.translate('fieldShouldBeEmail', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
@@ -44,10 +44,97 @@ Espo.define('Views.Fields.Email', 'Views.Fields.Base', function (Dep) {
}
},
+ validateEmailData: function () {
+ var data = this.model.get(this.dataFieldName);
+ if (data && data.length) {
+ var re = /\S+@+\S+/;
+ var notValid = false;
+ data.forEach(function (row, i) {
+ var emailAddress = row.emailAddress;
+ if (!re.test(emailAddress)) {
+ var msg = this.translate('fieldShouldBeEmail', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
+ this.showValidationMessage(msg, 'div.email-address-block:nth-child(' + (i + 1).toString() + ') input');
+ notValid = true;
+ }
+ }, this);
+ if (notValid) {
+ return true;
+ }
+ }
+ },
+
+ validateRequired: function () {
+ if (this.params.required || this.model.isRequired(this.name)) {
+ if (this.model.get(this.name) === '') {
+ var msg = this.translate('fieldIsRequired', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
+ this.showValidationMessage(msg, 'button[data-action="addEmailAddress"]');
+ return true;
+ }
+ }
+ },
+
+ data: function () {
+ return _.extend({
+ emailAddressData: this.model.get(this.name + 'Data') || [],
+ }, Dep.prototype.data.call(this));
+ },
+
events: {
'click [data-action="mailTo"]': function (e) {
this.mailTo($(e.currentTarget).data('email-address'));
},
+ 'click [data-action="switchEmailProperty"]': function (e) {
+ var $target = $(e.currentTarget);
+ var property = $target.data('property-type');
+
+ if (property == 'primary') {
+ if (!$target.hasClass('active')) {
+ this.$el.find('button.email-property[data-property-type="primary"]').removeClass('active').children().addClass('text-muted');
+ $target.addClass('active').children().removeClass('text-muted');
+ }
+
+ } else {
+ if ($target.hasClass('active')) {
+ $target.removeClass('active').children().addClass('text-muted');
+ } else {
+ $target.addClass('active').children().removeClass('text-muted');
+ }
+ }
+ this.fetchEmailAddressData();
+ },
+ 'change input.email-address': function (e) {
+ var $input = $(e.currentTarget);
+ if ($input.val() == '') {
+ var $block = $input.closest('div.email-address-block');
+
+ changePrimary = false;
+ if ($block.find('button[data-property-type="primary"]').hasClass('active')) {
+ changePrimary = true;
+ }
+ $block.remove();
+
+ if (changePrimary) {
+ this.$el.find('button[data-property-type="primary"]').first().addClass('active');
+ }
+ }
+
+ this.fetchEmailAddressData();
+ },
+ 'click [data-action="addEmailAddress"]': function () {
+ var data = this.model.get(this.dataFieldName) || [];
+
+ o = {
+ emailAddress: '',
+ primary: data.length ? false : true,
+ optOut: false,
+ invalid: false
+ };
+
+ data.push(o);
+
+ this.model.set(data, {silent: true});
+ this.render();
+ },
},
mailTo: function (emailAddress) {
@@ -63,9 +150,60 @@ Espo.define('Views.Fields.Email', 'Views.Fields.Base', function (Dep) {
});
},
+ setup: function () {
+ this.dataFieldName = this.name + 'Data';
+ },
+
+ afterRender: function () {
+ Dep.prototype.afterRender.call(this);
+
+ if (this.mode == 'edit') {
+
+ }
+ },
+
+ fetchEmailAddressData: function (dontUpdate) {
+ var data = [];
+
+ var $list = this.$el.find('div.email-address-block');
+
+ if ($list.size()) {
+ $list.each(function (i, d) {
+ var row = {};
+ var $d = $(d);
+ row.emailAddress = $d.find('input.email-address').val();
+ if (row.emailAddress == '') {
+ return;
+ }
+ row.primary = $d.find('button[data-property-type="primary"]').hasClass('active');
+ row.optOut = $d.find('button[data-property-type="optOut"]').hasClass('active');
+ row.invalid = $d.find('button[data-property-type="invalid"]').hasClass('active');
+ data.push(row);
+ }.bind(this));
+ }
+
+ var o = {};
+ o[this.dataFieldName] = data;
+
+ if (dontUpdate) {
+ this.model.set(o, {silent: true});
+ }
+
+ console.log(data);
+
+ return data;
+ },
+
fetch: function () {
- var data = {};
- data[this.name] = this.$element.val() || null;
+ var data = {};
+
+ var adderssData = this.fetchEmailAddressData(true);
+ data[this.dataFieldName] = adderssData;
+ data[this.name] = null;
+ if (adderssData.length) {
+ data[this.name] = adderssData[0].emailAddress;
+ }
+
return data;
},