/beancounter/static/js/lib.js
JavaScript | 202 lines | 154 code | 30 blank | 18 comment | 7 complexity | 96af4042f4f2d49090493dc30b3e15a3 MD5 | raw file
Possible License(s): 0BSD
- // vim: fdm=marker
- /*
- * Copyright (c) 2011-2012 Audrius KaĹžukauskas
- *
- * This file is part of BeanCounter and is released under
- * the ISC license, see LICENSE for more details.
- */
- /*jslint indent: 4, browser: true, nomen: true, sloppy: true */
- /*global $, _, Backbone, DATA */
- var B = {};
- B.Collection = Backbone.Collection.extend({ // {{{
- // Get a list of checked items.
- checked: function () {
- return this.filter(function (model) {
- return model.get('checked');
- });
- },
- // Get a list of checked items ids.
- checkedIds: function () {
- return _(this.checked()).pluck('id');
- }
- }); // }}}
- B.Views = {};
- // Generic table row view.
- B.Views.Row = Backbone.View.extend({ // {{{
- tagName: 'tr',
- events: {
- 'click input[type=checkbox]': 'toggleChecked',
- 'mouseenter': 'showEditIcon',
- 'mouseleave': 'hideEditIcon',
- 'click div.edit': 'edit'
- },
- initialize: function () {
- this.model.on('remove', this.remove, this);
- this.model.on('change:checked', this.toggleClass, this);
- },
- remove: function () {
- this.model.off('remove', this.remove);
- this.model.off('change:checked', this.toggleClass);
- Backbone.View.prototype.remove.call(this);
- },
- render: function () {
- this.$el.html(this.template(this.model.toJSON()));
- return this;
- },
- toggleChecked: function () {
- this.model.toggleChecked();
- },
- toggleClass: function () {
- this.$el.removeAttr('style').toggleClass('checked');
- },
- showEditIcon: function () {
- var icon = this.$('div.edit');
- if (!icon.prop('disabled')) {
- icon.show();
- }
- },
- hideEditIcon: function () {
- var icon = this.$('div.edit');
- if (!icon.prop('disabled')) {
- icon.hide();
- }
- },
- edit: function () {
- var Form = this.formFactory(),
- form = new Form({model: this.model});
- this.$el.after(form.render().el);
- this.remove();
- form.focus();
- this.model.trigger('edit:start');
- }
- }); // }}}
- // Generic form view.
- B.Views.Form = Backbone.View.extend({ // {{{
- tagName: 'tr',
- events: {
- 'keydown': 'processKeyDown',
- 'click button[name=save]': 'saveChanges',
- 'click button[name=cancel]': 'remove'
- },
- // Get form field values.
- getValues: function () {
- var values = {};
- this.$('input[type=text]').each(function () {
- values[this.name] = this.value;
- });
- return values;
- },
- processKeyDown: function (e) {
- switch (e.keyCode) {
- case 13: // Enter.
- this.saveChanges();
- break;
- case 27: // Esc.
- this.remove();
- break;
- }
- },
- focus: function () {
- this.$('td:nth-child(2) input').focus();
- }
- }); // }}}
- // Generic table view.
- B.Views.Table = Backbone.View.extend({ // {{{
- events: {
- 'click input.check-all': 'toggleCheckAll'
- },
- initialize: function () {
- this.collection.on('reset', this.render, this);
- this.collection.on('add', this.appendNew, this);
- this.collection.on('sort', this.sortTable, this);
- this.collection.on('remove', this.showEmptyNotice, this);
- },
- render: function () {
- // Clear tbody contents before rendering.
- this.$('tbody').empty();
- this.$('input.check-all').prop('checked', false);
- if (this.collection.isEmpty()) {
- this.$('tr.empty-msg').show();
- this.$('input.check-all').hide();
- } else {
- this.$('tr.empty-msg').hide();
- this.$('input.check-all').show();
- this.collection.each(function (model) {
- this.append(model);
- }, this);
- this.sortTable();
- }
- return this;
- },
- append: function (model) {
- var Row = this.rowFactory(),
- row = new Row({model: model}),
- $el = row.render().$el;
- this.$el.append($el);
- return $el;
- },
- // Append newly created row to the table.
- appendNew: function (model) {
- var $el = this.append(model);
- this.sortTable();
- this.$('input.check-all').prop('checked', false).show();
- $el.css({backgroundColor: '#eaa228'})
- .animate({backgroundColor: '#fff'}, 1000);
- },
- sortTable: function () {
- var thIndex = this.$('th.sort-header').index();
- this.$('tbody td').filter(function () {
- return $(this).index() === thIndex;
- }).sortElements(function (a, b) {
- return $.text([a]) > $.text([b]) ? 1 : -1;
- }, function () {
- return this.parentNode;
- });
- },
- toggleCheckAll: function (e) {
- var checked = e.target.checked;
- this.collection.each(function (model) {
- if (model.get('checked') !== checked) {
- model.toggleChecked();
- }
- });
- this.$('tbody input[type=checkbox]').prop('checked', checked);
- },
- // Show 'table is empty' notice if collection is empty.
- showEmptyNotice: function () {
- if (this.collection.isEmpty()) {
- this.$('tr.empty-msg').show();
- this.$('input.check-all').hide();
- }
- }
- }); // }}}