mikit-framework
Version:
A web framework for professional developers and designers alike.
181 lines (146 loc) • 5.7 kB
JavaScript
/**
* @library Mikit Collapse
* @author Mikit
* @license MIT
*/
(function (Mikit) {
Mikit.Collapse = function (element, options) {
this.namespace = 'collapse';
this.defaults = {
target: null,
toggle: true,
active: false, // string (hash = tab id selector)
toggleClass: 'mi-collapse-toggle',
boxClass: 'mi-collapse-box',
callbacks: ['open', 'opened', 'close', 'closed'],
// private
hashes: [],
currentHash: false,
currentItem: false
};
// Parent Constructor
Mikit.apply(this, arguments);
// Initialization
this.start();
};
// Functionality
Mikit.Collapse.prototype = {
start: function () {
// items
this.$items = this.getItems();
this.$items.each($.proxy(this.loadItems, this));
// boxes
this.$boxes = this.getBoxes();
// active
this.setActiveItem();
},
getItems: function () {
return this.$element.find('.' + this.opts.toggleClass);
},
getBoxes: function () {
return this.$element.find('.' + this.opts.boxClass);
},
loadItems: function (i, el) {
var item = this.getItem(el);
// set item identificator
item.$el.attr('rel', item.hash);
// active
if (!$(item.hash).hasClass('mi-hide')) {
this.opts.currentItem = item;
this.opts.active = item.hash;
item.$el.addClass('mi-active');
}
// event
item.$el.on('click.collapse', $.proxy(this.toggle, this));
},
setActiveItem: function () {
if (this.opts.active !== false) {
this.opts.currentItem = this.getItemBy(this.opts.active);
this.opts.active = this.opts.currentItem.hash;
}
if (this.opts.currentItem !== false) {
this.addActive(this.opts.currentItem);
this.opts.currentItem.$box.removeClass('mi-hide');
}
},
addActive: function (item) {
item.$box.removeClass('mi-hide').addClass('mi-open');
item.$el.addClass('mi-active');
if (item.$caret !== false) item.$caret.removeClass('mi-down').addClass('mi-up');
if (item.$parent !== false) item.$parent.addClass('mi-active');
this.opts.currentItem = item;
},
removeActive: function (item) {
item.$box.removeClass('mi-open');
item.$el.removeClass('mi-active');
if (item.$caret !== false) item.$caret.addClass('mi-down').removeClass('mi-up');
if (item.$parent !== false) item.$parent.removeClass('mi-active');
this.opts.currentItem = false;
},
toggle: function (e) {
if (e) e.preventDefault();
var target = $(e.target).closest('.' + this.opts.toggleClass).get(0) || e.target;
var item = this.getItem(target);
if (this.isOpened(item.hash)) this.close(item.hash);
else this.open(e)
},
openAll: function () {
this.$items.addClass('mi-active');
this.$boxes.addClass('mi-open').removeClass('mi-hide');
},
open: function (e, push) {
if (typeof e === 'undefined') return;
if (typeof e === 'object') e.preventDefault();
var target = $(e.target).closest('.' + this.opts.toggleClass).get(0) || e.target;
var item = (typeof e === 'object') ? this.getItem(target) : this.getItemBy(e);
if (item.$box.hasClass('mi-open')) {
return;
}
if (this.opts.toggle) this.closeAll();
this.callback('open', item);
this.addActive(item);
item.$box.animation('slideDown', $.proxy(this.onOpened, this));
},
onOpened: function () {
this.callback('opened', this.opts.currentItem);
},
closeAll: function () {
this.$items.removeClass('mi-active').closest('li').removeClass('mi-active');
this.$boxes.removeClass('mi-open').addClass('mi-hide');
},
close: function (num) {
var item = this.getItemBy(num);
this.callback('close', item);
this.opts.currentItem = item;
item.$box.animation('slideUp', $.proxy(this.onClosed, this));
},
onClosed: function () {
var item = this.opts.currentItem;
this.removeActive(item);
this.callback('closed', item);
},
isOpened: function (hash) {
return $(hash).hasClass('mi-open');
},
getItem: function (element) {
var item = {};
item.$el = $(element);
item.hash = item.$el.attr('href');
item.$box = $(item.hash);
var $parent = item.$el.parent();
item.$parent = ($parent[0].tagName === 'LI') ? $parent : false;
var $caret = item.$el.find('.mi-caret');
item.$caret = ($caret.length !== 0) ? $caret : false;
return item;
},
getItemBy: function (num) {
var element = (typeof num === 'number') ? this.$items.eq(num - 1) : this.$element.find('[rel="' + num + '"]');
return this.getItem(element);
}
};
// Inheritance
Mikit.Collapse.inherits(Mikit);
// Plugin
Mikit.Plugin.create('Collapse');
Mikit.Plugin.autoload('Collapse');
}(Mikit));