keeweb/app/scripts/views/list-view.js

173 lines
5.6 KiB
JavaScript
Raw Normal View History

2015-10-17 23:49:24 +02:00
'use strict';
var Backbone = require('backbone'),
Resizable = require('../mixins/resizable'),
Scrollable = require('../mixins/scrollable'),
2015-10-17 23:49:24 +02:00
ListSearchView = require('./list-search-view'),
EntryPresenter = require('../presenters/entry-presenter'),
2015-11-08 09:59:46 +01:00
DragDropInfo = require('../comp/drag-drop-info'),
2015-11-11 19:58:29 +01:00
AppSettingsModel = require('../models/app-settings-model'),
2015-10-17 23:49:24 +02:00
baron = require('baron');
var ListView = Backbone.View.extend({
template: require('templates/list.html'),
itemTemplate: require('templates/list-item-short.html'),
emptyTemplate: require('templates/list-empty.html'),
events: {
2015-11-08 09:59:46 +01:00
'click .list__item': 'itemClick',
'dragstart .list__item': 'itemDragStart'
2015-10-17 23:49:24 +02:00
},
views: null,
minWidth: 200,
maxWidth: 500,
itemsEl: null,
initialize: function () {
this.initScroll();
this.views = {};
this.views.search = new ListSearchView({ model: this.model });
this.listenTo(this.views.search, 'select-prev', this.selectPrev);
this.listenTo(this.views.search, 'select-next', this.selectNext);
this.listenTo(this.views.search, 'create-entry', this.createEntry);
2015-10-31 20:09:32 +01:00
this.listenTo(this.views.search, 'create-group', this.createGroup);
2015-10-17 23:49:24 +02:00
this.listenTo(this, 'show', this.viewShown);
this.listenTo(this, 'hide', this.viewHidden);
2015-11-11 19:58:29 +01:00
this.listenTo(this, 'view-resize', this.viewResized);
2015-10-17 23:49:24 +02:00
this.listenTo(Backbone, 'filter', this.filterChanged);
this.listenTo(Backbone, 'entry-updated', this.entryUpdated);
this.items = [];
},
render: function () {
if (!this.itemsEl) {
this.$el.html(this.template());
this.itemsEl = this.$el.find('.list__items>.scroller');
this.views.search.setElement(this.$el.find('.list__header')).render();
this.scroll = baron({
root: this.$el.find('.list__items')[0],
scroller: this.$el.find('.scroller')[0],
bar: this.$el.find('.scroller__bar')[0],
$: Backbone.$
});
this.scrollerBar = this.$el.find('.scroller__bar');
this.scrollerBarWrapper = this.$el.find('.scroller__bar-wrapper');
}
if (this.items.length) {
var presenter = new EntryPresenter(this.getDescField());
var itemsHtml = '';
this.items.forEach(function (item) {
presenter.present(item);
itemsHtml += this.itemTemplate(presenter);
}, this);
this.itemsEl.html(itemsHtml).scrollTop(0);
} else {
this.itemsEl.html(this.emptyTemplate());
}
2015-11-11 19:58:29 +01:00
if (typeof AppSettingsModel.instance.get('listViewWidth') === 'number') {
this.$el.width(AppSettingsModel.instance.get('listViewWidth'));
}
2015-10-17 23:49:24 +02:00
this.pageResized();
return this;
},
getDescField: function() {
return this.model.sort.replace('-', '');
},
itemClick: function(e) {
var id = $(e.target).closest('.list__item').attr('id');
var item = this.items.get(id);
if (!item.active) {
this.selectItem(item);
}
2015-10-26 22:07:19 +01:00
Backbone.trigger('toggle-details', true);
2015-10-17 23:49:24 +02:00
},
selectPrev: function() {
var activeItem = this.items.getActive(),
ix = this.items.indexOf(activeItem);
if (ix > 0) {
this.selectItem(this.items.at(ix - 1));
}
},
selectNext: function() {
var activeItem = this.items.getActive(),
ix = this.items.indexOf(activeItem);
if (ix < this.items.length - 1) {
this.selectItem(this.items.at(ix + 1));
}
},
createEntry: function() {
var newEntry = this.model.createNewEntry();
this.items.unshift(newEntry);
this.render();
this.selectItem(newEntry);
},
2015-10-31 20:09:32 +01:00
createGroup: function() {
var newGroup = this.model.createNewGroup();
Backbone.trigger('edit-group', newGroup);
},
2015-10-17 23:49:24 +02:00
selectItem: function(item) {
this.items.setActive(item);
Backbone.trigger('select-entry', item);
this.itemsEl.find('.list__item--active').removeClass('list__item--active');
var itemEl = document.getElementById(item.get('id'));
itemEl.classList.add('list__item--active');
var listEl = this.itemsEl[0],
itemRect = itemEl.getBoundingClientRect(),
listRect = listEl.getBoundingClientRect();
if (itemRect.top < listRect.top) {
listEl.scrollTop += itemRect.top - listRect.top;
} else if (itemRect.bottom > listRect.bottom) {
listEl.scrollTop += itemRect.bottom - listRect.bottom;
}
},
viewShown: function() {
this.views.search.show();
},
viewHidden: function() {
this.views.search.hide();
},
2015-11-11 19:58:29 +01:00
viewResized: _.throttle(function(size) {
AppSettingsModel.instance.set('listViewWidth', size);
}, 1000),
2015-10-17 23:49:24 +02:00
filterChanged: function(filter) {
this.items = filter.entries;
this.render();
},
entryUpdated: function() {
var scrollTop = this.itemsEl[0].scrollTop;
this.render();
this.itemsEl[0].scrollTop = scrollTop;
2015-11-08 09:59:46 +01:00
},
itemDragStart: function(e) {
e.stopPropagation();
var id = $(e.target).closest('.list__item').attr('id');
e.dataTransfer.setData('text/entry', id);
e.dataTransfer.effectAllowed = 'move';
DragDropInfo.dragObject = this.items.get(id);
2015-10-17 23:49:24 +02:00
}
});
_.extend(ListView.prototype, Resizable);
_.extend(ListView.prototype, Scrollable);
module.exports = ListView;