mirror of
https://github.com/Lissy93/md-cv-maker.git
synced 2021-05-12 19:52:19 +03:00
266 lines
8.8 KiB
JavaScript
266 lines
8.8 KiB
JavaScript
(function ($) {
|
|
|
|
// Add posibility to scroll to selected option
|
|
// usefull for select for example
|
|
$.fn.scrollTo = function(elem) {
|
|
$(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
|
|
return this;
|
|
};
|
|
|
|
$.fn.dropdown = function (options) {
|
|
var defaults = {
|
|
inDuration: 300,
|
|
outDuration: 225,
|
|
constrain_width: true, // Constrains width of dropdown to the activator
|
|
hover: false,
|
|
gutter: 0, // Spacing from edge
|
|
belowOrigin: false,
|
|
alignment: 'left',
|
|
stopPropagation: false
|
|
};
|
|
|
|
// Open dropdown.
|
|
if (options === "open") {
|
|
this.each(function() {
|
|
$(this).trigger('open');
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Close dropdown.
|
|
if (options === "close") {
|
|
this.each(function() {
|
|
$(this).trigger('close');
|
|
});
|
|
return false;
|
|
}
|
|
|
|
this.each(function(){
|
|
var origin = $(this);
|
|
var options = $.extend({}, defaults, options);
|
|
var isFocused = false;
|
|
|
|
// Dropdown menu
|
|
var activates = $("#"+ origin.attr('data-activates'));
|
|
|
|
function updateOptions() {
|
|
if (origin.data('induration') !== undefined)
|
|
options.inDuration = origin.data('induration');
|
|
if (origin.data('outduration') !== undefined)
|
|
options.outDuration = origin.data('outduration');
|
|
if (origin.data('constrainwidth') !== undefined)
|
|
options.constrain_width = origin.data('constrainwidth');
|
|
if (origin.data('hover') !== undefined)
|
|
options.hover = origin.data('hover');
|
|
if (origin.data('gutter') !== undefined)
|
|
options.gutter = origin.data('gutter');
|
|
if (origin.data('beloworigin') !== undefined)
|
|
options.belowOrigin = origin.data('beloworigin');
|
|
if (origin.data('alignment') !== undefined)
|
|
options.alignment = origin.data('alignment');
|
|
if (origin.data('stoppropagation') !== undefined)
|
|
options.stopPropagation = origin.data('stoppropagation');
|
|
}
|
|
|
|
updateOptions();
|
|
|
|
// Attach dropdown to its activator
|
|
origin.after(activates);
|
|
|
|
/*
|
|
Helper function to position and resize dropdown.
|
|
Used in hover and click handler.
|
|
*/
|
|
function placeDropdown(eventType) {
|
|
// Check for simultaneous focus and click events.
|
|
if (eventType === 'focus') {
|
|
isFocused = true;
|
|
}
|
|
|
|
// Check html data attributes
|
|
updateOptions();
|
|
|
|
// Set Dropdown state
|
|
activates.addClass('active');
|
|
origin.addClass('active');
|
|
|
|
// Constrain width
|
|
if (options.constrain_width === true) {
|
|
activates.css('width', origin.outerWidth());
|
|
|
|
} else {
|
|
activates.css('white-space', 'nowrap');
|
|
}
|
|
|
|
// Offscreen detection
|
|
var windowHeight = window.innerHeight;
|
|
var originHeight = origin.innerHeight();
|
|
var offsetLeft = origin.offset().left;
|
|
var offsetTop = origin.offset().top - $(window).scrollTop();
|
|
var currAlignment = options.alignment;
|
|
var gutterSpacing = 0;
|
|
var leftPosition = 0;
|
|
|
|
// Below Origin
|
|
var verticalOffset = 0;
|
|
if (options.belowOrigin === true) {
|
|
verticalOffset = originHeight;
|
|
}
|
|
|
|
// Check for scrolling positioned container.
|
|
var scrollYOffset = 0;
|
|
var scrollXOffset = 0;
|
|
var wrapper = origin.parent();
|
|
if (!wrapper.is('body')) {
|
|
if (wrapper[0].scrollHeight > wrapper[0].clientHeight) {
|
|
scrollYOffset = wrapper[0].scrollTop;
|
|
}
|
|
if (wrapper[0].scrollWidth > wrapper[0].clientWidth) {
|
|
scrollXOffset = wrapper[0].scrollLeft;
|
|
}
|
|
}
|
|
|
|
|
|
if (offsetLeft + activates.innerWidth() > $(window).width()) {
|
|
// Dropdown goes past screen on right, force right alignment
|
|
currAlignment = 'right';
|
|
|
|
} else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) {
|
|
// Dropdown goes past screen on left, force left alignment
|
|
currAlignment = 'left';
|
|
}
|
|
// Vertical bottom offscreen detection
|
|
if (offsetTop + activates.innerHeight() > windowHeight) {
|
|
// If going upwards still goes offscreen, just crop height of dropdown.
|
|
if (offsetTop + originHeight - activates.innerHeight() < 0) {
|
|
var adjustedHeight = windowHeight - offsetTop - verticalOffset;
|
|
activates.css('max-height', adjustedHeight);
|
|
} else {
|
|
// Flow upwards.
|
|
if (!verticalOffset) {
|
|
verticalOffset += originHeight;
|
|
}
|
|
verticalOffset -= activates.innerHeight();
|
|
}
|
|
}
|
|
|
|
// Handle edge alignment
|
|
if (currAlignment === 'left') {
|
|
gutterSpacing = options.gutter;
|
|
leftPosition = origin.position().left + gutterSpacing;
|
|
}
|
|
else if (currAlignment === 'right') {
|
|
var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth();
|
|
gutterSpacing = -options.gutter;
|
|
leftPosition = offsetRight + gutterSpacing;
|
|
}
|
|
|
|
// Position dropdown
|
|
activates.css({
|
|
position: 'absolute',
|
|
top: origin.position().top + verticalOffset + scrollYOffset,
|
|
left: leftPosition + scrollXOffset
|
|
});
|
|
|
|
|
|
// Show dropdown
|
|
activates.stop(true, true).css('opacity', 0)
|
|
.slideDown({
|
|
queue: false,
|
|
duration: options.inDuration,
|
|
easing: 'easeOutCubic',
|
|
complete: function() {
|
|
$(this).css('height', '');
|
|
}
|
|
})
|
|
.animate( {opacity: 1}, {queue: false, duration: options.inDuration, easing: 'easeOutSine'});
|
|
}
|
|
|
|
function hideDropdown() {
|
|
// Check for simultaneous focus and click events.
|
|
isFocused = false;
|
|
activates.fadeOut(options.outDuration);
|
|
activates.removeClass('active');
|
|
origin.removeClass('active');
|
|
setTimeout(function() { activates.css('max-height', ''); }, options.outDuration);
|
|
}
|
|
|
|
// Hover
|
|
if (options.hover) {
|
|
var open = false;
|
|
origin.unbind('click.' + origin.attr('id'));
|
|
// Hover handler to show dropdown
|
|
origin.on('mouseenter', function(e){ // Mouse over
|
|
if (open === false) {
|
|
placeDropdown();
|
|
open = true;
|
|
}
|
|
});
|
|
origin.on('mouseleave', function(e){
|
|
// If hover on origin then to something other than dropdown content, then close
|
|
var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element
|
|
if(!$(toEl).closest('.dropdown-content').is(activates)) {
|
|
activates.stop(true, true);
|
|
hideDropdown();
|
|
open = false;
|
|
}
|
|
});
|
|
|
|
activates.on('mouseleave', function(e){ // Mouse out
|
|
var toEl = e.toElement || e.relatedTarget;
|
|
if(!$(toEl).closest('.dropdown-button').is(origin)) {
|
|
activates.stop(true, true);
|
|
hideDropdown();
|
|
open = false;
|
|
}
|
|
});
|
|
|
|
// Click
|
|
} else {
|
|
// Click handler to show dropdown
|
|
origin.unbind('click.' + origin.attr('id'));
|
|
origin.bind('click.'+origin.attr('id'), function(e){
|
|
if (!isFocused) {
|
|
if ( origin[0] == e.currentTarget &&
|
|
!origin.hasClass('active') &&
|
|
($(e.target).closest('.dropdown-content').length === 0)) {
|
|
e.preventDefault(); // Prevents button click from moving window
|
|
if (options.stopPropagation) {
|
|
e.stopPropagation();
|
|
}
|
|
placeDropdown('click');
|
|
}
|
|
// If origin is clicked and menu is open, close menu
|
|
else if (origin.hasClass('active')) {
|
|
hideDropdown();
|
|
$(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
|
|
}
|
|
// If menu open, add click close handler to document
|
|
if (activates.hasClass('active')) {
|
|
$(document).bind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'), function (e) {
|
|
if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length) ) {
|
|
hideDropdown();
|
|
$(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id'));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
} // End else
|
|
|
|
// Listen to open and close event - useful for select component
|
|
origin.on('open', function(e, eventType) {
|
|
placeDropdown(eventType);
|
|
});
|
|
origin.on('close', hideDropdown);
|
|
|
|
|
|
});
|
|
}; // End dropdown plugin
|
|
|
|
$(document).ready(function(){
|
|
$('.dropdown-button').dropdown();
|
|
});
|
|
}( jQuery ));
|