Angular Flickity
An AngularJS module that exposes a directive and service to create and control multiple
Flickity instances.
:tv: Demos and Examples
Flickity by Metafizzy
Comments and pull requests welcome!
Contents
Installation
Dependencies
NPM
npm install flickity --save
npm install flickity-imagesloaded --save
npm install flickity-bg-lazyload --save
npm install angular-flickity --save
Bower
bower install flickity --save
bower install flickity-imagesloaded --save
bower install flickity-bg-lazyload --save
bower install angular-flickity --save
Include the scripts
Include Flickity
(and flickity-imagesloaded
/flickity-bg-lazyload
if needed):
Webpack
import Flickity from 'flickity';
import 'flickity-imagesloaded';
import 'flickity-bg-lazyload';
import 'angular-flickity';
angular.module('myProject', ['bc.Flickity']);
Manually
<!-- Include the module -->
<script src="path/to/lib/flickity.js"></script>
<script src="path/to/lib/flickity-imagesloaded.js"></script>
<script src="path/to/lib/flickity-bg-lazyload.js"></script>
<script src="path/to/angular-flickity/dist/angular-flickity.js"></script>
Note when using Flickity via bower
In my experience, including Flickity through bower often doesn't work out of the box. By default,
bower pulls in the unpackaged files as the Flickity bower.json
specifies rather than packaged
files which seems to be what we need.
The trick is to specify which files bower should use in your own bower.json
.
{
"name": "myProject",
"overrides": {
"flickity": {
"main": [
"dist/flickity.pkgd.js",
"dist/flickity.min.css"
]
}
}
}
Usage
Include bc.Flickity
as a dependency in your project.
angular.module('YourModule', ['bc.Flickity']);
Use the directive on the parent element containing your slides.
<div
bc-flickity="{{ vm.flickityOptions }}"
id="myCustomId"
>
<figure class="demo__slide" data-ng-repeat="slide in vm.slides">
<img data-ng-src="{{ slide }}" alt="" />
</figure>
</div>
<button
bc-flickity-previous
bc-flickity-id="myCustomId"
>Previous</button>
<button
bc-flickity-next
bc-flickity-id="myCustomId"
>Next</button>
Options
This module supports all options for Flickity version 2.0.5
. A full list of options can be
found here: Flickity Options.
Simply pass in an object containing any options you'd like to set.
angular.module('myModule')
.controller('MyController', ($scope) => {
$scope.myCustomOptions = {
cellSelector: '.mySlideClassName',
initialIndex: 3,
prevNextButtons: false,
};
})
;
export class MyController {
constructor() {
this.flickityOptions = {
cellSelector: '.mySlideClassName',
initialIndex: 3,
prevNextButtons: false,
};
}
}
my.template.html
:
<div bc-flickity="{{ myCustomOptions }}">
<div class="mySlideClassName"></div>
<div class="mySlideClassName"></div>
...
</div>
ID
The FlickityService
uses IDs to manage multiple instances of the directive. An ID is automatically
created and assigned at initialization. However, at times you may need to access your instances in a
programmatic way. There are two ways for IDs to be defined by your module.
Element ID
If the element containing the bc-flickity
directive has an ID attribute, the value will
be used to create the ID.
<div
bc-flickity="{{ myCustomOptions }}"
id="foo"
>
</div>
Explicitly Define
At times, you may not be able to use an element ID (or simply prefer not to). In those cases you can
pass the ID in directly as a string using bc-flickity-id
.
<div
bc-flickity="{{ myCustomOptions }}"
bc-flickity-id="bar"
>
</div>
Global Defaults
This module exposes FlickityConfigProvider
which can be used to set project-wide defaults for
Flickity. Simply set any options here using options that match the original Flickity
options.
export function config(FlickityConfigProvider) {
'ngInject';
FlickityConfigProvider.prevNextButtons = true;
FlickityConfigProvider.setGallerySize = false;
}
angular.module('myModule')
.config((FlickityConfigProvider) => {
'ngInject';
FlickityConfigProvider.prevNextButtons = true;
FlickityConfigProvider.setGallerySize = false;
})
;
Directives
bc-flickity
The directive bc-flickity
creates the Flickity gallery.
<div bc-flickity>
</div>
You may optionally pass an options object to the directive. User defined options will override any
default options.
<div bc-flickity="{{ vm.flickityOptions }}">
</div>
Learn more about angular-flickity
options & Flickity options
documentation
bc-flickity-next
The directive bc-flickity-next
is provided to call the next()
method on a Flickity
instance.
<button bc-flickity-next>Next</button>
Multiple Instances
If you need to support multiple Flickity
instances in a single view you can specify an instance ID
that the control should be linked to.
<button
bc-flickity-next
bc-flickity-id="customId"
>Next</button>
More on setting the ID using a directive or service.
If no ID is set, the directive will assume that only one instance exists and grab the ID from the
first instance.
Looping
This directive accepts an optional parameter to control the looping. If true
and at the last cell
when clicked, Flickity will loop back to the first cell. If false
, it will do nothing when
clicked at the last cell.
<button bc-flickity-next="true">Next</button>
Disabled
When the last cell is reached, the disabled
attribute will be added to the element. The disabled
attribute will not be added if either of these conditions are met:
- The associated gallery has
wrapAround
set to true
. - The directive has
true
passed in as the optional parameter (which overrides the default
options).
bc-flickity-previous
The directive bc-flickity-previous
is provided to call the previous()
method on the Flickity
instance.
<button bc-flickity-previous>Previous</button>
Multiple Instances
If you need to support multiple Flickity
instances in a single view you can specify an instance ID
that the control should be linked to.
<button
bc-flickity-next
bc-flickity-id="customId"
>Next</button>
More on setting the ID using a directive or service.
If no ID is set, the directive will assume that only one instance exists and grab the ID from the
first instance.
Looping
This directive accepts an optional parameter to control the looping. If true
and at the first cell
when clicked, Flickity will loop around to the last cell. If false
, it will do nothing when
clicked at the first cell.
<button bc-flickity-previous="true">Previous</button>
Disabled
When at the first cell, the disabled
attribute will be added to the element. The disabled
attribute will not be added if either of these conditions are met:
- The associated gallery has
wrapAround
set to true
. - The directive has
true
passed in as the optional parameter (which overrides the default
options).
Services
While you can easily use Flickity via the directive only, most Flickity methods are accessible via
the FlickityService
.
The services here follow the order of the Flickity Documentation as closely as possible
in order to be immediately familiar. This shouldn't feel like learning another library (assuming
you are already familiar with Flickity).
:tv: Service demo
Don't be afraid to look at the source code. It isn't terribly complicated and fairly well
commented.
Initialize
create
This can be called to manually create a new Flickity
instance.
:tv: Create instance demo
FlickityService.create(element, id, options)
Parameters
element
: {Element}
- A DOM element wrapped as a jQuery object. This can be done with jqLite
(
angular.element(element)
) or jQuery ($(element)
)
id
: {String}
optional
- ID for the created
Flickity
instance. If no ID is assigned, one will be created and used
internally.
options
: {Object}
optional
- Options object for Flickity
Returns Promise
{
id: 'foo',
instance: Flickity
};
NOTE:
Anytime you are dealing with the DOM from inside a controller (:-1:) make sure to use
document.ready. This ensures that the element you are looking for actually exists. You can also
use a $timeout but I find using document.ready more accurately represents the intention.
:tv: Demo showing DOM issue and solution
angular.element($document[0]).ready(() => {
const element = angular.element(document.getElementById('demo-slider'));
FlickityService.create(element[0], element[0].id);
});
NOTE:
If you are dealing with remote data, you should wrap the .create()
call with a $timeout
.
This ensures that the data has already been assigned to scope before the slider is initialized.
:tv: Demo with remote data
$http.get('http://yourRemoteSource.com/slides.json')
.then((results) => {
$scope.slides = results.data;
const element = angular.element(document.getElementById('demo-slider'));
$timeout(() => {
FlickityService.create(element[0], element[0].id);
});
});
Selecting Cells
select
Move directly to a specific slide.
:tv: Selecting a cell demo
FlickityService.select(id, index, isWrapped, isInstant)
id
: {String}
- A string representing the ID of the
Flickity
instance to move.
index
: {Number}
isWrapped
: {Bool}
optional
- Default:
false
- If
true
and previous
is called when on the first slide, the slider will wrap around to show
the last slide. - If
true
and next
is called when on the last slide, the slider will wrap back to show slide 1.
isInstant
: {Bool}
optional
- Default:
false
- If
true
the slide will change instantly with no animation.
Returns Promise
previous
Move to the previous slide.
FlickityService.previous(id, isWrapped, isInstant)
Parameters
id
: {String}
- A string representing the ID of the
Flickity
instance to move.
isWrapped
: {Bool}
optional
- Default:
false
- If
true
and previous
is called when on the first slide, the slider will wrap around to show
the last slide. - If
false
and previous
is called when on the first slide, the slider will do nothing.
isInstant
: {Bool}
optional
- Default:
false
- If
true
the slide will change instantly with no animation.
Returns Promise
next
Move to the next slide.
FlickityService.next(id, isWrapped, isInstant)
Parameters
id
: {String}
- A string representing the ID of the
Flickity
instance to move.
isWrapped
: {Bool}
optional
- Default:
false
- If
true
and next
is called when on the last slide, the slider will wrap back to show slide 1. - If
false
and next
is called when on the last slide, the slider will do nothing.
isInstant
: {Bool}
optional
- Default:
false
- If
true
the slide will change instantly with no animation.
Returns Promise
cellSelect
Select a slide of a cell.
FlickityService.cellSelect(id, value, isWrapped, isInstant)
Parameters
id
: {String}
- A string representing the ID of the
Flickity
instance to move.
value
: {Integer|String}
- Zero-based index OR selector string of the cell to select.
isWrapped
: {Bool}
optional
- Default:
false
- If
true
and previous
is called when on the first slide, the slider will wrap around to show
the last slide. - If
true
and next
is called when on the last slide, the slider will wrap back to show slide 1.
isInstant
: {Bool}
optional
- Default:
false
- If
true
the slide will change instantly with no animation.
Returns Promise
Sizing and Positioning
resize
Triggers Flickity to resize the gallery and re-position cells.
FlickityService.resize(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
reposition
Tell Flickity to reposition cells while retaining the current index. Useful if cell sizes change
after initialization.
FlickityService.reposition(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
Adding and Removing Cells
Note: If you are trying to add cell(s) by appending to a 'slides' array and then reinitializing
the slider, take a look at this :tv: demo
prepend
Create cells at the beginning of the gallery and prepend elements.
FlickityService.prepend(id, elements)
id
: {String}
- A string representing the ID of the
Flickity
instance.
elements
: {Object|Array|Element|NodeList}
- jQuery object, Array of Elements, Element, or NodeList
Returns Promise
append
Create cells at the end of the gallery and append elements.
FlickityService.append(id, elements)
id
: {String}
- A string representing the ID of the
Flickity
instance.
elements
: {Object|Array|Element|NodeList}
- jQuery object, Array of Elements, Element, or NodeList
Returns Promise
insert
Insert elements into the gallery and create cells at the desired index.
FlickityService.insert(id, elements, index)
id
: {String}
- A string representing the ID of the
Flickity
instance.
elements
: {Object|Array|Element|NodeList}
- jQuery object, Array of Elements, Element, or NodeList
index
: {Integer}
- Zero based integer where the new slides should be inserted.
Returns Promise
remove
Remove cells from the gallery and remove the elements from DOM.
FlickityService.remove(id, elements)
id
: {String}
- A string representing the ID of the
Flickity
instance.
elements
: {Object|Array|Element|NodeList}
- jQuery object, Array of Elements, Element, or NodeList
Returns Promise
Utilities
destroy
Destroys a Flickity
instance.
FlickityService.destroy(id)
Parameters
id
: {String}
- A string representing the ID of the
Flickity
instance to be destroyed.
Returns Promise
This is very useful when your Flickity instance is created inside a controller attached to a route.
Each time the route is hit, the route's controller calls to create a new Flickity instance. But if
that instance already exists, it will cause an error. The correct way to handle this is to destroy
the Flickity instance when the controller is being destroyed.
$scope.$on('$destroy', () => {
FlickityService.destroy(instanceId);
});
reloadCells
Re-collect all cell elements in flickity-slider
.
FlickityService.reloadCells(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
Note: If you are trying to add cell(s) by appending to a 'slides' array and then reinitializing
the slider, take a look at this :tv: demo
getCellElements
Get the elements of the cells.
FlickityService.getCellElements(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
get
Return a Flickity
instance found by ID.
FlickityService.get(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
getFirst
Return the first Flickity
instance.
FlickityService.getFirst()
Returns Promise
getByElement
Find a Flickity
instance by element or selector string.
FlickityService.getByElement(id, element)
id
: {String}
- A string representing the ID of the
Flickity
instance.
element
: {Element}
- Element or selector string representing the
Flickity
instance.
Returns Promise
Properties
selectedIndex
Get the index of the slide currently in view.
FlickityService.selectedIndex(id)
id
: {String}
- A string representing the ID of the
Flickity
instance for which you need the index.
Returns Promise
selectedIndex
: {Number}
- The index of the currently visible slide.
selectedElement
Get the currently selected cell element.
FlickityService.selectedElement(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
selectedElement
: {Element}
cells
Get all cells.
:tv: Get all cells demo
FlickityService.cells(id)
id
: {String}
- A string representing the ID of the
Flickity
instance.
Returns Promise
Events
All events trigger an associated $emit
on $rootScope
.
:tv: Events demo
Learn more in the Angular docs on $emit
.
Each $emit
event is named in this format: Flickity:[instanceId]:[eventName]
So, for example, if you had declared a custom ID of myCustomId
on bc-flickity
and wanted
to know when the settle
event occurs, you could listen for it like this:
const settle = $rootScope.$on('Flickity:myCustomId:settle', (event, data) => {
console.log('Flickity just settled!', event, data);
});
Events and Parameters
For more information on individual events, check out the Flickity Documentation on Events.
⢠eventName
⢠parameter
select
scroll
settle
dragStart
dragMove
dragEnd
pointerDown
pointerMove
pointerUp
staticClick
event
pointer
cellElement
cellIndex
lazyLoad
Event Naming Convention
eventName
=> Flickity:instanceId:eventName
Event name | $emit name |
---|
select | Flickity:instanceId:select |
scroll | Flickity:instanceId:scroll |
settle | Flickity:instanceId:settle |
dragStart | Flickity:instanceId:dragStart |
dragMove | Flickity:instanceId:dragMove |
dragEnd | Flickity:instanceId:dragEnd |
pointerDown | Flickity:instanceId:pointerDown |
pointerMove | Flickity:instanceId:pointerMove |
pointerUp | Flickity:instanceId:pointerUp |
staticClick | Flickity:instanceId:staticClick |
lazyLoad | Flickity:instanceId:lazyLoad |
Learn more about Flickity events.
Don't forget:
The $on
call should always be assigned to a variable. This allows it to be destroyed during the
$scope
cleanup.
Learn more about $destroy.
Demos
Development
npm run build
- Produces uncompressed (
.js
) and minified (.min.js
) versions of the library under the dist
folder.
npm run watch
- Watches for changes inside
/src
and calls npm run build
when changes are detected.
npm run test
npm run watch:tests
- Watch for changes and re-run tests.
About Flickity
Touch, responsive, flickable galleries.
Made by Metafizzy who make seriously awesome, stuff.