Tablecontroller should return only selected items

Tablecontroller currently returns a map of items that were
checked/unchecked. Which is confusingly called selected.

Currently, to get the actual selected items, We have to manually filter
through the list. This patch adds a selected field that returns a array
containing only the selected items.

Change-Id: I84bea8931c23cfcaa654e437d39b4faf8ae730e4
Closes-Bug: #1545861
This commit is contained in:
Thai Tran 2016-02-18 11:32:11 -08:00
parent b01ceda1ed
commit b86be6144e
6 changed files with 43 additions and 51 deletions

View File

@ -1,6 +1,6 @@
<action action-classes="'btn btn-danger'"
disabled="tCtrl.numSelected === 0"
item="tCtrl.selections">
disabled="tCtrl.selected.length === 0"
item="tCtrl.selected">
<span class="fa fa-remove"></span>
$text$
</action>

View File

@ -61,25 +61,22 @@
}
function clearSelected() {
ctrl.selected = [];
ctrl.selections = {};
ctrl.numSelected = 0;
}
function getSelected(map) {
return Object.keys(map)
.filter(function isChecked(k) { return map[k].checked; })
.map(function getItem(k) { return map[k].item; });
}
/*
* Toggle the row selection state
*/
function toggleSelect(row, checkedState, broadcast) {
ctrl.selections[row.id] = {
checked: checkedState,
item: row
};
if (checkedState) {
ctrl.numSelected++;
} else {
ctrl.numSelected--;
}
ctrl.selections[row.id] = { checked: checkedState, item: row };
ctrl.selected = getSelected(ctrl.selections);
if (broadcast) {
/*
* should only walk down scope tree that has

View File

@ -77,7 +77,7 @@
/*eslint-enable angular/ng_controller_name */
});
it('should update selected and numSelected when select called', function() {
it('should update selected when select called', function() {
/*eslint-disable angular/ng_controller_name */
var hzTableCtrl = $element.controller('hzTable');
var firstRow = $scope.safeFakeData[0];
@ -85,7 +85,7 @@
/*eslint-enable angular/ng_controller_name */
expect(hzTableCtrl.selections[firstRow.id]).toBeDefined();
expect(hzTableCtrl.numSelected).toBe(1);
expect(hzTableCtrl.selected.length).toBe(1);
});
});
@ -97,36 +97,36 @@
hzTableCtrl = $element.controller('hzTable');
});
it('should have numSelected === 1 when first checkbox is clicked', function() {
it('selected length should be 1 when first checkbox is clicked', function() {
var checkbox = checkboxes.first();
checkbox[0].checked = true;
checkbox.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(1);
expect(hzTableCtrl.selected.length).toBe(1);
});
it('should have numSelected === 0 when first checkbox is clicked, then unclicked',
it('selected length should be 0 when first checkbox is clicked, then unclicked',
function() {
var checkbox = checkboxes.first();
checkbox[0].checked = true;
checkbox.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(1);
expect(hzTableCtrl.selected.length).toBe(1);
checkbox[0].checked = false;
checkbox.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(0);
expect(hzTableCtrl.selected.length).toBe(0);
}
);
it('should have numSelected === 3 and select-all checked when all rows selected', function() {
it('selected length should be 3 and select-all checked when all rows selected', function() {
angular.forEach(checkboxes, function(checkbox) {
checkbox.checked = true;
angular.element(checkbox).triggerHandler('click');
});
expect(hzTableCtrl.numSelected).toBe(3);
expect(hzTableCtrl.selected.length).toBe(3);
expect($element.find('input[hz-select-all]')[0].checked).toBe(true);
});
@ -138,7 +138,7 @@
});
// all checkboxes selected so check-all should be checked
expect(hzTableCtrl.numSelected).toBe(3);
expect(hzTableCtrl.selected.length).toBe(3);
expect($element.find('input[hz-select-all]')[0].checked).toBe(true);
// deselect one checkbox
@ -147,7 +147,7 @@
firstCheckbox.triggerHandler('click');
// check-all should be unchecked
expect(hzTableCtrl.numSelected).toBe(2);
expect(hzTableCtrl.selected.length).toBe(2);
expect($element.find('input[hz-select-all]')[0].checked).toBe(false);
}
);
@ -175,7 +175,7 @@
selectAll[0].checked = true;
selectAll.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(3);
expect(hzTableCtrl.selected.length).toBe(3);
var checkboxes = $element.find('tbody input[hz-select]');
angular.forEach(checkboxes, function(checkbox) {
expect(checkbox.checked).toBe(true);
@ -189,7 +189,7 @@
var checkboxes = $element.find('tbody input[hz-select]');
expect(hzTableCtrl.numSelected).toBe(3);
expect(hzTableCtrl.selected.length).toBe(3);
angular.forEach(checkboxes, function(checkbox) {
expect(checkbox.checked).toBe(true);
});
@ -197,7 +197,7 @@
selectAll[0].checked = false;
selectAll.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(0);
expect(hzTableCtrl.selected.length).toBe(0);
angular.forEach(checkboxes, function(checkbox) {
expect(checkbox.checked).toBe(false);
});
@ -214,7 +214,7 @@
selectAll[0].checked = true;
selectAll.triggerHandler('click');
expect(hzTableCtrl.numSelected).toBe(3);
expect(hzTableCtrl.selected.length).toBe(3);
var checkboxes = $element.find('tbody input[hz-select]');
angular.forEach(checkboxes, function(checkbox) {
expect(checkbox.checked).toBe(true);

View File

@ -67,24 +67,12 @@
// delete selected image objects
function perform(selected) {
deleteImageService.perform(getSelectedImages(selected));
deleteImageService.perform(selected);
}
function allowed() {
return policy.ifAllowed({ rules: [['image', 'delete_image']] });
}
function getSelectedImages(selected) {
return Object.keys(selected).filter(isChecked).map(getImage);
function isChecked(value) {
return selected[value].checked;
}
function getImage(value) {
return selected[value].item;
}
}
} // end of batchDeleteService
})(); // end of IIFE

View File

@ -65,18 +65,15 @@
});
it('pass the image to the deleteImageService', function() {
spyOn(deleteImageService, 'perform').and.callThrough();
var selected = {
image1: {checked: true, item: {name: 'image1', id: '1'}},
image2: {checked: true, item: {name: 'image2', id: '2'}}
};
spyOn(deleteImageService, 'perform').and.callThrough();
var selected = [
{id: '1', name: 'image1'},
{id: '2', name: 'image2'}
];
service.perform(selected);
expect(deleteImageService.perform).toHaveBeenCalledWith(
[{id: '1', name: 'image1'}, {id: '2', name: 'image2'}]
);
expect(deleteImageService.perform).toHaveBeenCalledWith(selected);
});
});

View File

@ -0,0 +1,10 @@
---
fixes:
- Several fixes have been made to the hzTable controller. The list below
outline these changes. See inline documentation for usage details.
- Properties are now bound to the controller instead of the scope.
- Emit the `hzTable:clearSelected` event to clear table row selections.
- The property `selections` tracks the checkbox selection state of each row.
- The property `selected` is now a list of selected rows.
- The property `numSelected` has been removed, use `selected.length` instead.
- The `select` method has been renamed to to `toggleSelect`.