dynamic-rows-grid.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. /**
  6. * @api
  7. */
  8. define([
  9. 'underscore',
  10. './dynamic-rows'
  11. ], function (_, dynamicRows) {
  12. 'use strict';
  13. return dynamicRows.extend({
  14. defaults: {
  15. dataProvider: '',
  16. insertData: [],
  17. map: null,
  18. cacheGridData: [],
  19. deleteProperty: false,
  20. positionProvider: 'position',
  21. dataLength: 0,
  22. identificationProperty: 'id',
  23. identificationDRProperty: 'id',
  24. listens: {
  25. 'insertData': 'processingInsertData',
  26. 'recordData': 'initElements setToInsertData'
  27. },
  28. mappingSettings: {
  29. enabled: true,
  30. distinct: true
  31. }
  32. },
  33. /**
  34. * Calls 'initObservable' of parent
  35. *
  36. * @returns {Object} Chainable.
  37. */
  38. initObservable: function () {
  39. this._super()
  40. .observe([
  41. 'insertData'
  42. ]);
  43. return this;
  44. },
  45. /**
  46. * Set data from recordData to insertData
  47. */
  48. setToInsertData: function () {
  49. var insertData = [],
  50. obj;
  51. if (this.recordData().length && !this.update) {
  52. _.each(this.recordData(), function (recordData) {
  53. obj = {};
  54. obj[this.map[this.identificationProperty]] = recordData[this.identificationProperty];
  55. insertData.push(obj);
  56. }, this);
  57. if (insertData.length) {
  58. this.source.set(this.dataProvider, insertData);
  59. }
  60. }
  61. },
  62. /**
  63. * Initialize children
  64. *
  65. * @returns {Object} Chainable.
  66. */
  67. initChildren: function () {
  68. this.getChildItems().forEach(function (data, index) {
  69. this.processingAddChild(data, this.startIndex + index, data[this.identificationDRProperty]);
  70. }, this);
  71. return this;
  72. },
  73. /**
  74. * Initialize elements from grid
  75. *
  76. * @param {Array} data
  77. *
  78. * @returns {Object} Chainable.
  79. */
  80. initElements: function (data) {
  81. var newData = this.getNewData(data);
  82. this.parsePagesData(data);
  83. if (newData.length) {
  84. if (this.insertData().length) {
  85. this.processingAddChild(newData[0], data.length - 1, newData[0][this.identificationProperty]);
  86. }
  87. }
  88. return this;
  89. },
  90. /**
  91. * Delete record instance
  92. * update data provider dataScope
  93. *
  94. * @param {String|Number} index - record index
  95. * @param {String|Number} recordId
  96. */
  97. deleteRecord: function (index, recordId) {
  98. this.updateInsertData(recordId);
  99. this._super();
  100. },
  101. /**
  102. * Updates insertData when record is deleted
  103. *
  104. * @param {String|Number} recordId
  105. */
  106. updateInsertData: function (recordId) {
  107. var data = this.getElementData(this.insertData(), recordId),
  108. prop = this.map[this.identificationDRProperty];
  109. this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) {
  110. return recordData[prop].toString() === data[prop].toString();
  111. }, this));
  112. },
  113. /**
  114. * Find data object by index
  115. *
  116. * @param {Array} array - data collection
  117. * @param {Number} index - element index
  118. * @param {String} property - to find by property
  119. *
  120. * @returns {Object} data object
  121. */
  122. getElementData: function (array, index, property) {
  123. var obj = {},
  124. result;
  125. property ? obj[property] = index : obj[this.map[this.identificationDRProperty]] = index;
  126. result = _.findWhere(array, obj);
  127. if (!result) {
  128. property ?
  129. obj[property] = index.toString() :
  130. obj[this.map[this.identificationDRProperty]] = index.toString();
  131. }
  132. result = _.findWhere(array, obj);
  133. return result;
  134. },
  135. /**
  136. * Processing pages before addChild
  137. *
  138. * @param {Object} ctx - element context
  139. * @param {Number|String} index - element index
  140. * @param {Number|String} prop - additional property to element
  141. */
  142. processingAddChild: function (ctx, index, prop) {
  143. if (this._elems.length > this.pageSize) {
  144. return false;
  145. }
  146. this.showSpinner(true);
  147. this.addChild(ctx, index, prop);
  148. },
  149. /**
  150. * Contains old data with new
  151. *
  152. * @param {Array} data
  153. *
  154. * @returns {Array} changed data
  155. */
  156. getNewData: function (data) {
  157. var changes = [],
  158. tmpObj = {};
  159. if (data.length !== this.relatedData.length) {
  160. _.each(data, function (obj) {
  161. tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
  162. if (!_.findWhere(this.relatedData, tmpObj)) {
  163. changes.push(obj);
  164. }
  165. }, this);
  166. }
  167. return changes;
  168. },
  169. /**
  170. * Processing insert data
  171. *
  172. * @param {Object} data
  173. */
  174. processingInsertData: function (data) {
  175. var changes,
  176. obj = {};
  177. changes = this._checkGridData(data);
  178. this.cacheGridData = data;
  179. if (changes.length) {
  180. obj[this.identificationDRProperty] = changes[0][this.map[this.identificationProperty]];
  181. if (_.findWhere(this.recordData(), obj)) {
  182. return false;
  183. }
  184. changes.forEach(function (changedObject) {
  185. this.mappingValue(changedObject);
  186. }, this);
  187. }
  188. },
  189. /**
  190. * Mapping value from grid
  191. *
  192. * @param {Array} data
  193. */
  194. mappingValue: function (data) {
  195. var obj = {},
  196. tmpObj = {};
  197. if (this.mappingSettings.enabled) {
  198. _.each(this.map, function (prop, index) {
  199. obj[index] = !_.isUndefined(data[prop]) ? data[prop] : '';
  200. }, this);
  201. } else {
  202. obj = data;
  203. }
  204. if (this.mappingSettings.distinct) {
  205. tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
  206. if (_.findWhere(this.recordData(), tmpObj)) {
  207. return false;
  208. }
  209. }
  210. if (!obj.hasOwnProperty(this.positionProvider)) {
  211. this.setMaxPosition();
  212. obj[this.positionProvider] = this.maxPosition;
  213. }
  214. this.source.set(this.dataScope + '.' + this.index + '.' + this.recordData().length, obj);
  215. },
  216. /**
  217. * Check changed records
  218. *
  219. * @param {Array} data - array with records data
  220. * @returns {Array} Changed records
  221. */
  222. _checkGridData: function (data) {
  223. var cacheLength = this.cacheGridData.length,
  224. curData = data.length,
  225. max = cacheLength > curData ? this.cacheGridData : data,
  226. changes = [],
  227. obj = {};
  228. max.forEach(function (record, index) {
  229. obj[this.map[this.identificationDRProperty]] = record[this.map[this.identificationDRProperty]];
  230. if (!_.where(this.cacheGridData, obj).length) {
  231. changes.push(data[index]);
  232. }
  233. }, this);
  234. return changes;
  235. }
  236. });
  237. });