/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js
JavaScript | 356 lines | 181 code | 51 blank | 124 comment | 10 complexity | 309dd8ac384f2854585bf59955c52981 MD5 | raw file
- /**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
- define([
- 'underscore',
- 'mageUtils',
- 'uiLayout',
- 'uiCollection'
- ], function (_, utils, layout, Collection) {
- 'use strict';
- return Collection.extend({
- defaults: {
- active: true,
- hasChanges: false,
- fields: [],
- errorsCount: 0,
- fieldTmpl: 'ui/grid/editing/field',
- rowTmpl: 'ui/grid/editing/row',
- templates: {
- fields: {
- base: {
- parent: '${ $.$data.record.name }',
- name: '${ $.$data.column.index }',
- provider: '${ $.$data.record.name }',
- dataScope: 'data.${ $.$data.column.index }',
- imports: {
- disabled: '${ $.$data.record.parentName }:fields.${ $.$data.column.index }.disabled'
- },
- isEditor: true
- },
- text: {
- component: 'Magento_Ui/js/form/element/abstract',
- template: 'ui/form/element/input'
- },
- date: {
- component: 'Magento_Ui/js/form/element/date',
- template: 'ui/form/element/date',
- dateFormat: 'MMM d, y h:mm:ss a'
- },
- select: {
- component: 'Magento_Ui/js/form/element/select',
- template: 'ui/form/element/select',
- options: '${ JSON.stringify($.$data.column.options) }'
- }
- }
- },
- listens: {
- elems: 'updateFields',
- data: 'updateState'
- },
- imports: {
- onColumnsUpdate: '${ $.columnsProvider }:elems'
- },
- modules: {
- columns: '${ $.columnsProvider }',
- editor: '${ $.editorProvider }'
- }
- },
- /**
- * Initializes record component.
- *
- * @returns {Record} Chainable.
- */
- initialize: function () {
- _.bindAll(this, 'countErrors');
- utils.limit(this, 'updateState', 10);
- return this._super();
- },
- /**
- * Initializes observable properties.
- *
- * @returns {Record} Chainable.
- */
- initObservable: function () {
- this._super()
- .track('errorsCount hasChanges')
- .observe('active fields');
- return this;
- },
- /**
- * Adds listeners on a field.
- *
- * @returns {Record} Chainable.
- */
- initElement: function (field) {
- field.on('error', this.countErrors);
- return this._super();
- },
- /**
- * Creates new instance of a field.
- *
- * @param {Column} column - Column instance which contains field definition.
- * @returns {Record} Chainable.
- */
- initField: function (column) {
- var field = this.buildField(column);
- layout([field]);
- return this;
- },
- /**
- * Builds fields' configuration described in a provided column.
- *
- * @param {Column} column - Column instance which contains field definition.
- * @returns {Object} Complete fields' configuration.
- */
- buildField: function (column) {
- var fields = this.templates.fields,
- field = column.editor;
- if (_.isObject(field) && field.editorType) {
- field = utils.extend({}, fields[field.editorType], field);
- } else if (_.isString(field)) {
- field = fields[field];
- }
- field = utils.extend({}, fields.base, field);
- return utils.template(field, {
- record: this,
- column: column
- }, true, true);
- },
- /**
- * Creates fields for the specfied columns.
- *
- * @param {Array} columns - An array of column instances.
- * @returns {Record} Chainable.
- */
- createFields: function (columns) {
- columns.forEach(function (column) {
- if (column.editor && !this.hasChild(column.index)) {
- this.initField(column);
- }
- }, this);
- return this;
- },
- /**
- * Returns instance of a column found by provided index.
- *
- * @param {String} index - Index of a column (e.g. 'title').
- * @returns {Column}
- */
- getColumn: function (index) {
- return this.columns().getChild(index);
- },
- /**
- * Returns records' current data object.
- *
- * @returns {Object}
- */
- getData: function () {
- return this.filterData(this.data);
- },
- /**
- * Returns saved records' data. Data will be processed
- * with a 'filterData' and 'normalizeData' methods.
- *
- * @returns {Object} Saved records' data.
- */
- getSavedData: function () {
- var editor = this.editor(),
- savedData = editor.getRowData(this.index);
- savedData = this.filterData(savedData);
- return this.normalizeData(savedData);
- },
- /**
- * Replaces current records' data with the provided one.
- *
- * @param {Object} data - New records data.
- * @param {Boolean} [partial=false] - Flag that defines whether
- * to completely replace current data or to extend it.
- * @returns {Record} Chainable.
- */
- setData: function (data, partial) {
- var currentData = partial ? this.data : {};
- data = this.normalizeData(data);
- data = utils.extend({}, currentData, data);
- this.set('data', data)
- .updateState();
- return this;
- },
- /**
- * Filters provided object extracting from it values
- * that can be matched with an existing fields.
- *
- * @param {Object} data - Object to be processed.
- * @returns {Object}
- */
- filterData: function (data) {
- var fields = _.pluck(this.elems(), 'index');
- _.each(this.preserveFields, function (enabled, field) {
- if (enabled && !_.contains(fields, field)) {
- fields.push(field);
- }
- });
- return _.pick(data, fields);
- },
- /**
- * Parses values of a provided object with
- * a 'normalizeData' method of a corresponding field.
- *
- * @param {Object} data - Data to be processed.
- * @returns {Object}
- */
- normalizeData: function (data) {
- var index;
- this.elems.each(function (elem) {
- index = elem.index;
- if (data.hasOwnProperty(index)) {
- data[index] = elem.normalizeData(data[index]);
- }
- });
- return data;
- },
- /**
- * Clears values of all fields.
- *
- * @returns {Record} Chainable.
- */
- clear: function () {
- this.elems.each('clear');
- return this;
- },
- /**
- * Validates all of the available fields.
- *
- * @returns {Array} An array with validatation results.
- */
- validate: function () {
- return this.elems.map('validate');
- },
- /**
- * Checks if all fields are valid.
- *
- * @returns {Boolean}
- */
- isValid: function () {
- return _.every(this.validate(), 'valid');
- },
- /**
- * Counts total errors ammount accros all fields.
- *
- * @returns {Number}
- */
- countErrors: function () {
- var errorsCount = this.elems.filter('error').length;
- this.errorsCount = errorsCount;
- return errorsCount;
- },
- /**
- * Returns difference between current data and its'
- * initial state, retrieved from the records collection.
- *
- * @returns {Object} Object with changes descriptions.
- */
- checkChanges: function () {
- var savedData = this.getSavedData(),
- data = this.normalizeData(this.getData());
- return utils.compare(savedData, data);
- },
- /**
- * Updates 'fields' array filling it with available edtiors
- * or with column instances if associated field is not present.
- *
- * @returns {Record} Chainable.
- */
- updateFields: function () {
- var fields;
- fields = this.columns().elems.map(function (column) {
- return this.getChild(column.index) || column;
- }, this);
- this.fields(fields);
- return this;
- },
- /**
- * Updates state of a 'hasChanges' property.
- *
- * @returns {Record} Chainable.
- */
- updateState: function () {
- var diff = this.checkChanges(),
- changed = {};
- this.hasChanges = !diff.equal;
- changed[this.index] = this.data;
- this.editor().set('changed', [changed]);
- return this;
- },
- /**
- * Checks if provided column is an actions column.
- *
- * @param {Column} column - Column to be checked.
- * @returns {Boolean}
- */
- isActionsColumn: function (column) {
- return column.dataType === 'actions';
- },
- /**
- * Listener of columns provider child array changes.
- *
- * @param {Array} columns - Modified child elements array.
- */
- onColumnsUpdate: function (columns) {
- this.createFields(columns)
- .updateFields();
- }
- });
- });