')
.addClass('link-multiple-item')
.html(item)
.wrap('
').parent().html()
)
.join('');
}
/** @inheritDoc */
validateRequired() {
if (!this.isRequired()) {
return false;
}
const idList = this.model.get(this.idsName) || [];
if (idList.length === 0) {
const msg = this.translate('fieldIsRequired', 'messages')
.replace('{field}', this.getLabelText());
this.showValidationMessage(msg);
return true;
}
return false;
}
// noinspection JSUnusedGlobalSymbols
validateMaxCount() {
const maxCount = this.params.maxCount;
if (!maxCount) {
return false;
}
const idList = this.model.get(this.idsName) || [];
if (idList.length === 0) {
return false;
}
if (idList.length <= maxCount) {
return false;
}
const msg = this.translate('fieldExceedsMaxCount', 'messages')
.replace('{field}', this.getLabelText())
.replace('{maxCount}', maxCount.toString());
this.showValidationMessage(msg);
return true;
}
/** @inheritDoc */
fetch() {
const data = {};
data[this.idsName] = Espo.Utils.clone(this.ids);
data[this.nameHashName] = Espo.Utils.clone(this.nameHash);
return data;
}
/** @inheritDoc */
fetchFromDom() {
this.ids = [];
this.$el.find('.link-container').children().each((i, li) => {
const id = $(li).attr('data-id');
if (!id) {
return;
}
this.ids.push(id);
});
}
/** @inheritDoc */
fetchSearch() {
const type = this.$el.find('select.search-type').val();
const idList = this.ids || [];
if (~['anyOf', 'allOf', 'noneOf'].indexOf(type) && !idList.length) {
return {
type: 'isNotNull',
attribute: 'id',
data: {
type: type,
},
};
}
let data;
if (type === 'anyOf') {
data = {
type: 'linkedWith',
value: idList,
data: {
type: type,
nameHash: this.nameHash,
},
};
return data;
}
if (type === 'allOf') {
data = {
type: 'linkedWithAll',
value: idList,
data: {
type: type,
nameHash: this.nameHash,
},
};
if (!idList.length) {
data.value = null;
}
return data;
}
if (type === 'noneOf') {
data = {
type: 'notLinkedWith',
value: idList,
data: {
type: type,
nameHash: this.nameHash,
},
};
return data;
}
if (type === 'isEmpty') {
data = {
type: 'isNotLinked',
data: {
type: type,
},
};
return data;
}
if (type === 'isNotEmpty') {
data = {
type: 'isLinked',
data: {
type: type,
},
};
return data;
}
}
/** @inheritDoc */
getSearchType() {
return this.getSearchParamsData().type ||
this.searchParams.typeFront ||
this.searchParams.type || 'anyOf';
}
/**
* @protected
* @param {string} id
*/
quickView(id) {
const entityType = this.foreignScope;
const helper = new RecordModal(this.getMetadata(), this.getAcl());
helper.showDetail(this, {
id: id,
scope: entityType,
});
}
/**
* @protected
*/
actionSelect() {
Espo.Ui.notify(' ... ');
const panelDefs = this.panelDefs;
const viewName = panelDefs.selectModalView ||
this.getMetadata().get(`clientDefs.${this.foreignScope}.modalViews.select`) ||
this.selectRecordsView;
const mandatorySelectAttributeList = this.mandatorySelectAttributeList ||
panelDefs.selectMandatoryAttributeList;
const createButton = this.isEditMode() &&
(!this.createDisabled && !panelDefs.createDisabled || this.forceCreateButton);
const createAttributesProvider = createButton ?
this.getCreateAttributesProvider() :
null;
this._getSelectFilters().then(filters => {
const orderBy = filters.orderBy || this.panelDefs.selectOrderBy;
const orderDirection = filters.orderBy ? filters.order : this.panelDefs.selectOrderDirection;
this.createView('dialog', viewName, {
scope: this.foreignScope,
createButton: createButton,
filters: filters.advanced,
boolFilterList: filters.bool,
primaryFilterName: filters.primary,
filterList: this.getSelectFilterList(),
multiple: true,
mandatorySelectAttributeList: mandatorySelectAttributeList,
forceSelectAllAttributes: this.forceSelectAllAttributes,
createAttributesProvider: createAttributesProvider,
layoutName: this.panelDefs.selectLayout,
orderBy: orderBy,
orderDirection: orderDirection,
}, dialog => {
dialog.render();
Espo.Ui.notify(false);
this.listenToOnce(dialog, 'select', models => {
this.clearView('dialog');
if (Object.prototype.toString.call(models) !== '[object Array]') {
models = [models];
}
this.select(models);
});
});
});
}
/**
* @protected
* @return {function(): Promise
>}
*/
getCreateAttributesProvider() {
return () => {
const attributes = this.getCreateAttributes() || {};
if (!this.panelDefs.createHandler) {
return Promise.resolve(attributes);
}
return new Promise(resolve => {
Espo.loader.requirePromise(this.panelDefs.createHandler)
.then(Handler => new Handler(this.getHelper()))
.then(handler => {
handler.getAttributes(this.model)
.then(additionalAttributes => {
resolve({
...attributes,
...additionalAttributes,
});
});
});
});
};
}
/**
* On records select.
*
* @protected
* @param {module:model[]} models
* @since 8.0.4
*/
select(models) {
models.forEach(model => {
this.addLink(model.id, model.get('name'));
});
}
/**
* @private
* @return {Promise<{bool?: string[], advanced?: Object, primary?: string}>}
*/
_getSelectFilters() {
const handler = this.panelDefs.selectHandler;
const localBoolFilterList = this.getSelectBoolFilterList();
if (!handler || this.isSearchMode()) {
const boolFilterList = (localBoolFilterList || this.panelDefs.selectBoolFilterList) ?
[
...(localBoolFilterList || []),
...(this.panelDefs.selectBoolFilterList || []),
] :
undefined;
return Promise.resolve({
primary: this.getSelectPrimaryFilterName() || this.panelDefs.selectPrimaryFilterName,
bool: boolFilterList,
advanced: this.getSelectFilters() || undefined,
});
}
return new Promise(resolve => {
Espo.loader.requirePromise(handler)
.then(Handler => new Handler(this.getHelper()))
.then(/** module:handlers/select-related */handler => {
return handler.getFilters(this.model);
})
.then(filters => {
const advanced = {...(this.getSelectFilters() || {}), ...(filters.advanced || {})};
const primaryFilter = this.getSelectPrimaryFilterName() ||
filters.primary || this.panelDefs.selectPrimaryFilterName;
const boolFilterList = (localBoolFilterList || filters.bool || this.panelDefs.selectBoolFilterList) ?
[
...(localBoolFilterList || []),
...(filters.bool || []),
...(this.panelDefs.selectBoolFilterList || []),
] :
undefined;
resolve({
bool: boolFilterList,
primary: primaryFilter,
advanced: advanced,
});
});
});
}
actionCreateLink() {
const viewName = this.getMetadata().get(['clientDefs', this.foreignScope, 'modalViews', 'edit']) ||
'views/modals/edit';
Espo.Ui.notify(' ... ');
this.getCreateAttributesProvider()().then(attributes => {
this.createView('dialog', viewName, {
scope: this.foreignScope,
fullFormDisabled: true,
attributes: attributes,
}, view => {
view.render()
.then(() => Espo.Ui.notify(false));
this.listenToOnce(view, 'after:save', model => {
view.close();
this.clearView('dialog');
this.select([model]);
});
});
});
}
/** @private */
_transformAutocompleteResult(response) {
const list = [];
response.list.forEach(item => {
list.push({
id: item.id,
name: item.name || item.id,
data: item.id,
value: item.name || item.id,
attributes: item,
});
});
return list;
}
/**
* Get an empty autocomplete result.
*
* @protected
* @return {Promise<[{name: ?string, id: string} & Record]>}
*/
getOnEmptyAutocomplete() {
return undefined;
}
}
export default LinkMultipleFieldView;