/src/header.js
JavaScript | 225 lines | 108 code | 29 blank | 88 comment | 23 complexity | 54dec951926dbb2f836cb85471868fa4 MD5 | raw file
Possible License(s): MIT
- /*
- backgrid
- http://github.com/wyuenho/backgrid
- Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
- Licensed under the MIT license.
- */
- /**
- HeaderCell is a special cell class that renders a column header cell. If the
- column is sortable, a sorter is also rendered and will trigger a table
- refresh after sorting.
- @class Backgrid.HeaderCell
- @extends Backbone.View
- */
- var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({
- /** @property */
- tagName: "th",
- /** @property */
- events: {
- "click a": "onClick"
- },
- /**
- Initializer.
- @param {Object} options
- @param {Backgrid.Column|Object} options.column
- @throws {TypeError} If options.column or options.collection is undefined.
- */
- initialize: function (options) {
- this.column = options.column;
- if (!(this.column instanceof Column)) {
- this.column = new Column(this.column);
- }
- var column = this.column, collection = this.collection, $el = this.$el;
- this.listenTo(column, "change:editable change:sortable change:renderable",
- function (column) {
- var changed = column.changedAttributes();
- for (var key in changed) {
- if (changed.hasOwnProperty(key)) {
- $el.toggleClass(key, changed[key]);
- }
- }
- });
- this.listenTo(column, "change:direction", this.setCellDirection);
- this.listenTo(column, "change:name change:label", this.render);
- if (Backgrid.callByNeed(column.editable(), column, collection)) $el.addClass("editable");
- if (Backgrid.callByNeed(column.sortable(), column, collection)) $el.addClass("sortable");
- if (Backgrid.callByNeed(column.renderable(), column, collection)) $el.addClass("renderable");
- this.listenTo(collection.fullCollection || collection, "sort", this.removeCellDirection);
- },
- /**
- Event handler for the collection's `sort` event. Removes all the CSS
- direction classes.
- */
- removeCellDirection: function () {
- this.$el.removeClass("ascending").removeClass("descending");
- this.column.set("direction", null);
- },
- /**
- Event handler for the column's `change:direction` event. If this
- HeaderCell's column is being sorted on, it applies the direction given as a
- CSS class to the header cell. Removes all the CSS direction classes
- otherwise.
- */
- setCellDirection: function (column, direction) {
- this.$el.removeClass("ascending").removeClass("descending");
- if (column.cid == this.column.cid) this.$el.addClass(direction);
- },
- /**
- Event handler for the `click` event on the cell's anchor. If the column is
- sortable, clicking on the anchor will cycle through 3 sorting orderings -
- `ascending`, `descending`, and default.
- */
- onClick: function (e) {
- e.preventDefault();
- var column = this.column;
- var collection = this.collection;
- var event = "backgrid:sort";
- function cycleSort(header, col) {
- if (column.get("direction") === "ascending") collection.trigger(event, col, "descending");
- else if (column.get("direction") === "descending") collection.trigger(event, col, null);
- else collection.trigger(event, col, "ascending");
- }
- function toggleSort(header, col) {
- if (column.get("direction") === "ascending") collection.trigger(event, col, "descending");
- else collection.trigger(event, col, "ascending");
- }
- var sortable = Backgrid.callByNeed(column.sortable(), column, this.collection);
- if (sortable) {
- var sortType = column.get("sortType");
- if (sortType === "toggle") toggleSort(this, column);
- else cycleSort(this, column);
- }
- },
- /**
- Renders a header cell with a sorter, a label, and a class name for this
- column.
- */
- render: function () {
- this.$el.empty();
- var column = this.column;
- var sortable = Backgrid.callByNeed(column.sortable(), column, this.collection);
- var label;
- if(sortable){
- label = $("<a>").text(column.get("label")).append("<b class='sort-caret'></b>");
- } else {
- label = document.createTextNode(column.get("label"));
- }
- this.$el.append(label);
- this.$el.addClass(column.get("name"));
- this.$el.addClass(column.get("direction"));
- this.delegateEvents();
- return this;
- }
- });
- /**
- HeaderRow is a controller for a row of header cells.
- @class Backgrid.HeaderRow
- @extends Backgrid.Row
- */
- var HeaderRow = Backgrid.HeaderRow = Backgrid.Row.extend({
- /**
- Initializer.
- @param {Object} options
- @param {Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>} options.columns
- @param {Backgrid.HeaderCell} [options.headerCell] Customized default
- HeaderCell for all the columns. Supply a HeaderCell class or instance to a
- the `headerCell` key in a column definition for column-specific header
- rendering.
- @throws {TypeError} If options.columns or options.collection is undefined.
- */
- initialize: function () {
- Backgrid.Row.prototype.initialize.apply(this, arguments);
- },
- makeCell: function (column, options) {
- var headerCell = column.get("headerCell") || options.headerCell || HeaderCell;
- headerCell = new headerCell({
- column: column,
- collection: this.collection
- });
- return headerCell;
- }
- });
- /**
- Header is a special structural view class that renders a table head with a
- single row of header cells.
- @class Backgrid.Header
- @extends Backbone.View
- */
- var Header = Backgrid.Header = Backbone.View.extend({
- /** @property */
- tagName: "thead",
- /**
- Initializer. Initializes this table head view to contain a single header
- row view.
- @param {Object} options
- @param {Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>} options.columns Column metadata.
- @param {Backbone.Model} options.model The model instance to render.
- @throws {TypeError} If options.columns or options.model is undefined.
- */
- initialize: function (options) {
- this.columns = options.columns;
- if (!(this.columns instanceof Backbone.Collection)) {
- this.columns = new Columns(this.columns);
- }
- this.row = new Backgrid.HeaderRow({
- columns: this.columns,
- collection: this.collection
- });
- },
- /**
- Renders this table head with a single row of header cells.
- */
- render: function () {
- this.$el.append(this.row.render().$el);
- this.delegateEvents();
- return this;
- },
- /**
- Clean up this header and its row.
- @chainable
- */
- remove: function () {
- this.row.remove.apply(this.row, arguments);
- return Backbone.View.prototype.remove.apply(this, arguments);
- }
- });