| Current Path : /home/rtorresani/www/vendor/magento/module-ui/view/base/web/js/form/components/ |
| Current File : //home/rtorresani/www/vendor/magento/module-ui/view/base/web/js/form/components/collection.js |
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* @api
*/
define([
'underscore',
'mageUtils',
'uiRegistry',
'uiComponent',
'uiLayout',
'Magento_Ui/js/modal/confirm'
], function (_, utils, registry, Component, layout, confirm) {
'use strict';
var childTemplate = {
parent: '${ $.$data.name }',
name: '${ $.$data.childIndex }',
dataScope: '${ $.name }',
nodeTemplate: '${ $.$data.name }.${ $.$data.itemTemplate }'
};
return Component.extend({
defaults: {
lastIndex: 0,
template: 'ui/form/components/collection'
},
/**
* Extends instance with default config, calls initialize of parent
* class, calls initChildren method.
*/
initialize: function () {
this._super()
.initChildren();
return this;
},
/**
* Activates the incoming child and triggers the update event.
*
* @param {Object} elem - Incoming child.
*/
initElement: function (elem) {
this._super();
elem.activate();
this.bubble('update');
return this;
},
/**
* Loops over corresponding data in data storage,
* creates child for each and pushes it's identifier to initialItems array.
*
* @returns {Collection} Chainable.
*/
initChildren: function () {
var children = this.source.get(this.dataScope),
initial = this.initialItems = [];
_.each(children, function (item, index) {
initial.push(index);
this.addChild(index);
}, this);
return this;
},
/**
* Creates new item of collection, based on incoming 'index'.
* If not passed creates one with 'new_' prefix.
*
* @param {String|Object} [index] - Index of a child.
* @returns {Collection} Chainable.
*/
addChild: function (index) {
this.childIndex = !_.isString(index) ?
'new_' + this.lastIndex++ :
index;
layout([utils.template(childTemplate, this)]);
return this;
},
/**
* Returns true if current set of items differ from initial one,
* or if some child has been changed.
*
* @returns {Boolean}
*/
hasChanged: function () {
var initial = this.initialItems,
current = this.elems.pluck('index'),
changed = !utils.equalArrays(initial, current);
return changed || this.elems.some(function (elem) {
return _.some(elem.delegate('hasChanged'));
});
},
/**
* Initiates validation of its' children components.
*
* @returns {Array} An array of validation results.
*/
validate: function () {
var elems;
this.allValid = true;
elems = this.elems.sortBy(function (elem) {
return !elem.active();
});
elems = elems.map(this._validate, this);
return _.flatten(elems);
},
/**
* Iterator function for components validation.
* Activates first invalid child component.
*
* @param {Object} elem - Element to run validation on.
* @returns {Array} An array of validation results.
*/
_validate: function (elem) {
var result = elem.delegate('validate'),
invalid;
invalid = _.some(result, function (item) {
return !item.valid;
});
if (this.allValid && invalid) {
this.allValid = false;
elem.activate();
}
return result;
},
/**
* Creates function that removes element
* from collection using '_removeChild' method.
* @param {Object} elem - Element that should be removed.
* @deprecated Not used anymore
*/
removeAddress: function (elem) {
var self = this;
confirm({
content: this.removeMessage,
actions: {
/** @inheritdoc */
confirm: function () {
self._removeAddress(elem);
}
}
});
},
/**
* Removes element from both collection and data storage,
* activates first element if removed one was active,
* triggers 'update' event.
*
* @param {Object} elem - Element to remove.
*/
_removeAddress: function (elem) {
var isActive = elem.active(),
first;
elem.destroy();
first = this.elems.first();
if (first && isActive) {
first.activate();
}
this.bubble('update');
}
});
});