API Docs for: 1.0.0
Show:

File: Resources/public/js/views/fields/ez-relationlist-editview.js

  1. /*
  2. * Copyright (C) eZ Systems AS. All rights reserved.
  3. * For full copyright and license information view LICENSE file distributed with this source code.
  4. */
  5. YUI.add('ez-relationlist-editview', function (Y) {
  6. "use strict";
  7. /**
  8. * Provides the field edit view for the relation list fields
  9. *
  10. * @module ez-relationlist-editview
  11. */
  12. Y.namespace('eZ');
  13.  
  14. var FIELDTYPE_IDENTIFIER = 'ezobjectrelationlist';
  15.  
  16. /**
  17. * Relation list edit view
  18. *
  19. * @namespace eZ
  20. * @class RelationListEditView
  21. * @constructor
  22. * @extends eZ.FieldEditView
  23. */
  24. Y.eZ.RelationListEditView = Y.Base.create('relationListEditView', Y.eZ.FieldEditView, [Y.eZ.AsynchronousView], {
  25. events: {
  26. '.ez-relation-discover': {
  27. 'tap': '_runUniversalDiscovery',
  28. },
  29. '.ez-relation-remove-content': {
  30. 'tap': '_removeRelation'
  31. }
  32. },
  33.  
  34. initializer: function () {
  35. var fieldValue = this.get('field').fieldValue;
  36.  
  37. this._fireMethod = this._fireLoadObjectRelations;
  38. this._handleFieldDescriptionVisibility = false;
  39. if( fieldValue.destinationContentIds ){
  40. this._set('destinationContentsIds', fieldValue.destinationContentIds);
  41. }
  42. this.after('relatedContentsChange', function (e) {
  43. this._syncDestinationContentsIds(e);
  44. if (e.src === "remove") {
  45. if (this.get('destinationContentsIds').length !== 0) {
  46. this._vanish('tr[data-content-id="' + e.contentId + '"]', false);
  47. } else {
  48. this._vanish('.ez-relationlist-contents', true);
  49. }
  50. } else {
  51. this.render();
  52. }
  53. });
  54. },
  55.  
  56. /**
  57. * Make a DOM element vanish.
  58. *
  59. * @method _vanish
  60. * @param {String} domIdentifier
  61. * @param {Boolean} reRender
  62. * @protected
  63. */
  64. _vanish: function (domIdentifier, reRender) {
  65. var that = this,
  66. container = this.get('container');
  67.  
  68. container.one(domIdentifier).transition({
  69. duration: 0.3,
  70. opacity: 0,
  71. }, function() {
  72. container.one(domIdentifier).remove();
  73. if (reRender) {
  74. that.render();
  75. }
  76. });
  77. },
  78.  
  79. /**
  80. * Synchronize the destinationContentId attribute when destinationContent change.
  81. *
  82. * @method _syncDestinationContentsIds
  83. * @param {EventFacade} e
  84. * @protected
  85. */
  86. _syncDestinationContentsIds: function (e) {
  87. var destinationContentsIds = [];
  88.  
  89. Y.Array.each(e.newVal, function (value) {
  90. destinationContentsIds.push(value.get('contentId'));
  91. });
  92. this._set('destinationContentsIds', destinationContentsIds);
  93. },
  94.  
  95. /**
  96. * Fire the `loadObjectRelations` event
  97. *
  98. * @method _fireLoadObjectRelations
  99. * @protected
  100. */
  101. _fireLoadObjectRelations: function () {
  102. if ( !this._isFieldEmpty() ) {
  103. this.fire('loadObjectRelations', {
  104. relationType: 'ATTRIBUTE',
  105. fieldDefinitionIdentifier: this.get('fieldDefinition').identifier,
  106. content: this.get('content'),
  107. });
  108. }
  109. },
  110.  
  111. /**
  112. * Checks whether the field is empty
  113. *
  114. * @method _isFieldEmpty
  115. * @protected
  116. * @return {Boolean}
  117. */
  118. _isFieldEmpty: function () {
  119. if ( this.get('destinationContentsIds') ) {
  120. return ( this.get('destinationContentsIds').length === 0 );
  121. }
  122. return true;
  123. },
  124.  
  125. /**
  126. * Returns an object containing the additional variables
  127. *
  128. * @method _variables
  129. * @protected
  130. * @return Object
  131. */
  132. _variables: function () {
  133. var relatedContents = this.get('relatedContents'),
  134. relatedContentsJSON = [];
  135.  
  136. Y.Array.each(relatedContents, function (value) {
  137. relatedContentsJSON.push(value.toJSON());
  138. });
  139.  
  140. return {
  141. relatedContents: relatedContentsJSON,
  142. loadingError: this.get('loadingError'),
  143. isEmpty: this._isFieldEmpty(),
  144. isRequired: this.get('fieldDefinition').isRequired,
  145. };
  146. },
  147.  
  148. /**
  149. * Tap event handler for the remove relation buttons.
  150. * It remove the content related to the button from the relation list.
  151. *
  152. * @method _removeRelation
  153. * @protected
  154. * @param {EventFacade} e
  155. */
  156. _removeRelation: function (e) {
  157. var remainingContents,
  158. removedContentId;
  159.  
  160. e.preventDefault();
  161. remainingContents = Y.Array.reject(this.get('relatedContents'), function (val) {
  162. return ((removedContentId = e.target.getAttribute('data-content-id')) == val.get('id'));
  163. });
  164. this.set('relatedContents', remainingContents, {src: "remove", contentId: removedContentId});
  165. this.validate();
  166. },
  167.  
  168. validate: function () {
  169. if ( this.get('fieldDefinition').isRequired && this._isFieldEmpty() ){
  170. this.set('errorStatus', Y.eZ.trans('this.field.is.required', {}, 'fieldedit'));
  171. } else {
  172. this.set('errorStatus', false);
  173. }
  174. },
  175.  
  176. /**
  177. * Fire the contentDiscover event to launch the universal discovery widget.
  178. *
  179. * @method _runUniversalDiscovery
  180. * @protected
  181. * @param {EventFacade} e
  182. */
  183. _runUniversalDiscovery: function (e) {
  184. var that = this;
  185.  
  186. e.preventDefault();
  187. this.fire('contentDiscover', {
  188. config: {
  189. title: Y.eZ.trans('select.contents.to.add', {}, 'fieldedit'),
  190. multiple: true,
  191. contentDiscoveredHandler: Y.bind(this._selectRelation, this),
  192. cancelDiscoverHandler: Y.bind(this.validate, this),
  193. startingLocationId: this.get('fieldDefinition').fieldSettings.selectionDefaultLocationHref,
  194. isSelectable: function (contentStruct) {
  195. var selectionContentTypes = that.get('fieldDefinition').fieldSettings.selectionContentTypes,
  196. contentTypeIdentifier = contentStruct.contentType.get('identifier');
  197.  
  198. return (
  199. (selectionContentTypes.length === 0)
  200. || (selectionContentTypes.indexOf(contentTypeIdentifier) > -1)
  201. );
  202. },
  203. },
  204. });
  205. },
  206.  
  207. /**
  208. * Universal discovery contentDiscovered event handler to fill the relation list
  209. * after the user chose one or several contents.
  210. *
  211. * @method _selectRelation
  212. * @protected
  213. * @param {EventFacade} e
  214. */
  215. _selectRelation: function (e) {
  216. var relatedContents = this.get('relatedContents').concat();
  217.  
  218. Y.Array.each(e.selection, function (struct) {
  219. if ( !this._isRelated(struct.contentInfo) ) {
  220. relatedContents.push(struct.contentInfo);
  221. }
  222. }, this);
  223.  
  224. this.set('errorStatus', false);
  225.  
  226. this.set('relatedContents', relatedContents);
  227. },
  228.  
  229. /**
  230. * Checks if the content info is already in the relation.
  231. *
  232. * @method _isRelated
  233. * @protected
  234. * @param {eZ.ContentInfo} contentInfo
  235. * @return Boolean
  236. */
  237. _isRelated: function (contentInfo) {
  238. return (this.get('destinationContentsIds').indexOf(contentInfo.get('contentId')) !== -1);
  239. },
  240.  
  241. /**
  242. * Returns the field value.
  243. *
  244. * @protected
  245. * @method _getFieldValue
  246. * @return Object
  247. */
  248. _getFieldValue: function () {
  249. this.validate();
  250. return {destinationContentIds: this.get('destinationContentsIds')};
  251. },
  252. },{
  253. ATTRS: {
  254. /**
  255. * The related contents of the relation list
  256. *
  257. * @attribute relatedContents
  258. * @type Array of (eZ.ContentInfo) or {eZ.Content}
  259. */
  260. relatedContents: {
  261. value: [],
  262. },
  263.  
  264. /**
  265. * Array of contents Ids in the relation (e.g. 42, not /api/ezp/v2/content/objects/42)
  266. *
  267. * @attribute destinationContentsIds
  268. * @type Array
  269. * @readOnly
  270. */
  271. destinationContentsIds: {
  272. value: null,
  273. readOnly: true,
  274. },
  275. },
  276. });
  277.  
  278. Y.eZ.FieldEditView.registerFieldEditView(
  279. FIELDTYPE_IDENTIFIER, Y.eZ.RelationListEditView
  280. );
  281. });
  282.