Initial commit
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
var $ = require('jquery');
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
|
||||
var DEFAULTS = {
|
||||
width: 160,
|
||||
speedIn: 150,
|
||||
speedOut: 300,
|
||||
verticalPosition: 'down',
|
||||
horizontalPosition: 'right',
|
||||
tick: 'right',
|
||||
verticalOffset: 0,
|
||||
horizontalOffset: 0
|
||||
};
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
className: 'dropdown',
|
||||
|
||||
initialize: function (options) {
|
||||
_.bindAll(this, 'open', 'hide', '_handleClick', '_keydown', '_onDocumentClick');
|
||||
|
||||
this.options = {};
|
||||
// Extend options
|
||||
_.defaults(this.options, options, DEFAULTS);
|
||||
|
||||
if (options.template) {
|
||||
this.template = options.template;
|
||||
}
|
||||
|
||||
// Bind to target
|
||||
$(options.target).on('click', this._handleClick);
|
||||
$(document).on('keydown', this._keydown);
|
||||
$(document).on('click', this._onDocumentClick);
|
||||
|
||||
this.modelView = new Backbone.Model({
|
||||
open: false
|
||||
});
|
||||
|
||||
this.modelView.on('change:open', function (model, isOpen) {
|
||||
isOpen ? this.hide() : this.open();
|
||||
}, this);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
// Render
|
||||
var $el = this.$el;
|
||||
$el
|
||||
.html(this.template && this.template(this.options))
|
||||
.css({
|
||||
width: this.options.width
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
_handleClick: function (event) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
var isOpen = this.modelView.get('open');
|
||||
this.modelView.set('open', !isOpen);
|
||||
},
|
||||
|
||||
_onDocumentClick: function (e) {
|
||||
var $el = $(e.target);
|
||||
var $target = $(this.options.target);
|
||||
var isTarget = $el.get(0) === $target.get(0);
|
||||
if (!isTarget && $el.closest('.Dropdown').length === 0) {
|
||||
this.modelView.set({open: false}, {silent: true});
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_keydown: function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
this.modelView.set('open', false);
|
||||
}
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.$el.hide();
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.$el.css({
|
||||
display: 'block',
|
||||
opacity: 1
|
||||
});
|
||||
},
|
||||
|
||||
open: function (event, target) {
|
||||
// Target
|
||||
var $target = target && $(target) || this.options.target;
|
||||
this.options.target = $target;
|
||||
|
||||
// Positionate
|
||||
var targetPos = $target[this.options.position || 'offset']();
|
||||
var targetWidth = $target.outerWidth();
|
||||
var targetHeight = $target.outerHeight();
|
||||
var elementWidth = this.$el.outerWidth();
|
||||
var elementHeight = this.$el.outerHeight();
|
||||
var verticalPosition = this.options.verticalPosition;
|
||||
var verticalOffset = this.options.verticalOffset;
|
||||
var horizontalPosition = this.options.horizontalPosition;
|
||||
var horizontalOffset = this.options.horizontalOffset;
|
||||
|
||||
this.$el.css({
|
||||
top: targetPos.top + parseInt((verticalPosition === 'up') ? (-elementHeight - 10 - verticalOffset) : (targetHeight + 10 - verticalOffset)),
|
||||
left: targetPos.left + parseInt((horizontalPosition === 'left') ? (horizontalOffset - 15) : (targetWidth - elementWidth + 15 - horizontalOffset))
|
||||
})
|
||||
.addClass(
|
||||
// Add vertical and horizontal position class
|
||||
(verticalPosition === 'up' ? 'vertical_top' : 'vertical_bottom') +
|
||||
' ' +
|
||||
(horizontalPosition === 'right' ? 'horizontal_right' : 'horizontal_left') +
|
||||
' ' +
|
||||
// Add tick class
|
||||
'tick_' + this.options.tick
|
||||
);
|
||||
|
||||
this.show();
|
||||
},
|
||||
|
||||
isOpen: function () {
|
||||
return this.modelView.get('open');
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
const target = $(this.options.target);
|
||||
this.options.target && target.off('click', this._handleClick);
|
||||
$(document).off('keydown', this._keydown);
|
||||
$(document).off('click', this._onDocumentClick);
|
||||
CoreView.prototype.clean.apply(this);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user