dropdown-autoflip.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Fuel UX Dropdown Auto Flip
  3. * https://github.com/ExactTarget/fuelux
  4. *
  5. * Copyright (c) 2014 ExactTarget
  6. * Licensed under the BSD New license.
  7. */
  8. // -- BEGIN UMD WRAPPER PREFACE --
  9. // For more information on UMD visit:
  10. // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
  11. (function (factory) {
  12. if (typeof define === 'function' && define.amd) {
  13. // if AMD loader is available, register as an anonymous module.
  14. define(['jquery'], factory);
  15. } else {
  16. // OR use browser globals if AMD is not present
  17. factory(jQuery);
  18. }
  19. }(function ($) {
  20. // -- END UMD WRAPPER PREFACE --
  21. // -- BEGIN MODULE CODE HERE --
  22. $(document.body).on('click.fu.dropdown-autoflip', '[data-toggle=dropdown][data-flip]', function (event) {
  23. if ($(this).data().flip === "auto") {
  24. // have the drop down decide where to place itself
  25. _autoFlip($(this).next('.dropdown-menu'));
  26. }
  27. });
  28. // For pillbox suggestions dropdown
  29. $(document.body).on('suggested.fu.pillbox', function (event, element) {
  30. _autoFlip($(element));
  31. $(element).parent().addClass('open');
  32. });
  33. function _autoFlip(menu) {
  34. // hide while the browser thinks
  35. $(menu).css({
  36. visibility: "hidden"
  37. });
  38. // decide where to put menu
  39. if (dropUpCheck(menu)) {
  40. menu.parent().addClass("dropup");
  41. } else {
  42. menu.parent().removeClass("dropup");
  43. }
  44. // show again
  45. $(menu).css({
  46. visibility: "visible"
  47. });
  48. }
  49. function dropUpCheck(element) {
  50. // caching container
  51. var $container = _getContainer(element);
  52. // building object with measurementsances for later use
  53. var measurements = {};
  54. measurements.parentHeight = element.parent().outerHeight();
  55. measurements.parentOffsetTop = element.parent().offset().top;
  56. measurements.dropdownHeight = element.outerHeight();
  57. measurements.containerHeight = $container.overflowElement.outerHeight();
  58. // this needs to be different if the window is the container or another element is
  59. measurements.containerOffsetTop = (!!$container.isWindow) ? $container.overflowElement.scrollTop() : $container.overflowElement.offset().top;
  60. // doing the calculations
  61. measurements.fromTop = measurements.parentOffsetTop - measurements.containerOffsetTop;
  62. measurements.fromBottom = measurements.containerHeight - measurements.parentHeight - (measurements.parentOffsetTop - measurements.containerOffsetTop);
  63. // actual determination of where to put menu
  64. // false = drop down
  65. // true = drop up
  66. if (measurements.dropdownHeight < measurements.fromBottom) {
  67. return false;
  68. } else if (measurements.dropdownHeight < measurements.fromTop) {
  69. return true;
  70. } else if (measurements.dropdownHeight >= measurements.fromTop && measurements.dropdownHeight >= measurements.fromBottom) {
  71. // decide which one is bigger and put it there
  72. if (measurements.fromTop >= measurements.fromBottom) {
  73. return true;
  74. } else {
  75. return false;
  76. }
  77. }
  78. }
  79. function _getContainer(element) {
  80. var containerElement, isWindow;
  81. if (element.attr('data-target')) {
  82. containerElement = element.attr('data-target');
  83. isWindow = false;
  84. } else {
  85. containerElement = window;
  86. isWindow = true;
  87. }
  88. $.each(element.parents(), function (index, value) {
  89. if ($(value).css('overflow') !== 'visible') {
  90. containerElement = value;
  91. isWindow = false;
  92. return false;
  93. }
  94. });
  95. return {
  96. overflowElement: $(containerElement),
  97. isWindow: isWindow
  98. };
  99. }
  100. // register empty plugin
  101. $.fn.dropdownautoflip = function () {
  102. /* empty */
  103. };
  104. // -- BEGIN UMD WRAPPER AFTERWORD --
  105. }));
  106. // -- END UMD WRAPPER AFTERWORD --