I noticed today that the array.js field type does not allow duplicates and also does not prevent the user from "adding" a new element once maxItemCount is reached. It does prevent you from "saving" the entity if maxItemCount is exceeded but I wanted to prevent user from even adding a new item once maxItemCount is reached.
In my case, I wanted this field to act like a true array where I don't specify any options in field definitions so that espo allows user to enter custom options.
After some trial and error, I have come up with the following code.
You will see that one needs to override some functions. I'm using espoCRM 8.0.6 at the moment. I hope it helps someone. This is what I have so far. Curious as to why duplicates would not be allowed in a field type "array" anyway..
In my case, I wanted this field to act like a true array where I don't specify any options in field definitions so that espo allows user to enter custom options.
After some trial and error, I have come up with the following code.
You will see that one needs to override some functions. I'm using espoCRM 8.0.6 at the moment. I hope it helps someone. This is what I have so far. Curious as to why duplicates would not be allowed in a field type "array" anyway..
Code:
define('custom:views/fields/custom-array.js, ['views/fields/array', 'helpers/reg-exp-pattern'], function(Dep, RegExpPattern) {
return Dep.extend({
events: _.extend({
//overide removeValue action
'click [data-action="removeValue"]': function(e) {
e.preventDefault();
e.stopPropagation();
let $listGroupItem = $(e.currentTarget).closest('div.list-group-item');
this.removeValue($listGroupItem);
this.focusOnElement();
},
}),
setup: function() {
Dep.prototype.setup.call(this);
// some initialization
},
afterRender: function() {
Dep.prototype.afterRender.call(this);
// your customizations executed after the field is rendered
},
//overide addValueFromUi
addValueFromUi(value) {
value = value.trim();
if (this.noEmptyString && value === '') {
return;
}
if (this.params.pattern) {
let helper = new RegExpPattern(this.getMetadata(), this.getLanguage());
let result = helper.validate(this.params.pattern, value, this.name, this.entityType);
if (result) {
setTimeout(() => this.showValidationMessage(result.message, 'input.select'), 10);
return;
}
}
// Do not allow adding more than maxItemLength
if (this.params.maxCount && this.selected.length === (this.params.maxCount)) {
let msg =
this.translate('fieldExceedsMaxCount', 'messages')
.replace('{field}', this.getLabelText())
.replace('{maxCount}', this.params.maxCount.toString());
this.showValidationMessage(msg, '.array-control-container');
return;
}
this.addValue(value);
this.$select.val('');
this.controlAddItemButton();
},
//overide addValue
addValue(value) {
let html = this.getItemHtml(value);
this.$list.append(html);
this.selected.push(value);
this.trigger('change');
},
//overide removeValue
removeValue($listGroupItem) {
let itemIndex = this.$list.children().index($listGroupItem);
this.$list.children().eq(itemIndex).remove();
this.selected.splice(itemIndex, 1);
this.trigger('change');
}
});
});
