From d947236bccb9ffba7244c3c7e8a432e26d428daf Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 21 Aug 2019 12:44:51 +0300 Subject: [PATCH] checklist field --- .../Core/FieldValidators/ChecklistType.php | 35 +++++ .../Espo/Resources/i18n/en_US/Admin.json | 1 + .../Resources/metadata/fields/checklist.json | 51 +++++++ .../res/templates/fields/checklist/detail.tpl | 7 + .../res/templates/fields/checklist/edit.tpl | 7 + client/src/views/fields/checklist.js | 135 ++++++++++++++++++ frontend/less/espo/custom.less | 14 ++ 7 files changed, 250 insertions(+) create mode 100644 application/Espo/Core/FieldValidators/ChecklistType.php create mode 100644 application/Espo/Resources/metadata/fields/checklist.json create mode 100644 client/res/templates/fields/checklist/detail.tpl create mode 100644 client/res/templates/fields/checklist/edit.tpl create mode 100644 client/src/views/fields/checklist.js diff --git a/application/Espo/Core/FieldValidators/ChecklistType.php b/application/Espo/Core/FieldValidators/ChecklistType.php new file mode 100644 index 0000000000..cbfd38a593 --- /dev/null +++ b/application/Espo/Core/FieldValidators/ChecklistType.php @@ -0,0 +1,35 @@ + + + + +{{/each}} diff --git a/client/res/templates/fields/checklist/edit.tpl b/client/res/templates/fields/checklist/edit.tpl new file mode 100644 index 0000000000..29fc72c813 --- /dev/null +++ b/client/res/templates/fields/checklist/edit.tpl @@ -0,0 +1,7 @@ + +{{#each optionDataList}} +
+ + +
+{{/each}} diff --git a/client/src/views/fields/checklist.js b/client/src/views/fields/checklist.js new file mode 100644 index 0000000000..6627b5535a --- /dev/null +++ b/client/src/views/fields/checklist.js @@ -0,0 +1,135 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: https://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +define('views/fields/checklist', ['views/fields/array'], function (Dep) { + + return Dep.extend({ + + type: 'checklist', + + listTemplate: 'fields/array/list', + + detailTemplate: 'fields/checklist/detail', + + editTemplate: 'fields/checklist/edit', + + isInversed: false, + + events: { + }, + + data: function () { + return _.extend({ + optionDataList: this.getOptionDataList(), + }, Dep.prototype.data.call(this)); + }, + + setup: function () { + Dep.prototype.setup.call(this); + + this.params.options = this.params.options || []; + }, + + afterRender: function () { + if (this.mode == 'search') { + this.renderSearch(); + } + + if (this.isEditMode()) { + this.$el.find('input').on('change', function () { + this.trigger('change'); + }.bind(this)); + } + }, + + getOptionDataList: function () { + var valueList = this.model.get(this.name) || []; + var list = []; + + this.params.options.forEach(function (item) { + var isChecked = ~valueList.indexOf(item); + var dataName = 'checklistItem-' + this.name + '-' + item; + var id = 'checklist-item-' + this.name + '-' + item; + + if (this.isInversed) isChecked = !isChecked; + list.push({ + name: item, + isChecked: isChecked, + dataName: dataName, + id: id, + label: this.translatedOptions[item] || item, + }); + }, this); + + return list; + }, + + fetch: function () { + var list = []; + + this.params.options.forEach(function (item) { + var $item = this.$el.find('input[data-name="checklistItem-' + this.name + '-' + item + '"]'); + var isChecked = $item.get(0) && $item.get(0).checked; + if (this.isInversed) + isChecked = !isChecked; + if (isChecked) + list.push(item); + }, this); + + var data = {}; + data[this.name] = list; + + return data; + }, + + validateRequired: function () { + if (this.isRequired()) { + var value = this.model.get(this.name); + if (!value || value.length == 0) { + var msg = this.translate('fieldIsRequired', 'messages').replace('{field}', this.getLabelText()); + this.showValidationMessage(msg, '.checklist-item-container:last-child input'); + return true; + } + } + }, + + validateMaxCount: function () { + if (this.params.maxCount) { + var itemList = this.model.get(this.name) || []; + if (itemList.length > this.params.maxCount) { + var msg = + this.translate('fieldExceedsMaxCount', 'messages') + .replace('{field}', this.getLabelText()) + .replace('{maxCount}', this.params.maxCount.toString()); + this.showValidationMessage(msg, '.checklist-item-container:last-child input'); + return true; + } + } + }, + }); +}); diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less index bb9610b1e3..62a78c776c 100644 --- a/frontend/less/espo/custom.less +++ b/frontend/less/espo/custom.less @@ -1025,6 +1025,20 @@ ul.dropdown-menu > li.checkbox:last-child { } } +.field { + .checklist-label { + color: @text-color; + margin-bottom: 0; + } + + .checklist-item-container { + margin-bottom: 2px; + &:last-child { + margin-bottom: 0; + } + } +} + .filter > .form-group .field { .link-container { font-size: @font-size-small;