Aurelia-Bootstrap-Select
Introduction
An Aurelia Custom Element for the 3rd party addon Bootstrap-Select
Demo page
https://ghiscoding.github.io/Aurelia-Bootstrap-Plugins/#/aurelia/bootstrap-plugins/bootstrap-select
Screenshots
Screenshots from the demo app
Usage
A quick example of the code in action.
Note: We use the collection.bind
attribute to pass the collection of all select options.
Selected-Value vs Selected-Item
For conveniencies, we provide 2 bindable attributes (both are two-way
binding). The first selected-value
provides a way to pull the index(es) or (option value), while the second binding selected-item
is giving us the item(s) or most commonly the object(s) selected.
Note: in a collection of strings only, these 2 bindable attributes would have the exact same output and so there isn't much benefit to use both in that particular case.
Example:
Given this collection of objects
let myCollection = id: 1 option: 'Ketchup' company: 'Heinz' id: 2 option: 'Mustard' company: 'French\'s' ;
if the 2nd option is selected, the ouput would be:
selected-item // output --> { id: 2, option: 'Mustard', company: 'French\'s' }selected-value // output --> 2
Use it in the View
Value: ${condimentValue} Item: ${condimentItem | stringify}
changed
bindable event
Use it in the ViewModel with the @bindable condimentItem; @bindable condimentValue; { // output --> { id: 2, option: 'Mustard', company: 'French\'s' } console; } { // output --> 2 console }
How to use it with a Complex Object?
As per @Mobe91 comment, here's an example on how to use it with a complex object.
View
ViewModel
@autoinject bindingEngine: BindingEngine; allCampingStuff = ...; // some collection condimentSelection = selectedCondimentItem: null selectedCondimentValue: null ; selectedCondimentItemSubscription: Subscription; { thisbindingEngine = bindingEngine; } { let observer = thisbindingEngine; thisselectedCondimentItemSubscription= observer; } { thisbusinessesSubscription; } { // handle value change }
Available Options
Every options of Bootstrap Select
can be called through picker-options.bind=""
. For the complete list, please visit the official site Bootstrap Select - Options.
NOTE:
The picker options can also be defined globally through main.js
via a config.options
configuration, see Global Options. To know which Global Options are available take a look at the Global Options file
Examples
from the View
or from the View and ViewModel
pickerOptions = actionsBox: true dropupAuto: true ;
Mapping Data Structure
A default mapping data structure is used by the tool to apply certain styling or do certain action simply by reading a property pulled from the collection (for example, a property disabled
in the collection can be used to disabled an option from the select). These mapping were created mainly for all the options that are available only as data-zzz
(for examle data-subtext
) that are defined in Bootstrap-Select Examples. The list of the mapping is the following
mappingDataStructure: class: 'class' content: 'content' disabled: 'disabled' divider: 'divider' groupLabel: 'group' // used by optgroup groupDisabled: 'disabled' // used by optgroup icon: 'icon' maxOptions: 'maxOptions' // used by optgroup option: 'option' subtext: 'subtext' style: 'style' title: 'title' tokens: 'tokens'
Example
Let say we want to use subtext that is referenced in the collection has company
, in that case we will want to rename the mapping from subtext
to company
(as shown in the example below).
from the View, use the data-mapping-structure
attribute
in the ViewModel
// redefined the subtext mapping as companylet newMapping = subtext: 'company'; // Given this collection of objectslet myCollection = id: 1 option: 'Ketchup' company: 'Heinz' id: 2 option: 'Mustard' company: 'French\'s' ;
NOTE:
The mapping data structure can also be defined globally through main.js
via a config.extra
configuration, see Global Options
Available Methods/Functions
Again every single methods which comes with Bootstrap Select
are available. For the complete list, please visit the official site Bootstrap Select - Functions.
To have access to the methods/functions, you will need to expose the element itself through element.bind
that will then expose the methods (also note that doing so will also give you access to events
, options
and methods
).
Example
View (exposing the element)
ViewModel (calling the method)
@bindable picker; { thispickermethods; }
Extra Methods/Functions
To provide more functionality, we added extra methods that are also exposed the same way as mentioned in previous section Available Methods. The list of extra methods is the following:
disableOptgroupByIndex(index, isDisable = true)
disableOptgroupByLabel(label, isDisable = true)
Example
ViewModel (calling the method)
@bindable picker; { // to disable the optgroup 'Breads', we can call thispickermethods; }
Available Events
Every events of Bootstrap Select
are, as no surprises, available as well. For the complete list, please visit the official site Bootstrap Select - Events.
To have access to the events
, you will need to expose the element itself through element.bind
to expose the methods (also note that doing so will also give you access to events
, options
and methods
).
Note
The events are called with the syntax of onEvent
which differs from the original syntax. Example, for the dp.change
, we would use the onChange
event.
Example
View (exposing the element)
ViewModel (calling the onEvent trigger)
{ thispickerevents console; thispickerevents console; thispickerevents console; thispickerevents console; thispickerevents console; thispickerevents console; thispickerevents console; thispickerevents console; }
Disabled
There is multiple disabled
options available. You can disable any of the following:
- option
- by a mapping property in your collection (refer to mapping data structure)
- optgroup
- element (the custom element itself)
- by adding
disabled
directly on the element
- by adding
Multiple (select)
To make the Bootstrap Select
be a multi-select, simply add the multiple="true"
(or just multiple
) attribute to the element.
on View
Note: The attribute is used as a boolean attribute, so passing false
like multiple="false"
will make the select act as a regular single select.
Object-Key (attribute)
When using a collection a objects, the tool will use an attribute called object-key
(by default is set to id
) to know which property of the object to do comparison
Example:
Given this collection of objects
let myCollection = id: 1 option: 'Ketchup' company: 'Heinz' id: 2 option: 'Mustard' company: 'French\'s' ;
on View
Optgroup
To have optgroup in your select list, just use the attribute has-optgroup="true"
. The optgroup will use group
as the default mapping (if you want to change it, refer to Mapping Data Structure by changing the groupLabel
property)
Example:
Given this collection of objects, with a group
property.
let myCollection = id: 1 option: 'Ketchup' group: 'Condiments' id: 2 option: 'Mustard' group: 'Condiments' id: 10 option: 'Steam' group: 'Breads' id: 12 option: 'Toasted' group: 'Breads' ;
in View, it will automatically use the group
property
Note The attribute is used as a boolean attribute, so passing false
as has-optgroup="false"
will not show the optgroup.
Installation
You can run the examples or build your own by doing the following.
Aurelia-CLI / Webpack
npm install --save aurelia-bootstrap-select
Aurelia-CLI
For CLI
you will need to add (bootstrap-select
and aurelia-bootstrap-select
) to your aurelia.json
file. The exported class is abp-select
.
"name": "bootstrap-select" "main": "dist/js/bootstrap-select.js" "path": "../node_modules/bootstrap-select" "resources": "dist/css/bootstrap-select.min.css" "name": "aurelia-bootstrap-select" "main": "index" "path": "../node_modules/aurelia-bootstrap-select/dist/amd" "resources": "**/*.{css,html}"
index.html
Bootstrap 4
An extra custom CSS file was added to address the Bootstrap 4 changes (until Bootstrap-Select
comes out with version that supports it). If you followed the instruction earlier to modify the aurelia.json
file then it should work without any modification, if it does not then make sure to have this portion (under the aurelia-bootstrap-select
package):
"resources":
Aurelia-Webpack
Bootstrap-Select
and possibly others require to have the same jQuery
accross the bundle. You will need to modify your webpack.config.babel.js
for this to work correctly.
const ENV...+ const ProvidePlugin = require('webpack/lib/ProvidePlugin')('webpack/lib/ContextReplacementPlugin')let config = generateConfig({ entry: { 'app': ['./src/main' /* this is filled by the aurelia-webpack-plugin */], 'aurelia-bootstrap': coreBundles.bootstrap, 'aurelia': coreBundles.aurelia.filter(pkg => coreBundles.bootstrap.indexOf(pkg) === -1) }, output: { path: outDir },+ plugins: [+ new ProvidePlugin({+ $: "jquery",+ jQuery: "jquery",+ 'window.jQuery': 'jquery',+ 'window.Tether': 'tether',+ Tether: 'tether'+ })+ ],+ resolve: {+ alias: {+ // Force all modules to use the same jquery version.+ 'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')+ }+ }},
Aurelia (main.js)
Make the plugin available globally in your main.js
file. Please note the exported class is abp-select
For WebPack only (main.js)
;
Bootstrap 4 support
An extra custom CSS file was added to address the changes (until Bootstrap-Select
comes out with version that supports it, open BS4 issue #1135), you can import this custom CSS file via:
;
CLI/WebPack (main.js)
{ aureliause ; aureliastart;}
Note on aurelia-webpack-plugin 2.0
If you started using the new aurelia-webpack-plugin
version 2.0
, which is currently in RC Pre-Release and is already packaged in some of the Aurelia Skeletons (not all). You will have to use the PLATFORM.ModuleName
wrapper. The previous code becomes:
aureliause;
Global Options
You can change any of the global options directly in the main.js
through a config
as shown below:
{ aureliause ; aureliastart;}
or with aurelia-webpack-plugin 2.0
:
{ aureliause; aureliause; aureliastart;}
To know which Global Options are available take a look at the Global Options file
License
Contributions/Comments
Contributions are welcome. This plugin was created to help the community (and myself), if you wish to suggest something and/or want to make a PR (Pull Request), please feel free to do so.
Use it, like it?
You like and use an Aurelia-Bootstrap-Plugins
, please click on the ⭐️ and spread the word.