var _ = require('underscore'); var Backbone = require('backbone'); var CoreView = require('backbone/core-view'); var CustomListCollection = require('./custom-list-collection'); var SearchView = require('./custom-list-search-view'); var CustomListView = require('./custom-list-view'); var headerTemplate = require('./custom-list-header.tpl'); var CustomListAction = require('./custom-list-action-view'); var itemTemplate = require('./custom-list-item.tpl'); var CustomListItemView = require('./custom-list-item-view'); /* * A custom list with possibility to search within values. * * It accepts a collection of (val, label) model attributes or a values array * with the same content or only strings. * * new CustomList({ * showSearch: false, * itemTemplate: itemTemplate, * values: [ * { * val: 'hello', * label: 'hi' * } * ] * }); */ module.exports = CoreView.extend({ module: 'components:custom-list:custom-view', options: { showSearch: true, allowFreeTextInput: false, typeLabel: 'column', itemTemplate: itemTemplate, itemView: CustomListItemView }, className: 'CDB-Box-modal CustomList', tagName: 'div', events: { 'mouseover': '_onMouseOver', 'mouseout': '_onMouseOut' }, initialize: function (opts) { if (!opts.collection) { if (!opts.options) { throw new Error('options array {value, label} is required'); } this.collection = new CustomListCollection(opts.options); } if (opts.position) { this.$el.css(opts.position); } this.options = _.extend({}, this.options, opts); this._selectModel = this.options.selectModel; if (this.options.mouseOverAction) { this._mouseOverAction = this.options.mouseOverAction; } if (this.options.mouseOutAction) { this._mouseOutAction = this.options.mouseOutAction; } this.model = new Backbone.Model({ query: '', visible: false }); this._initBinds(); }, render: function () { this.$el.empty(); this.clearSubViews(); if (this.options.showSearch || this.options.actions) { this._renderHeader(); } if (this.options.showSearch) { this._renderSearch(); } if (this.options.actions) { this._renderActions(); } this._renderList(); if (this.options.showSearch) { this._focusSearch(); } return this; }, _initBinds: function () { this.model.bind('change:visible', this._onVisibleChanged, this); this.model.bind('change:query', this._setActionsVisibility, this); }, _renderHeader: function () { this.$el.prepend(headerTemplate()); }, _renderSearch: function () { this._searchView = new SearchView({ template: this.options.searchTemplate, typeLabel: this.options.typeLabel, searchPlaceholder: this.options.searchPlaceholder, model: this.model }); this.$('.js-header').prepend(this._searchView.render().el); this.addView(this._searchView); }, _renderActions: function () { _.each(this.options.actions, function (action) { var view = new CustomListAction(action); this.$('.js-actions').append(view.render().el); this.addView(view); }, this); }, _setActionsVisibility: function () { this.$('.js-actions').toggleClass('u-hide', this.model.get('query') !== ''); }, _focusSearch: function () { setTimeout(function () { if (this._searchView) { this._searchView.focus(); var input = this._searchView.$('input'); var $initialVal = input.val(); input.val($initialVal + ' '); input.val($initialVal); } }.bind(this), 0); }, _renderList: function () { this._listView = new CustomListView({ model: this.model, allowFreeTextInput: this.options.allowFreeTextInput, collection: this.collection, typeLabel: this.options.typeLabel, itemView: this.options.itemView, itemTemplate: this.options.itemTemplate, size: this.options.size, mouseOverAction: this._mouseOverAction, mouseOutAction: this._mouseOutAction }); this.$el.append(this._listView.render().el); this._listView.highlight(); this.addView(this._listView); this._listView.bind('customEvent', function (eventName, item) { this.trigger(eventName, item, this); }, this); }, highlight: function () { this._listView.highlight(); }, _onVisibleChanged: function (_model, isVisible) { this._resetQuery(); this._toggleVisibility(); isVisible ? this.render() : this.clearSubViews(); }, _resetQuery: function () { var query = this._selectModel && this._selectModel.get(this.options.typeLabel) || ''; this.model.set('query', query); var isInCollection = this.collection.findWhere({ val: query }); if (query && !isInCollection) { this.collection.add({ label: query, val: query }); } }, show: function () { this.model.set('visible', true); }, hide: function () { this.trigger('hidden', this); this.model.set('visible', false); }, toggle: function () { this.model.set('visible', !this.model.get('visible')); }, _toggleVisibility: function () { this.$el.toggleClass('is-visible', !!this.model.get('visible')); }, isVisible: function () { return this.model.get('visible'); }, _onMouseOver: function () { this._mouseOverAction && this._mouseOverAction(); }, _onMouseOut: function () { this._mouseOutAction && this._mouseOutAction(); }, remove: function () { this._listView && this._listView.clean(); CoreView.prototype.remove.call(this); } });