Skip to content
Browse files

HtmlTable.Select, HtmlTable.Zebra: Adding support for hidden rows in …

…tables
  • Loading branch information...
1 parent bce9546 commit 8760f79ff484d6d19c545d497287c86fb2062a3f @anutron anutron committed Jan 5, 2011
View
1 Docs/Interface/HtmlTable.Select.md
@@ -31,6 +31,7 @@ HtmlTable Method: constructor
* selectable - (*boolean*) if *true* the rows will be selectable. Defaults to *false*.
* allowMultiSelect - (*boolean*) if *true* (the default) the user can select more than one row at a time.
* shiftForMultiSelect - (*boolean*) enables support for holding shift to multi-select files (defaults to *false*). If *false* (and `allowMultiSelect` is *true*), clicking any row selects it.
+* selectHiddenRows - (*boolean*) if *false* (the default), the selection logic ignores hidden rows, as if they were not in the DOM.
### Events
View
2 Source/Element/Element.Position.js
@@ -219,7 +219,7 @@ var local = Element.Position = {
Element.implement({
position: function(options){
- if (options && (options.x != null || options.y != null)) {
+ if (options && (options.x != null || options.y != null)){
return (original ? original.apply(this, arguments) : this);
}
var position = this.setStyle('position', 'absolute').calculatePosition(options);
View
2 Source/Forms/Form.Request.js
@@ -190,7 +190,7 @@ if (!window.Form) window.Form = {};
Element.implement('formUpdate', function(update, options){
var fq = this.retrieve('form.request');
- if (!fq) {
+ if (!fq){
fq = new Form.Request(this, update, options);
} else {
if (update) fq.setTarget(update);
View
65 Source/Interface/HtmlTable.Select.js
@@ -37,7 +37,8 @@ HtmlTable = Class.refactor(HtmlTable, {
classSelectable: 'table-selectable',
shiftForMultiSelect: true,
allowMultiSelect: true,
- selectable: false
+ selectable: false,
+ selectHiddenRows: false
},
initialize: function(){
@@ -49,7 +50,7 @@ HtmlTable = Class.refactor(HtmlTable, {
this.bound = {
mouseleave: this.mouseleave.bind(this),
clickRow: this.clickRow.bind(this),
- activateKeyboard: function() {
+ activateKeyboard: function(){
if (this.keyboard && this.selectEnabled) this.keyboard.activate();
}.bind(this)
};
@@ -82,10 +83,6 @@ HtmlTable = Class.refactor(HtmlTable, {
return ret;
},
- isSelected: function(row){
- return this.selectedRows.contains(row);
- },
-
toggleRow: function(row){
return this[(this.isSelected(row) ? 'de' : '') + 'selectRow'](row);
},
@@ -109,23 +106,31 @@ HtmlTable = Class.refactor(HtmlTable, {
return this;
},
+ isSelected: function(row){
+ return this.selectedRows.contains(row);
+ },
+
+ getSelected: function(){
+ return this.selectedRows;
+ },
+
getSelected: function(){
return this.selectedRows;
},
- serialize: function() {
+ serialize: function(){
var previousSerialization = this.previous.apply(this, arguments) || {};
- if (this.options.selectable) {
- previousSerialization.selectedRows = this.selectedRows.map(function(row) {
+ if (this.options.selectable){
+ previousSerialization.selectedRows = this.selectedRows.map(function(row){
return Array.indexOf(this.body.rows, row);
}.bind(this));
}
return previousSerialization;
},
- restore: function(tableState) {
- if(this.options.selectable && tableState.selectedRows) {
- tableState.selectedRows.each(function(index) {
+ restore: function(tableState){
+ if(this.options.selectable && tableState.selectedRows){
+ tableState.selectedRows.each(function(index){
this.selectRow(this.body.rows[index]);
}.bind(this));
}
@@ -167,7 +172,9 @@ HtmlTable = Class.refactor(HtmlTable, {
endRow = tmp;
}
- for (var i = startRow; i <= endRow; i++) this[method](rows[i], true);
+ for (var i = startRow; i <= endRow; i++){
+ if (this.options.selectHiddenRows || rows[i].isDisplayed()) this[method](rows[i], true);
+ }
return this;
},
@@ -211,7 +218,7 @@ HtmlTable = Class.refactor(HtmlTable, {
shiftFocus: function(offset, event){
if (!this.focused) return this.selectRow(this.body.rows[0], event);
- var to = this.getRowByOffset(offset);
+ var to = this.getRowByOffset(offset, this.options.selectHiddenRows);
if (to === null || this.focused == this.body.rows[to]) return this;
this.toggleRow(this.body.rows[to], event);
},
@@ -230,14 +237,25 @@ HtmlTable = Class.refactor(HtmlTable, {
this.rangeStart = row;
},
- getRowByOffset: function(offset){
+ getRowByOffset: function(offset, includeHiddenRows){
if (!this.focused) return 0;
- var rows = Array.clone(this.body.rows),
- index = rows.indexOf(this.focused) + offset;
-
- if (index < 0) index = null;
- if (index >= rows.length) index = null;
-
+ var index = Array.indexOf(this.body.rows, this.focused);
+ if ((index == 0 && offset < 0) || (index == this.body.rows.length -1 && offset > 0)) return null;
+ if (includeHiddenRows){
+ index += offset;
+ } else {
+ var limit = 0,
+ count = 0;
+ if (offset > 0){
+ while (count < offset && index < this.body.rows.length -1){
+ if (this.body.rows[++index].isDisplayed()) count++;
+ }
+ } else {
+ while (count > offset && index > 0){
+ if (this.body.rows[--index].isDisplayed()) count--;
+ }
+ }
+ }
return index;
},
@@ -257,16 +275,15 @@ HtmlTable = Class.refactor(HtmlTable, {
if (this.options.useKeyboard || this.keyboard){
if (!this.keyboard) this.keyboard = new Keyboard();
- if (!this.selectKeysDefined) {
+ if (!this.selectKeysDefined){
this.selectKeysDefined = true;
var timer, held;
var move = function(offset){
var mover = function(e){
clearTimeout(timer);
e.preventDefault();
-
- var to = this.body.rows[this.getRowByOffset(offset)];
+ var to = this.body.rows[this.getRowByOffset(offset, this.options.selectHiddenRows)];
if (e.shift && to && this.isSelected(to)){
this.deselectRow(this.focused);
this.focused = to;
View
8 Source/Interface/HtmlTable.Sort.js
@@ -121,17 +121,17 @@ HtmlTable = Class.refactor(HtmlTable, {
return this.sort(Array.indexOf(this.head.getElements(this.options.thSelector).flatten(), el) % this.body.rows[0].cells.length);
},
- serialize: function() {
+ serialize: function(){
var previousSerialization = this.previous.apply(this, arguments) || {};
- if (this.options.sortable) {
+ if (this.options.sortable){
previousSerialization.sortIndex = this.sorted.index;
previousSerialization.sortReverse = this.sorted.reverse;
}
return previousSerialization;
},
- restore: function(tableState) {
- if(this.options.sortable && tableState.sortIndex) {
+ restore: function(tableState){
+ if(this.options.sortable && tableState.sortIndex){
this.sort(tableState.sortIndex, tableState.sortReverse);
}
this.previous.apply(this, arguments);
View
11 Source/Interface/HtmlTable.Zebra.js
@@ -15,6 +15,7 @@ authors:
requires:
- /HtmlTable
+ - /Element.Shortcuts
- /Class.refactor
provides: [HtmlTable.Zebra]
@@ -26,7 +27,8 @@ HtmlTable = Class.refactor(HtmlTable, {
options: {
classZebra: 'table-tr-odd',
- zebra: true
+ zebra: true,
+ zebraOnlyVisibleRows: true
},
initialize: function(){
@@ -36,7 +38,12 @@ HtmlTable = Class.refactor(HtmlTable, {
},
updateZebras: function(){
- Array.each(this.body.rows, this.zebra, this);
+ var index = 0;
+ Array.each(this.body.rows, function(row){
+ if (!this.options.zebraOnlyVisibleRows || row.isDisplayed()){
+ this.zebra(row, index++);
+ }
+ }, this);
},
setRowStyle: function(row, i){
View
49 Specs/1.3/Interface/HtmlTable.Select.js
@@ -17,6 +17,55 @@ describe('HtmlTable.Select', function(){
expect(table.isSelected(row)).toEqual(false);
});
+
+ it('should return the selected row(s)', function(){
+ var table = getTable();
+
+ var rows = table.body.getChildren();
+ table.selectRow(rows[0]);
+ var selected = table.getSelected();
+ expect(selected[0]).toEqual(rows[0]);
+ expect(selected.length).toEqual(1);
+
+ table.selectRow(rows[1]);
+ selected = table.getSelected();
+ expect(selected[1]).toEqual(rows[1]);
+ expect(selected.length).toEqual(2);
+ });
+
+
+ it('should skip hidden rows when selecting rows', function(){
+ var table = getTable();
+
+ var rows = table.body.getChildren();
+ rows[1].setStyle('display', 'none');
+ table.selectRange(rows[0], rows[2]);
+ var selected = table.getSelected();
+ expect(selected.length).toEqual(2);
+ expect(selected[0]).toEqual(rows[0]);
+ expect(selected[1]).toEqual(rows[2]);
+ });
+
+ it('should select all and select none', function(){
+ var table = getTable();
+ var rows = table.body.getChildren();
+
+ table.selectAll();
+ var selected = table.getSelected();
+
+ expect(selected.length).toEqual(3);
+ expect(selected[0]).toEqual(rows[0]);
+ expect(selected[1]).toEqual(rows[1]);
+ expect(selected[2]).toEqual(rows[2]);
+ expect(selected[0].hasClass('table-tr-selected')).toBeTruthy();
+
+ table.selectNone();
+ selected = table.getSelected();
+ expect(selected.length).toEqual(0);
+ expect(rows[0].hasClass('table-tr-selected')).toBeFalsy();
+ });
+
+
it('should serialize the state of the table', function(){
var SelectableTable = new HtmlTable({
selectable: true,
View
39 Specs/1.3/Interface/HtmlTable.Zebra.js
@@ -0,0 +1,39 @@
+describe('HtmlTable.Zebra', function(){
+
+ var getTable = function(){
+ return new HtmlTable({
+ rows: [[0],[1],[2]]
+ });
+ };
+
+ it('should alternate the zebra class on/off', function(){
+ var table = getTable();
+ var rows = table.body.getChildren();
+ expect(rows[0].hasClass('table-tr-odd')).toBeTruthy();
+ expect(rows[1].hasClass('table-tr-odd')).toBeFalsy();
+ expect(rows[2].hasClass('table-tr-odd')).toBeTruthy();
+ });
+
+ it('should update the zebras on row add/remove', function(){
+ var table = getTable();
+ table.push([3]);
+ table.push([4]);
+ var rows = table.body.getChildren();
+ expect(rows[3].hasClass('table-tr-odd')).toBeFalsy();
+ expect(rows[4].hasClass('table-tr-odd')).toBeTruthy();
+
+ rows[3].destroy();
+ table.updateZebras();
+ expect(rows[3].hasClass('table-tr-odd')).toBeFalsy();
+ });
+
+ it('should ignore hidden rows for zebra classes', function(){
+ var table = getTable();
+ var rows = table.body.getChildren();
+ rows[1].setStyle('display','none');
+ table.updateZebras();
+ expect(rows[0].hasClass('table-tr-odd')).toBeTruthy();
+ expect(rows[2].hasClass('table-tr-odd')).toBeFalsy();
+ });
+
+});
View
5 Specs/Configuration.js
@@ -55,11 +55,11 @@ Configuration.sets = {
'Element/Element.Forms', 'Element/Element.Measure', 'Element/Elements.From', 'Element/Element.Shortcuts',
'Element/Element.Event.Pseudos', 'Element/Element.Event.Pseudos.Keys', 'Element/Element.Delegation', 'Element/Element.Pin', 'Element/Element.Position',
'Types/URI', 'Types/URI.Relative', 'Types/Object.Extras_client',
- 'Interface/Keyboard', 'Interface/Keyboard.Extras', 'Interface/HtmlTable', 'Interface/HtmlTable.Sort', 'Interface/HtmlTable.Select',
+ 'Interface/Keyboard', 'Interface/Keyboard.Extras', 'Interface/HtmlTable', 'Interface/HtmlTable.Sort', 'Interface/HtmlTable.Select', 'Interface/Htmltable.Zebra',
'Forms/Form.Validator',
'Fx/Fx.Reveal', 'Fx/Fx.Slide',
'Request/Request.JSONP',
- 'Utilities/Color', 'Utilities/Group', 'Utilities/Table'
+ 'Utilities/Color', 'Utilities/Group', 'Utilities/Table', 'Utilities/Hash.Cookie', 'Utilities/Assets'
]
}
@@ -186,6 +186,7 @@ Configuration.source = {
'Interface/HtmlTable',
'Interface/HtmlTable.Sort',
'Interface/HtmlTable.Select',
+ 'Interface/HtmlTable.Zebra',
'Fx/Fx.Reveal',
'Fx/Fx.Slide',

0 comments on commit 8760f79

Please sign in to comment.
Something went wrong with that request. Please try again.