Document multi-select-list directive

This commit is contained in:
Joe Fiorini 2015-03-18 11:22:05 -04:00
parent 9fd0184131
commit 4122be0211
11 changed files with 331 additions and 12 deletions

View File

@ -1 +1 @@
import 'tower/debug';
import 'tower/shared/multi-select-list/main.js';

View File

@ -8,7 +8,7 @@
*/
/**
* @ngdoc function
* @name forms.function:Organizations
* @name forms.function:CustomInventory
* @description This form is for adding/editing an organization
*/

View File

@ -3,7 +3,7 @@
*/
/**
* @ngdoc function
* @name helpers.function:Schedules
* @name helpers.function:ConfigureTower
* @description
* Schedules Helper
*

View File

@ -3,7 +3,7 @@
*/
/**
* @ngdoc function
* @name helpers.function:Schedules
* @name helpers.function:CustomInventory
* @description
* Schedules Helper
*

View File

@ -3,7 +3,7 @@
*/
/**
* @ngdoc function
* @name helpers.function:Schedules
* @name helpers.function:Survey
* @description
* Schedules Helper
*

View File

@ -1,3 +1,12 @@
/**
* @ngdoc object
* @name multiSelectList.controller:multiSelectList
*
* @description
*
* `multiSelectList` controller provides the API for the {@link multiSelectList.directive:multiSelectList `multiSelectList`} directive. The controller contains methods for selecting/deselecting items, controlling the extended selection, registering items to be selectable and emitting an event on the directive's `$scope`.
*
*/
export default ['$scope',
function ($scope) {
$scope.items = [];
@ -7,10 +16,11 @@ export default ['$scope',
deselectedItems: []
};
// Makes $scope.selection.length an alias for $scope.selectedItems.length
Object.defineProperty($scope.selection,
'length',
{ get: function() {
return this.items.length;
return this.selectedItems.length;
}
});
@ -26,15 +36,41 @@ export default ['$scope',
_items.pluck('value').difference($scope.selection.selectedItems)
.value();
/**
*
* @ngdoc event
* @name multiSelectList.selectionChanged
* @eventOf multiSelectList.directive:multiSelectList
*
*/
$scope.$emit('multiSelectList.selectionChanged', $scope.selection);
}
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#registerItem
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Prepares an object to be tracked in the select list. Returns the
* decorated item created by
* {@link multiSelectList.controller:multiSelectList#decorateItem `decorateItem`}
*/
this.registerItem = function(item) {
var decoratedItem = this.decorateItem(item);
$scope.items = $scope.items.concat(decoratedItem);
return decoratedItem;
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#deregisterItem
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Removes an item from the list; called if the item is removed from the display
* so that it is no longer tracked as a selectable item.
*/
this.deregisterItem = function(leavingItem) {
$scope.items = $scope.items.filter(function(item) {
return leavingItem !== item;
@ -42,6 +78,18 @@ export default ['$scope',
rebuildSelections();
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#decorateItem
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
*
* This decorates an item with an object that has an `isSelected` property.
* This value is used to determine the lists of selected and non-selected
* items to emit with the `multiSelectList.selectionChanged`
* event.
*/
this.decorateItem = function(item) {
return {
isSelected: false,
@ -49,12 +97,31 @@ export default ['$scope',
};
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#selectAll
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Marks all items in the list as selected.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*/
this.selectAll = function() {
$scope.items.forEach(function(item) {
item.isSelected = true;
});
rebuildSelections();
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#deselectAll
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Marks all items in the list as not selected.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*/
this.deselectAll = function() {
$scope.items.forEach(function(item) {
item.isSelected = false;
@ -64,19 +131,59 @@ export default ['$scope',
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#deselectAllExtended
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Disables extended selection.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*/
this.deselectAllExtended = function(extendedLength) {
$scope.selection.isExtended = false;
rebuildSelections();
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#selectAllExtended
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Enables extended selection.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*/
this.selectAllExtended = function(extendedLength) {
$scope.selection.isExtended = true;
rebuildSelections();
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#selectItem
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Marks an item as selected.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*
*/
this.selectItem = function(item) {
item.isSelected = true;
rebuildSelections();
};
/**
* @ngdoc
* @name multiSelectList.controller:multiSelectList#deregisterItem
* @methodOf multiSelectList.controller:multiSelectList
*
* @description
* Marks an item as not selected.
* Triggers {@link multiSelectList.selectionChanged `multiSelectList.selectionChanged`}
*
*/
this.deselectItem = function(item) {
item.isSelected = false;
rebuildSelections();

View File

@ -1,8 +1,75 @@
/**
* @ngdoc overview
* @name multiSelectList
* @scope
* @description Does some stuff
*
* @ngdoc directive
* @name multiSelectList.directive:multiSelectList
* @description
* The `multiSelectList` directive works in conjunction with the
* `selectListItem` and (optionally) the `selectAll` directives to
* render checkboxes with list items and tracking the selected state
* of each item. The `selectListItem` directive renders a checkbox,
* and the `multiSelectList` directive tracks the selected state
* of list items. The `selectAll` directive renders a checkbox that
* will select/deselect all items in the list.
*
*
* This directive exposes a special object on its local scope called
* `selection` that is used to access the current selection state.
* The following properties on `selection` are available:
*
* | Property | Type | Details |
* |-------------------|-----------------|-------------------------------------------------------------|
* | `selectedItems` | {@type array} | The items that are currently selected |
* | `deselectedItem` | {@type array} | The items that are currently _not_ selected |
* | `isExtended` | {@type boolean} | Indicates that the user has requested an extended selection |
* | `length` | {@type number} | The length of the selected items array |
*
* Use the `multi-select-list` directive to indicate that you want
* to allow users to select items in a list. To display a checkbox
* next to each item, use the {@link multiSelectList.directive:selectListItem `select-list-item`} directive.
*
* # Rendering a basic multi-select list
*
* @example
*
* This example creates a list of names and then
* uses `multiSelectList` to make the names
* selectable:
*
<example module="multiSelectList">
<file name="index.html">
<div ng-init="names =
[ { name: 'blah'
},
{ name: 'diddy'
},
{ name: 'doo'
},
{ name: 'dah'
},
{ name: 'blah'
}
]">
<ul multi-select-list>
<li ng-repeat="item in names">
<select-list-item item="item"></select-list-item>
{{item.name}}
</li>
</ul>
</div>
</file>
</example>
*
*/
import controller from './multi-select-list.controller';
export default
[ function() {
return {
[ function() {
return {
restrict: 'A',
scope: {
},

View File

@ -1,3 +1,122 @@
/**
* @ngdoc directive
* @name multiSelectList.directive:selectAll
* @scope
* @restrict E
*
* @param {string} label The text that will appear next to the checkbox
* @param {number} itemsLength The number of displayed items in the list
* @param {number} extendedItemsLength The total number of items in the list used for extended mode (see below)
* @param {string_expression} extendedLabel A custom label to display when prompting the user to extend the selection; this is an expression so strings must be in single quotes ('), but you can use scope varibles here to display the count of items with the `extendedItemsLength` property
* @param {boolean_expression} selectionsEmpty An expression that evaluates to a truthy value used to disable
* the select all checkbox when the displayed list is empty
*
* @description
*
* Use the `select-all` directive as a child of a `multi-select-list`
* to present the user with a checkbox that, when checked, checks all
* `select-list-item` children, and when unchecked it unchecks them.
*
* <example module="multiSelectList">
<file name="index.html">
<div ng-init="names =
[ { name: 'blah'
},
{ name: 'diddy'
},
{ name: 'doo'
},
{ name: 'dah'
},
{ name: 'blah'
}
]">
<ul multi-select-list>
<li>
<select-all label="Select All"></select-all>
</li>
<li ng-repeat="item in names">
<select-list-item item="item"></select-list-item>
{{item.name}}
</li>
</ul>
</div>
</file>
* </example>
*
* ## Extended Selections
*
* In some cases the list items you are displaying are only a subset of
* a larger list (eg. using pagination or infinite scroll to seperate
* items). In these cases, when a user checks "select all", it may be
* useful to give them the option to also select all the remaining
* items in the list.
*
* This behavior is controlled by the `extendedItemsLength` property
* of this directive. Set it to the total length of items in the list.
* For example, if you have a list of 100 items, displayed 10 per page,
* then `itemsLength` would be 10 and `extendedItemsLength` would be 100.
* When the user checks "select all" in the above example, it will show
* a button prompting them to "Select all 100 items". When the user selects
* this option, the `select-all` directive tells the `multiSelectList`
* controller that the selection is "extended" to all the items in the list.
* Listeners to the `multiSelectList.selectionChanged` event can then use this
* flag to respond differently when all items are selected.
*
*
* <example module="extendedSelectionExample">
<file name="app.js">
angular.module('extendedSelectionExample', ['multiSelectList'])
.controller('namesController', ['$scope', function($scope) {
var cleanup = $scope.$on('multiSelectList.selectionChanged', function(e, selection) {
$scope.isSelectionExtended = selection.isExtended;
});
$scope.$on('$destroy', cleanup);
$scope.allNames =
[ { name: 'John'
},
{ name: 'Jared'
},
{ name: 'Joe'
},
{ name: 'James'
},
{ name: 'Matt'
},
{ name: 'Luke'
},
{ name: 'Chris'
}
];
$scope.firstPageOfNames =
$scope.allNames.slice(0,3);
}]);
</file>
<file name="index.html">
<div ng-controller="namesController">
<p ng-if="isSelectionExtended">Extended Selection</p>
<ul multi-select-list>
<li>
<select-all
label="Select All"
selections-empty="selectedItems.length === 0"
extended-items-length="allNames.length"
items-length="firstPageOfNames.length"></select-all>
</li>
<li ng-repeat="item in firstPageOfNames">
<select-list-item item="item"></select-list-item>
{{item.name}}
</li>
</ul>
</div>
</file>
*</example>
*/
// TODO: Extract to its own helper
// Example:
// template('shared/multi-select-list/select-all')
@ -17,14 +136,14 @@ export default
label: '@',
itemsLength: '=',
extendedItemsLength: '=',
isSelectionExtended: '=',
extendedLabel: '&',
isSelectionEmpty: '=selectionsEmpty'
},
templateUrl: template('shared/multi-select-list/select-all'),
link: function(scope, element, attrs, controller) {
scope.label = scope.label || 'All';
scope.selectExtendedLabel = scope.extendedLabel || 'Select all ' + scope.extendedItemsLength + ' items';
scope.selectExtendedLabel = scope.extendedLabel() || 'Select all ' + scope.extendedItemsLength + ' items';
scope.deselectExtendedLabel = scope.deselectExtendedLabel || 'Deselect extra items';
scope.doSelectAll = function(e) {
@ -36,6 +155,12 @@ export default
}
} else {
controller.deselectAll();
if (scope.isSelectionExtended) {
scope.deselectAllExtended();
}
scope.showExtendedMessage = false;
}
};
@ -51,10 +176,12 @@ export default
scope.selectAllExtended = function() {
controller.selectAllExtended(scope.extendedItemsLength);
scope.isSelectionExtended = true;
};
scope.deselectAllExtended = function() {
controller.deselectAllExtended(scope.extendedItemsLength);
scope.isSelectionExtended = false;
};
}

View File

@ -13,6 +13,6 @@
</button>
<button
ng-click="deselectAllExtended()"
ng-if="isSelectionExtended">
ng-if="isSelectionExtended && showExtendedMessage">
{{deselectExtendedLabel}}
</button>

View File

@ -1,3 +1,21 @@
/**
* @ngdoc directive
* @name multiSelectList.directive:selectListItem
* @restrict E
* @scope
* @description
*
The `select-list-item` directive renders a checkbox for tracking
the state of a given item in a list. When the user checks the
checkbox it tells the `multi-select-list` controller to select
the item; when the user unchecks the checkbox it tells the controller
to deselect the item.
@example
For examples of using this directive, see {@link multiSelectList.directive:multiSelectList multiSelectList}.
*/
export default
[ function() {
return {

View File

@ -3,7 +3,7 @@
*/
/**
* @ngdoc function
* @name widgets.function:DashboardJobs
* @name widgets.function:PortalJobs
* @description
*
*/