UNPKG

backgrid

Version:

Backgrid.js is a set of components for building semantic and easily stylable data grid widgets with Backbone.

407 lines (339 loc) 13.5 kB
/* backgrid http://github.com/cloudflare/backgrid Copyright (c) 2013-present Cloudflare, Inc. and contributors Licensed under the MIT license. */ describe("A HeaderCell", function () { var col; var cell; beforeEach(function () { col = new Backbone.Collection([{id: 2}, {id: 1}, {id: 3}]); cell = new Backgrid.HeaderCell({ column: { name: "id", cell: "integer" }, collection: col }); cell.render(); }); it("renders a table header cell with the label text and an optional anchor with sort-caret", function () { expect(cell.el.tagName).toBe("TH"); expect(cell.$el.find("button").text()).toBe("id"); expect(cell.$el.find(".sort-caret").length).toBe(1); expect(cell.$el.find(".sort-caret").attr("aria-hidden")).toEqual("true"); cell.column.set("sortable", false); cell.render(); expect(cell.el.tagName).toBe("TH"); expect(cell.$el.text()).toBe("id"); expect(cell.$el.find(".sort-caret").length).toBe(0); }); it("adds an editable, sortable and a renderable class to the cell if these column attributes are true", function () { var column = { name: "title", cell: "string" }; cell = new Backgrid.HeaderCell({ column: column, collection: col }); expect(cell.$el.hasClass("editable")).toBe(true); expect(cell.$el.hasClass("sortable")).toBe(true); expect(cell.$el.hasClass("renderable")).toBe(true); cell.column.set("editable", false); expect(cell.$el.hasClass("editable")).toBe(false); cell.column.set("sortable", false); expect(cell.$el.hasClass("sortable")).toBe(false); cell.column.set("renderable", false); expect(cell.$el.hasClass("renderable")).toBe(false); var TrueCol = Backgrid.Column.extend({ mySortable: function () { return true; }, myRenderable: function () { return true; }, myEditable: function () { return true; } }); var FalseCol = Backgrid.Column.extend({ mySortable: function () { return false; }, myRenderable: function () { return false; }, myEditable: function () { return false; } }); column = new TrueCol({ name: "title", cell: "string", sortable: "mySortable", renderable: "myRenderable", editable: "myEditable" }); cell = new Backgrid.HeaderCell({ column: column, collection: col }); expect(cell.$el.hasClass("editable")).toBe(true); expect(cell.$el.hasClass("sortable")).toBe(true); expect(cell.$el.hasClass("renderable")).toBe(true); column = new FalseCol({ name: "title", cell: "string", sortable: "mySortable", renderable: "myRenderable", editable: "myEditable" }); cell = new Backgrid.HeaderCell({ column: column, collection: col }); expect(cell.$el.hasClass("editable")).toBe(false); expect(cell.$el.hasClass("sortable")).toBe(false); expect(cell.$el.hasClass("renderable")).toBe(false); column = new Backgrid.Column({ name: "title", cell: "string", sortable: function () { return true; }, editable: function () { return true; }, renderable: function () { return true; } }); cell = new Backgrid.HeaderCell({ column: column, collection: col }); expect(cell.$el.hasClass("editable")).toBe(true); expect(cell.$el.hasClass("sortable")).toBe(true); expect(cell.$el.hasClass("renderable")).toBe(true); }); it("will rerender with the column name and/or label changes", function () { expect(cell.$el.find("button").text(), "id"); expect(cell.$el.hasClass("id"), true); cell.column.set("name", "name"); expect(cell.$el.find("name"), true); expect(cell.$el.hasClass("name"), true); cell.column.set("label", "Name"); expect(cell.$el.find("button").text(), "Name"); expect(cell.$el.hasClass("Name"), true); }); it("will put a class indicating the sorting direction if `direction` is set in the column", function () { cell = new Backgrid.HeaderCell({ column: { name: "id", cell: "integer", direction: "descending" }, collection: col }); cell.render(); expect(cell.el.tagName).toBe("TH"); expect(cell.$el.find("button").text()).toBe("id"); expect(cell.$el.find(".sort-caret").length).toBe(1); expect(cell.$el.hasClass("descending")).toBe(true); }); it("triggers `backgrid:sort` with the column and direction set to 'ascending' if the column's direction is not set", function () { var column, direction; cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBe("ascending"); }); it("triggers `backgrid:sort` with the column and direction set to 'descending' if the column's direction is set to 'ascending'", function () { var column, direction; cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.column.set("direction", "ascending"); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBe("descending"); }); it("triggers `backgrid:sort` with the column and direction set to `null` if the column's direction is set to 'descending'", function () { var column, direction; cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.column.set("direction", "descending"); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBeNull(); }); it("will set the column to the correct direction when `change:direction` is triggered from the column", function () { cell.column.set("direction", "ascending"); expect(cell.$el.hasClass("ascending")).toBe(true); cell.column.set("direction", "descending"); expect(cell.$el.hasClass("descending")).toBe(true); cell.column.set("direction", null); expect(cell.$el.hasClass("ascending")).toBe(false); expect(cell.$el.hasClass("descending")).toBe(false); }); it("will remove its direction CSS class if `backgrid:sorted` is triggered from the collection or pageableCollection#fullCollection", function () { cell.column.set("direction", "ascending"); expect(cell.$el.hasClass("ascending")).toBe(true); cell.collection.comparator = "id"; cell.collection.sort(); cell.collection.trigger("backgrid:sorted"); expect(cell.$el.hasClass("ascending")).toBe(false); expect(cell.$el.hasClass("descending")).toBe(false); col = new Backbone.PageableCollection(col.toJSON(), { mode: "client" }); col.setSorting("id", 1); cell = new Backgrid.HeaderCell({ column: { name: "id", cell: "integer" }, collection: col }); cell.column.set("direction", "ascending"); expect(cell.$el.hasClass("ascending")).toBe(true); cell.collection.fullCollection.comparator = "id"; cell.collection.fullCollection.sort(); cell.collection.fullCollection.trigger("backgrid:sorted"); expect(cell.$el.hasClass("ascending")).toBe(false); expect(cell.$el.hasClass("descending")).toBe(false); }); it("with `sortType` set to `toggle`, triggers `backgrid:sort` with the column and direction set to 'ascending' if the column's direction is not set", function () { var column, direction; cell.column.set("sortType", "toggle"); cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBe("ascending"); }); it("with `sortType` set to `toggle`, triggers `backgrid:sort` with the column and direction set to 'descending' if the column's direction is set to 'ascending'", function () { var column, direction; cell.column.set("sortType", "toggle"); cell.column.set("direction", "ascending"); cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBe("descending"); }); it("with `sortType` set to `toggle`, triggers `backgrid:sort` with the column and direction set to 'ascending' if the column's direction is set to 'descending'", function () { var column, direction; cell.column.set("sortType", "toggle"); cell.column.set("direction", "descending"); cell.collection.on("backgrid:sort", function (col, dir) { column = col; direction = dir; }); cell.$el.find("button").click(); expect(column).toBe(cell.column); expect(direction).toBe("ascending"); }); }); describe("A HeaderRow", function () { var Book = Backbone.Model.extend({}); var Books = Backbone.Collection.extend({ model: Book }); var books; var row; beforeEach(function () { books = new Books([{ title: "Alice's Adventures in Wonderland", year: 1865 }, { title: "A Tale of Two Cities", year: 1859 }, { title: "The Catcher in the Rye", year: 1951 }]); row = new Backgrid.HeaderRow({ columns: [{ name: "name", cell: "string" }, { name: "year", cell: "integer" }], collection: books }); row.render(); }); it("renders a row of header cells", function () { expect(row.$el[0].tagName).toBe("TR"); var th1 = $(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.find("button").text()).toBe("name"); expect(th1.find("button").eq(1).is($("b", {className: "sort-caret"}))); var th2 = $(row.el.childNodes[1]); 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.find("button").text()).toBe("year"); expect(th2.find("button > span:last-child").eq(0).hasClass("sort-caret")).toBe(true); }); it("resets the carets of the non-sorting columns", function () { row.$el.find("button").eq(0).click(); // ascending row.$el.find("button").eq(1).click(); // ascending, resets the previous expect(row.$el.find("button").eq(0).hasClass("ascending")).toBe(false); expect(row.$el.find("button").eq(1).hasClass("ascending")).toBe(false); }); it("inserts or removes a cell if a column is added or removed", function () { row.columns.add({name: "price", cell: "number"}); expect(row.$el.children().length).toBe(3); var lastTh = $(row.el.lastChild); expect(lastTh.hasClass("editable")).toBe(true); expect(lastTh.hasClass("sortable")).toBe(true); expect(lastTh.hasClass("renderable")).toBe(true); expect(lastTh.hasClass("price")).toBe(true); expect(lastTh.find("button").text()).toBe("price"); expect(lastTh.find("button > span:last-child").eq(0).hasClass("sort-caret")).toBe(true); row.columns.add({name: "publisher", cell: "string", renderable: false}); expect(row.$el.children().length).toBe(4); expect(row.$el.children().last().find("button").text()).toBe("publisher"); expect(row.$el.children().last().hasClass("renderable")).toBe(false); row.columns.remove(row.columns.first()); expect(row.$el.children().length).toBe(3); var firstTh = $(row.el.firstChild); expect(firstTh.hasClass("editable")).toBe(true); expect(firstTh.hasClass("sortable")).toBe(true); expect(firstTh.hasClass("renderable")).toBe(true); expect(firstTh.hasClass("year")).toBe(true); expect(firstTh.find("button").text()).toBe("year"); expect(firstTh.find("button > span:last-child").eq(0).hasClass("sort-caret")).toBe(true); }); }); describe("A Header", function () { var Book = Backbone.Model.extend({}); var Books = Backbone.Collection.extend({ model: Book }); var books; var head; beforeEach(function () { books = new Books([{ title: "Alice's Adventures in Wonderland", year: 1865 }, { title: "A Tale of Two Cities", year: 1859 }, { title: "The Catcher in the Rye", year: 1951 }]); head = new Backgrid.Header({ columns: [{ name: "name", cell: "string" }, { name: "year", cell: "integer" }], collection: books }); head.render(); }); it("renders a header with a row of header cells", function () { 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.find("button").text()).toBe("name"); expect(th1.find("button").eq(1).is($("b", {className: "sort-caret"}))); var th2 = $(head.row.el.childNodes[1]); 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.find("button").text()).toBe("year"); expect(th2.find("button > span:last-child").eq(0).hasClass("sort-caret")).toBe(true); }); });