Skip to content

Commit

Permalink
[FEAT] Enable row toggling with body property (#792)
Browse files Browse the repository at this point in the history
  • Loading branch information
frykten authored Oct 27, 2021
1 parent d34b76c commit 3268e40
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 4 deletions.
5 changes: 4 additions & 1 deletion addon/components/-private/row-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default Component.extend({
columns: undefined,
rowMetaCache: undefined,
rowSelectionMode: undefined,
rowToggleMode: undefined,
rowValue: undefined,
rowsCount: undefined,

Expand All @@ -64,16 +65,18 @@ export default Component.extend({
'cells',
'canSelect',
'rowSelectionMode',
'rowToggleMode',
'rowsCount',
function() {
let rowValue = this.get('rowValue');
let rowMeta = this.get('rowMeta');
let cells = this.get('cells');
let canSelect = this.get('canSelect');
let rowSelectionMode = canSelect ? this.get('rowSelectionMode') : 'none';
let rowToggleMode = this.get('rowToggleMode');
let rowsCount = this.get('rowsCount');

return { rowValue, rowMeta, cells, rowSelectionMode, rowsCount };
return { rowValue, rowMeta, cells, rowSelectionMode, rowToggleMode, rowsCount };
}
),

Expand Down
8 changes: 8 additions & 0 deletions addon/components/ember-tbody/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ export default Component.extend({
*/
rowSelectionMode: defaultTo(SELECT_MODE.MULTIPLE),

/**
When true, this option enables the toggling of rows without using the ctrlKey or metaKey.
@argument rowToggleMode
@type boolean
*/
rowToggleMode: defaultTo(false),

/**
When true, this option causes selecting all of a node's children to also
select the node itself.
Expand Down
5 changes: 3 additions & 2 deletions addon/components/ember-tbody/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
rowMetaCache=this.rowMetaCache

canSelect=this.canSelect
rowSelectionMode=this.rowSelectionMode
checkboxSelectionMode=this.checkboxSelectionMode

rowSelectionMode=this.rowSelectionMode
rowToggleMode=this.rowToggleMode
rowsCount=this.wrappedRows.length

as |api|
Expand All @@ -36,6 +36,7 @@
rowMeta=api.rowMeta
cells=api.cells
rowSelectionMode=api.rowSelectionMode
rowToggleMode=api.rowToggleMode
rowsCount=api.rowsCount

row=(component "ember-tr" api=api)
Expand Down
4 changes: 3 additions & 1 deletion addon/components/ember-tr/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export default Component.extend({

rowSelectionMode: readOnly('api.rowSelectionMode'),

rowToggleMode: readOnly('api.rowToggleMode'),

isHeader: readOnly('api.isHeader'),

isSelected: readOnly('rowMeta.isSelected'),
Expand All @@ -100,7 +102,7 @@ export default Component.extend({
let rowMeta = this.get('rowMeta');

if (rowMeta && rowSelectionMode === SELECT_MODE.MULTIPLE) {
let toggle = event.ctrlKey || event.metaKey;
let toggle = event.ctrlKey || event.metaKey || this.get('rowToggleMode');
let range = event.shiftKey;

rowMeta.select({ toggle, range });
Expand Down
1 change: 1 addition & 0 deletions tests/helpers/generate-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const fullTable = hbs`
selectingChildrenSelectsParent=selectingChildrenSelectsParent
checkboxSelectionMode=checkboxSelectionMode
rowSelectionMode=rowSelectionMode
rowToggleMode=rowToggleMode
selection=selection
selectionMatchFunction=selectionMatchFunction
Expand Down
121 changes: 121 additions & 0 deletions tests/integration/components/selection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,127 @@ module('Integration | selection', () => {
});
});

module('rowToggleMode', function() {
componentModule('true', function() {
test('Can select a row by clicking on it', async function(assert) {
await generateTable(this, { rowToggleMode: true });

assert.ok(table.validateSelected(), 'the row is not marked as selected on initialization');

await table.selectRow(0);

assert.ok(table.validateSelected(0), 'the row is selected after being clicked');
});

test('Can toggle a row', async function(assert) {
await generateTable(this, { rowToggleMode: true });

let row = table.body.rows.objectAt(0);

assert.ok(table.validateSelected(), 'the row is not toggled on');

await row.clickWith();

assert.ok(table.validateSelected(0), 'the row is toggled on');

await row.clickWith();

assert.ok(table.validateSelected(), 'the row is toggled back off');
});

test('Can toggle multiple rows', async function(assert) {
await generateTable(this, { rowToggleMode: true });

let rowOne = table.rows.objectAt(0);
let rowTwo = table.rows.objectAt(1);

assert.ok(table.validateSelected(), 'the rows are not selected');

await rowOne.clickWith();
await rowTwo.clickWith();

assert.ok(table.validateSelected(0, 1), 'the rows are selected');

await rowOne.clickWith();
await rowTwo.clickWith();

assert.ok(table.validateSelected(), 'the rows are toggled back off');
});
});

componentModule('false', function() {
test('Cannot toggle a row', async function(assert) {
await generateTable(this, { rowToggleMode: false });

await table.selectRow(0);

assert.ok(table.validateSelected(0), 'the row is toggled on');

let row = table.rows.objectAt(0);

await row.clickWith();

assert.ok(table.validateSelected(0), 'the row is still on');
});

test('Cannot toggle multiple rows', async function(assert) {
await generateTable(this, { rowToggleMode: false });

assert.ok(table.validateSelected(), 'no rows are selected');

let rowOne = table.rows.objectAt(0);
let rowTwo = table.rows.objectAt(1);

await rowOne.clickWith();

assert.ok(table.validateSelected(0), 'the first row is selected');

await rowTwo.clickWith();

assert.ok(table.validateSelected(1), 'the second row is selected');
});

test('Can toggle a row with meta and control', async function(assert) {
await generateTable(this, { rowToggleMode: false });

let row = table.body.rows.objectAt(0);

for (let key of ['ctrlKey', 'metaKey']) {
assert.ok(table.validateSelected(), 'the row is not toggled on');

await row.clickWith({ [key]: true });

assert.ok(table.validateSelected(0), 'the row is toggled on');

await row.clickWith({ [key]: true });

assert.ok(table.validateSelected(), 'the row is toggled back off');
}
});

test('Can toggle multiple rows with meta and control', async function(assert) {
await generateTable(this, { rowToggleMode: false });

let rowOne = table.rows.objectAt(0);
let rowTwo = table.rows.objectAt(1);

for (let key of ['ctrlKey', 'metaKey']) {
assert.ok(table.validateSelected(), 'the rows are not selected');

await rowOne.clickWith({ [key]: true });
await rowTwo.clickWith({ [key]: true });

assert.ok(table.validateSelected(0, 1), 'the rows are selected');

await rowOne.clickWith({ [key]: true });
await rowTwo.clickWith({ [key]: true });

assert.ok(table.validateSelected(), 'the rows are toggled back off');
}
});
});
});

componentModule('misc', function() {
test('Can disable selection by not using an action', async function(assert) {
assert.expect(3);
Expand Down

0 comments on commit 3268e40

Please sign in to comment.