An elegant and efficient multi select for AngularJS apps.
IVH Multi Select aims to provide a robust multiselect component while keeping a careful eye on performance and minizing watch counts. While collapsed IVH Multi Select will create just ~10 watchers, and only ~40 while expanded.
Note that IVH Multi Select assumes Bootstrap 3 styles.
Install with bower:
bower install --save angular-ivh-multi-select
Note: You may optionally include angular-ivh-auto-focus as well to automatically focus multi select input controls. See the auto focus section below for detail.
Add this module as a dependency to your app:
angular.module('myApp', ['ivh.multiSelect']);
At a minimum you must provide a collection of items to select from:
<div ivh-multi-select
ivh-multi-select-items="myCollection">
Choose some items!
</div>
IVH Multi Select will display a button that when clicked shows a menu of items to select complete with checkboxes and pagination if availabe.
We're using the selection-model component to manage selections internally.
You can configure this directive's behavior by working with the
selectionModelOptionsProvider. Inline selection-model-*
attributes
will also be forwarded to the underlying selection model:
<div ivh-multi-select
ivh-multi-select-items="myCollection"
selection-model-selected-attribute="'customSelectedAttr'">
Choose some items!
</div>
This includes selection-model-on-change
with the notable exception that when
this expression is evaluated IVH Multi Select will provide a scope variable,
item
, which will be a reference to the collection item whose selected status
has changed.
Labels can be pulled from collection item properties or created with a custom expression:
<div ivh-multi-select
ivh-multi-select-items="myCollection"
ivh-multi-select-label-attribute="'name'">
Use "name" attribute for item labels
</div>
<!--
Note: Use `item` to reference the current item in your label expression.
-->
<div ivh-multi-select
ivh-multi-select-items="myCollection"
ivh-multi-select-label-expression="'{{item.firstName}} {{item.lastName}}'">
Use an angular expression for item labels
</div>
In keeping with our focus on performance, IVH Multi Select will paginate your lists if you happen to have the ivh.pager module included as a dependency (v0.3.0 or greater).
This is not a hard dependency, if you do not include IVH Pager your lists will be displayed in full.
We're using selection-model internally to manage selections. As a convenience we
provide a filter, ivhMultiSelectCollect
, to help convert these to arrays of
IDs if that is more in keeping with your use case. Note that this behavior is
only supported when using the multi-additive
selection mode (the default).
<!--
The array demo.selectedIds will be updated whenever an item is clicked on or
the user hits the "All" or "None" buttons.
-->
<div ivh-multi-select
ivh-multi-select-items="demo.items"
selection-model-on-change="demo.selectedIds | ivhMultiSelectCollect:item">
</div>
<!--
You may also provide an id attribute and selected attribute if needed.
-->
<div ivh-multi-select
ivh-multi-select-items="demo.items"
selection-model-on-change="demo.selectedIds | ivhMultiSelectCollect:item:'id':'selected'">
</div>
For times when it would be too expensive to keep the entire list of available options on the client side we provide a second directive which allows you to provide an item getter function.
<div ivh-multi-select-async
ivh-multi-select-fetcher="fetcher"
ivh-multi-select-selected-items="mySelection"
selection-model-mode="\'multi-additive\'">
Blargus
</div>
Note the async in ivh-multi-select-async
, this is in fact a separate
directive from ivh-multi-select
but supports a nearly identical set of
attributes with the following exceptions:
- The values assigned to
ivh-multi-select-fetcher
is required and expected to be a function (signiture detailed below). - The value assigned to
ivh-multi-select-id-attribute
will be used to compare newly fetched items with those in your selected items array as they are paged in and out. This is optional and defaults to'id'
. ivh-multi-select-items
is ignored... getting our items from the server is kinda the point.- You may use the
ivh-multi-select-selected-items
attribute to provide an array of selected items. This will be kept up to date with user driven changes as items are selected and deselected. Note that only'single'
and'multi-additive'
(the default) selection modes are supported. Order and item reference preservation is not guarenteed.
The function we'll use to fetch pages of items.
This should accept an options object with the following properties:
- filter: A string, whatever the user has entered in the filter box
- page: The zero-based page number we're requesting for paginated results.
- pageSize: The number of items we expect per page
The function should return an object, or promise which resolves to shuch an object, with the following properties:
- items: A page of collection items, if more than one page was returned only
the first
pageSize
will be displayed (assuming paging is enabled). - page: [Optional] The zero-based page number corresponding to the returned
results. If ommitted and paging is enabled we will assume
page
from the request options. - pageSize: The size of a page of results, if omitted we will assume
pageSize
from the request options. totalCount
: The total (unpaged) result set count
Include the IVH Auto Focus module in your application to enable auto-focusing multi select inputs.
Install with bower:
bower install --save angular-ivh-auto-focus
Include in your application
angular.module('myApp', [
'ivh.multiSelect',
'ivh.autoFocus'
]);
Enjoy auto focusing multi select inputs 😄.
Use npm test
to run the full suite of linting, style checks, and unit tests.
Or, run each individually:
- Use
grunt jshint
for linting - Use
grunt jscs
for coding style checks - Use
grunt jasmine
to unit tests
For ease of development the grunt watch
task will run each of the above as
needed when you make changes to source files.
- 2015-10-26 v0.8.0 (sync) Filter on calculated label
- 2015-10-26 v0.6.0 Add support for server side paging
- 2015-10-26 v0.5.0 Add custom label expressions
- 2015-10-20 v0.2.0 Forward selection-model-on-change
- 2015-10-08 v0.2.0 Forward options to selection model
- 2015-10-07 v0.1.0 Initial release
MIT