API Docs for: 1.0.0
Show:

File: Resources/public/js/views/universaldiscovery/ez-universaldiscoveryconfirmedlistview.js

/*
 * Copyright (C) eZ Systems AS. All rights reserved.
 * For full copyright and license information view LICENSE file distributed with this source code.
 */
YUI.add('ez-universaldiscoveryconfirmedlistview', function (Y) {
    "use strict";
    /**
     * Provides the universal discovery confirmed list view.
     *
     * @module ez-universaldiscoveryconfirmedlistview
     */
    Y.namespace('eZ');

    var MAX_MINI_DISPLAY = 3,
        IS_EMPTY = 'is-empty',
        IS_FULL_LIST_VISIBLE = 'is-full-list-visible';

    /**
     * The universal discovery confirmed list view. It displays the contents
     * choosen by the user in the universal discovery widget. By default, only
     * the last 3 contents are really displayed.
     *
     * @namespace eZ
     * @class UniversalDiscoveryConfirmedListView
     * @constructor
     * @extends eZ.TemplateBasedView
     */
    Y.eZ.UniversalDiscoveryConfirmedListView = Y.Base.create('universalDiscoveryConfirmedListView', Y.eZ.TemplateBasedView, [], {
        events: {
            '.ez-ud-mini-display-list': {
                'tap': '_toggleFullList'
            },
            '.ez-ud-full-list-close': {
                'tap': function (e) {
                    e.preventDefault();
                    this._hideFullList();
                }
            },
            '.ez-ud-full-list-item-remove': {
                'tap': '_confirmRemoval',
            }
        },

        initializer: function () {
            this.after('confirmedListChange', function (e) {
                if ( this._hasConfirmedList() ) {
                    this.render();
                } else {
                    // do not rerender the view if it's getting empty so that
                    // the hiding transition can be seen
                    this._uiHandleEmptyClass();
                    this._hideFullList();
                }
            });
            this.after('showFullListChange', this._uiHandleFullList);
            this.after('trackOutsideEventsChange', this._handleClickOutsideEventHandler);
        },

        render: function () {
            var container = this.get('container');

            container.setHTML(this.template({
                confirmedList: this._jsonifyList(this.get('confirmedList')).reverse(),
                miniDisplayList: this._getMiniDisplayList(),
                remainingCount: this._getRemainingCount(),
            }));
            this._uiHandleEmptyClass();
            return this;
        },

        /**
         * tap event handler on the remove button.
         *
         * @method _removeContent
         * @param {EventFacade} e
         * @protected
         */
        _confirmRemoval: function (e) {
            var contentId = e.target.getAttribute('data-content-id');

            e.preventDefault();
            this._set('trackOutsideEvents', false);
            this.fire('confirmBoxOpen', {
                config: {
                    title: "Are you sure you want to remove this item?",
                    confirmHandler: Y.bind(function () {
                        this._removeContent(contentId);
                        this._set('trackOutsideEvents', true);
                    }, this),
                    cancelHandler: Y.bind(function () {
                        this._set('trackOutsideEvents', true);
                    }, this),
                },
            });
        },

        /**
         * Fires the unselectContent to remove the content from the universal
         * discovery selection.
         *
         * @method _removeContent
         * @param {String} contentId
         * @protected
         */
        _removeContent: function (contentId) {
            /**
             * Fired to unselect a content in universal discovery widget
             *
             * @event unselectContent
             * @param {String} contentId
             */
            this.fire('unselectContent', {
                contentId: contentId
            });
        },

        /**
         * Adds or removes the `is-empty` class on the container depending on
         * the confirmedList content
         *
         * @method _uiHandleEmptyClass
         * @protected
         */
        _uiHandleEmptyClass: function () {
            var container = this.get('container');

            if ( this._hasConfirmedList() ) {
                container.removeClass(IS_EMPTY);
            } else {
                container.addClass(IS_EMPTY);
            }
        },

        /**
         * Show or hide the full list depending on the `showFullList` flag
         *
         * @method _uiHandleFullList
         * @protected
         */
        _uiHandleFullList: function () {
            var container = this.get('container');

            if ( this.get('showFullList') ) {
                container.addClass(IS_FULL_LIST_VISIBLE);
                this._set('trackOutsideEvents', true);
            } else {
                container.removeClass(IS_FULL_LIST_VISIBLE);
                this._set('trackOutsideEvents', false);
            }
        },

        /**
         * `trackOutsideEventsChange` event handler.
         * Adds or removes the click outside event handler depending on the
         * `trackOutsideEvents` attribute value.
         *
         * @method _handleClickOutsideEventHandler
         * @protected
         */
        _handleClickOutsideEventHandler: function () {
            if ( this.get('trackOutsideEvents') ) {
                this._addClickOutsideHandler();
            } else {
                this._removeClickOutsideHandler();
            }
        },

        /**
         * Adds the click outside event handler
         *
         * @method _addClickOutsideHandler
         * @protected
         */
        _addClickOutsideHandler: function () {
            this._clickOutsideHandler = this.get('container').on('clickoutside', Y.bind(function (e) {
                // This condition is workaround to make sure any tap on the
                // confirmbox does not hide the full list.
                if ( !e.target.ancestor('.ez-confirmbox-container', true) ) {
                    this._hideFullList();
                }
            }, this));
        },

        /**
         * Removes the click outside event handler
         *
         * @method _removeClickOutsideHandler
         * @protected
         */
        _removeClickOutsideHandler: function () {
            if ( this._clickOutsideHandler ) {
                this._clickOutsideHandler.detach();
                this._clickOutsideHandler = null;
            }
        },

        /**
         * Toggles the `showFullList` flag
         *
         * @method _toggleFullList
         * @protected
         */
        _toggleFullList: function () {
            this._set('showFullList', !this.get('showFullList'));
        },

        /**
         * Hides the full list
         *
         * @method _hideFullList
         * @protected
         */
        _hideFullList: function () {
            this._set('showFullList', false);
        },

        /**
         * Returns the number of content in the content list that won't be
         * displayed in the *mini list*
         *
         * @method _getRemainingCount
         * @protected
         * @return {Number}
         */
        _getRemainingCount: function () {
            if ( !this._hasConfirmedList() || this.get('confirmedList').length < MAX_MINI_DISPLAY ) {
                return 0;
            }
            return this.get('confirmedList').length - MAX_MINI_DISPLAY;
        },

        /**
         * Extracts a portion of the content list to display before the *+X
         * more* message. If the confirmed list is not filled, it returns false.
         *
         * @method _getMiniDisplayList
         * @protected
         * @return {Array|false}
         */
        _getMiniDisplayList: function () {
            var list,
                hasConfirmedList = this._hasConfirmedList();

            if ( hasConfirmedList ) {
                list = this.get('confirmedList').concat().reverse();
                return this._jsonifyList(list.slice(0, MAX_MINI_DISPLAY));
            }
            return false;
        },

        /**
         * Transforms the given confirmed list so that it's suitable to be used
         * in the template, ie the models are replaced by the result of the
         * `toJSON` method
         *
         * @method _jsonifyList
         * @protected
         * @param {Array} list
         */
        _jsonifyList: function (list) {
            var res = [];

            Y.Array.each(list, function (struct, i) {
                res[i] = {
                    contentInfo: struct.contentInfo.toJSON(),
                    location: struct.location.toJSON(),
                    contentType: struct.contentType.toJSON(),
                };
            });
            return res;
        },

        /**
         * Checks whether the confirmed list is filled or not
         *
         * @method _hasConfirmedList
         * @protected
         * @return {Boolean}
         */
        _hasConfirmedList: function () {
            return !!this.get('confirmedList');
        },

        /**
         * Custom reset implementation to make sure to also reset the
         * read only `showFullList` attribute.
         *
         * @method reset
         * @param {String} name
         */
        reset: function (name) {
            if ( name === 'showFullList' ) {
                this._set('showFullList', false);
                return;
            }
            this.constructor.superclass.reset.apply(this, arguments);
        },
    }, {
        ATTRS: {
            /**
             * The current confirmed list. It's an array containing one or
             * several content structure (ie an object with a contentInfo, a
             * location and a content type models) or null.
             *
             * @attribute confirmedList
             * @type {Array|Null}
             */
            confirmedList: {
                value: null,
            },

            /**
             * Flag indicating whether the full list should be shown
             *
             * @attribute showFullList
             * @type Boolean
             * @readOnly
             */
            showFullList: {
                readOnly: true,
                value: false,
            },

            /**
             * Flag indicating whether the confirmed list should track the
             * outside events (click).
             *
             * @attribute trackOutsideEvents
             * @readOnly
             */
            trackOutsideEvents: {
                readOnly: true,
            }
        },
    });
});