mirror of
https://github.com/ExactTarget/fuelux.git
synced 2026-04-26 03:00:10 -04:00
140 lines
3.8 KiB
JavaScript
140 lines
3.8 KiB
JavaScript
/* global jQuery:true */
|
|
|
|
/*
|
|
* Fuel UX Dropdown Auto Flip
|
|
* https://github.com/ExactTarget/fuelux
|
|
*
|
|
* Copyright (c) 2014 ExactTarget
|
|
* Licensed under the BSD New license.
|
|
*/
|
|
|
|
// -- BEGIN UMD WRAPPER PREFACE --
|
|
|
|
// For more information on UMD visit:
|
|
// https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
|
|
|
|
(function umdFactory (factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// if AMD loader is available, register as an anonymous module.
|
|
define(['jquery'], factory);
|
|
} else if (typeof exports === 'object') {
|
|
// Node/CommonJS
|
|
module.exports = factory(require('jquery'));
|
|
} else {
|
|
// OR use browser globals if AMD is not present
|
|
factory(jQuery);
|
|
}
|
|
}(function dropdownautoflipWrapper ($) {
|
|
// -- END UMD WRAPPER PREFACE --
|
|
|
|
// -- BEGIN MODULE CODE HERE --
|
|
|
|
$(document).on('click.fu.dropdown-autoflip', '[data-toggle=dropdown][data-flip]', function (event) {
|
|
if ($(this).data().flip === "auto") {
|
|
// have the drop down decide where to place itself
|
|
_autoFlip($(this).next('.dropdown-menu'));
|
|
}
|
|
});
|
|
|
|
// For pillbox suggestions dropdown
|
|
$(document).on('suggested.fu.pillbox', function (event, element) {
|
|
_autoFlip($(element));
|
|
$(element).parent().addClass('open');
|
|
});
|
|
|
|
function _autoFlip(menu) {
|
|
// hide while the browser thinks
|
|
$(menu).css({
|
|
visibility: "hidden"
|
|
});
|
|
|
|
// decide where to put menu
|
|
if (dropUpCheck(menu)) {
|
|
menu.parent().addClass("dropup");
|
|
} else {
|
|
menu.parent().removeClass("dropup");
|
|
}
|
|
|
|
// show again
|
|
$(menu).css({
|
|
visibility: "visible"
|
|
});
|
|
}
|
|
|
|
function dropUpCheck(element) {
|
|
// caching container
|
|
var $container = _getContainer(element);
|
|
|
|
// building object with measurementsances for later use
|
|
var measurements = {};
|
|
measurements.parentHeight = element.parent().outerHeight();
|
|
measurements.parentOffsetTop = element.parent().offset().top;
|
|
measurements.dropdownHeight = element.outerHeight();
|
|
measurements.containerHeight = $container.overflowElement.outerHeight();
|
|
|
|
// this needs to be different if the window is the container or another element is
|
|
measurements.containerOffsetTop = (!!$container.isWindow) ? $container.overflowElement.scrollTop() : $container.overflowElement.offset().top;
|
|
|
|
// doing the calculations
|
|
measurements.fromTop = measurements.parentOffsetTop - measurements.containerOffsetTop;
|
|
measurements.fromBottom = measurements.containerHeight - measurements.parentHeight - (measurements.parentOffsetTop - measurements.containerOffsetTop);
|
|
|
|
// actual determination of where to put menu
|
|
// false = drop down
|
|
// true = drop up
|
|
if (measurements.dropdownHeight < measurements.fromBottom) {
|
|
return false;
|
|
} else if (measurements.dropdownHeight < measurements.fromTop) {
|
|
return true;
|
|
} else if (measurements.dropdownHeight >= measurements.fromTop && measurements.dropdownHeight >= measurements.fromBottom) {
|
|
// decide which one is bigger and put it there
|
|
if (measurements.fromTop >= measurements.fromBottom) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function _getContainer(element) {
|
|
var targetSelector = element.attr('data-target');
|
|
var isWindow = true;
|
|
var containerElement;
|
|
|
|
if(!targetSelector) {
|
|
// no selection so find the relevant ancestor
|
|
$.each(element.parents(), function (index, parentElement) {
|
|
if ($(parentElement).css('overflow') !== 'visible') {
|
|
containerElement = parentElement;
|
|
isWindow = false;
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
else if (targetSelector !== 'window') {
|
|
containerElement = $(targetSelector);
|
|
isWindow = false;
|
|
}
|
|
|
|
// fallback to window
|
|
if (isWindow) {
|
|
containerElement = window;
|
|
}
|
|
|
|
return {
|
|
overflowElement: $(containerElement),
|
|
isWindow: isWindow
|
|
};
|
|
}
|
|
|
|
// register empty plugin
|
|
$.fn.dropdownautoflip = function () {
|
|
/* empty */
|
|
};
|
|
|
|
// -- BEGIN UMD WRAPPER AFTERWORD --
|
|
}));
|
|
// -- END UMD WRAPPER AFTERWORD --
|