diff --git a/lib/backgrid.js b/lib/backgrid.js index 6a8324c8..080c2a5f 100644 --- a/lib/backgrid.js +++ b/lib/backgrid.js @@ -2152,7 +2152,11 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({ this.$el.append(label); this.$el.addClass(column.get("name")); + this.$el.attr("data-column-cid", column.cid); this.$el.addClass(column.get("direction")); + if (column.get("attributes")) { + this.$el.attr(column.get("attributes")); + } this.delegateEvents(); return this; } @@ -2221,7 +2225,18 @@ var Header = Backgrid.Header = Backbone.View.extend({ if (!(this.columns instanceof Backbone.Collection)) { this.columns = new Columns(this.columns); } + this.createHeaderRow(); + + this.listenTo(this.columns, "sort", _.bind(function() { + this.createHeaderRow(); + this.render(); + }, this)); + }, + /** + Sets up a new headerRow and attaches it to the view + */ + createHeaderRow: function() { this.row = new Backgrid.HeaderRow({ columns: this.columns, collection: this.collection @@ -2229,11 +2244,13 @@ var Header = Backgrid.Header = Backbone.View.extend({ }, /** - Renders this table head with a single row of header cells. + Renders this table head with a single row of header cells. */ render: function () { + this.$el.empty(); this.$el.append(this.row.render().$el); this.delegateEvents(); + this.trigger("backgrid:header:rendered", this); return this; }, diff --git a/src/header.js b/src/header.js index 5474a440..8f3cfaa0 100644 --- a/src/header.js +++ b/src/header.js @@ -127,7 +127,11 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({ this.$el.append(label); this.$el.addClass(column.get("name")); + this.$el.attr("data-column-cid", column.cid); this.$el.addClass(column.get("direction")); + if (column.get("attributes")) { + this.$el.attr(column.get("attributes")); + } this.delegateEvents(); return this; } @@ -196,7 +200,18 @@ var Header = Backgrid.Header = Backbone.View.extend({ if (!(this.columns instanceof Backbone.Collection)) { this.columns = new Columns(this.columns); } + this.createHeaderRow(); + + this.listenTo(this.columns, "sort", _.bind(function() { + this.createHeaderRow(); + this.render(); + }, this)); + }, + /** + Sets up a new headerRow and attaches it to the view + */ + createHeaderRow: function() { this.row = new Backgrid.HeaderRow({ columns: this.columns, collection: this.collection @@ -204,11 +219,13 @@ var Header = Backgrid.Header = Backbone.View.extend({ }, /** - Renders this table head with a single row of header cells. + Renders this table head with a single row of header cells. */ render: function () { + this.$el.empty(); this.$el.append(this.row.render().$el); this.delegateEvents(); + this.trigger("backgrid:header:rendered", this); return this; }, diff --git a/test/header.js b/test/header.js index cf035ce7..76b127d8 100644 --- a/test/header.js +++ b/test/header.js @@ -1,10 +1,10 @@ /* - backgrid - http://github.com/wyuenho/backgrid + backgrid + http://github.com/wyuenho/backgrid - Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors - Licensed under the MIT license. -*/ + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. + */ describe("A HeaderCell", function () { var col; @@ -274,10 +274,16 @@ describe("A HeaderRow", function () { row = new Backgrid.HeaderRow({ columns: [{ name: "name", - cell: "string" + cell: "string", + attributes: { + colspan: "1" + } }, { name: "year", - cell: "integer" + cell: "integer", + attributes: { + colspan: "2" + } }], collection: books }); @@ -292,6 +298,8 @@ describe("A HeaderRow", function () { expect(th1.hasClass("sortable")).toBe(true); expect(th1.hasClass("renderable")).toBe(true); expect(th1.hasClass("name")).toBe(true); + expect(th1.data("column-cid")).toBe(row.columns.at(0).cid); + expect(th1.attr("colspan")).toBe("1"); expect(th1.find("a").text()).toBe("name"); expect(th1.find("a").eq(1).is($("b", {className: "sort-caret"}))); @@ -300,6 +308,8 @@ describe("A HeaderRow", function () { expect(th2.hasClass("sortable")).toBe(true); expect(th2.hasClass("renderable")).toBe(true); expect(th2.hasClass("year")).toBe(true); + expect(th2.data("column-cid")).toBe(row.columns.at(1).cid); + expect(th2.attr("colspan")).toBe("2"); expect(th2.find("a").text()).toBe("year"); expect(th2.find("a > b:last-child").eq(0).hasClass("sort-caret")).toBe(true); }); @@ -352,7 +362,6 @@ describe("A Header", function () { var head; beforeEach(function () { - books = new Books([{ title: "Alice's Adventures in Wonderland", year: 1865 @@ -363,6 +372,10 @@ describe("A Header", function () { title: "The Catcher in the Rye", year: 1951 }]); + }); + + it("creates a header row on initialization", function() { + spyOn(Backgrid.Header.prototype, "createHeaderRow"); head = new Backgrid.Header({ columns: [{ @@ -374,18 +387,53 @@ describe("A Header", function () { }], collection: books }); + expect(head.createHeaderRow.callCount).toEqual(1); + }); - head.render(); + it("renders again when sort is triggered on the column collection", function() { + head = new Backgrid.Header({ + columns: [{ + name: "name", + cell: "string" + }, { + name: "year", + cell: "integer" + }], + collection: books + }); + + spyOn(head, "createHeaderRow"); + spyOn(head, "render"); + + head.columns.trigger("sort"); + + expect(head.createHeaderRow).toHaveBeenCalled(); + expect(head.render).toHaveBeenCalled(); }); it("renders a header with a row of header cells", function () { + head = new Backgrid.Header({ + columns: [{ + name: "name", + cell: "string" + }, { + name: "year", + cell: "integer" + }], + collection: books + }); + + spyOn(head, "trigger"); + + head.render(); + expect(head.$el[0].tagName).toBe("THEAD"); var th1 = $(head.row.el.childNodes[0]); expect(th1.hasClass("editable")).toBe(true); expect(th1.hasClass("sortable")).toBe(true); expect(th1.hasClass("renderable")).toBe(true); - expect(th1.hasClass("name")).toBe(true); + expect(th1.data("column-cid")).toBe(head.columns.at(0).cid); expect(th1.find("a").text()).toBe("name"); expect(th1.find("a").eq(1).is($("b", {className: "sort-caret"}))); @@ -393,9 +441,12 @@ describe("A Header", function () { expect(th2.hasClass("editable")).toBe(true); expect(th2.hasClass("sortable")).toBe(true); expect(th2.hasClass("renderable")).toBe(true); - expect(th2.hasClass("year")).toBe(true); + expect(th2.data("column-cid")).toBe(head.columns.at(1).cid); expect(th2.find("a").text()).toBe("year"); expect(th2.find("a > b:last-child").eq(0).hasClass("sort-caret")).toBe(true); + + expect(head.trigger.calls.length).toBe(1); + expect(head.trigger).toHaveBeenCalledWith("backgrid:header:rendered", head); }); });