popover-extra-placements.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. (function($) {
  2. "use strict"; // jshint;_;
  3. // save the original plugin function object
  4. var _super = $.fn.popover;
  5. // create a new constructor
  6. var Popover = function(element, options) {
  7. _super.Constructor.apply(this, arguments);
  8. };
  9. // extend prototypes and create a super function
  10. Popover.prototype = $.extend({}, _super.Constructor.prototype, {
  11. constructor: Popover,
  12. _super: function() {
  13. var args = $.makeArray(arguments);
  14. _super.Constructor.prototype[args.shift()].apply(this, args);
  15. },
  16. show: function() {
  17. var $tip, inside, pos, actualWidth, actualHeight, placement, tp;
  18. if (this.hasContent && this.enabled) {
  19. $tip = this.tip();
  20. this.setContent();
  21. if (this.options.animation) {
  22. $tip.addClass('fade');
  23. }
  24. placement = typeof this.options.placement == 'function' ?
  25. this.options.placement.call(this, $tip[0], this.$element[0]) :
  26. this.options.placement;
  27. inside = /in/.test(placement);
  28. $tip
  29. .remove()
  30. .css({ top: 0, left: 0, display: 'block' })
  31. .appendTo(inside ? this.$element : document.body);
  32. pos = this.getPosition(inside);
  33. actualWidth = $tip[0].offsetWidth;
  34. actualHeight = $tip[0].offsetHeight;
  35. switch (inside ? placement.split(' ')[1] : placement) {
  36. case 'bottom':
  37. tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2};
  38. break;
  39. case 'top':
  40. tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2};
  41. break;
  42. case 'left':
  43. tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth};
  44. break;
  45. case 'right':
  46. tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width};
  47. break;
  48. // extend placements (top)
  49. case 'topLeft':
  50. tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - (actualWidth * .25)};
  51. break;
  52. case 'topRight':
  53. tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - (actualWidth * .75)};
  54. break;
  55. // extend placements (right)
  56. case 'rightTop':
  57. tp = {top: pos.top + pos.height / 2 - (actualHeight *.25), left: pos.left + pos.width};
  58. break;
  59. case 'rightBottom':
  60. tp = {top: pos.top + pos.height / 2 - (actualHeight * .75), left: pos.left + pos.width};
  61. break;
  62. // extend placements (bottom)
  63. case 'bottomLeft':
  64. tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - (actualWidth * .25)};
  65. break;
  66. case 'bottomRight':
  67. tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - (actualWidth * .80)};
  68. break;
  69. // extend placements (left)
  70. case 'leftTop':
  71. tp = {top: pos.top + pos.height / 2 - (actualHeight *.25), left: pos.left - actualWidth};
  72. break;
  73. case 'leftBottom':
  74. tp = {top: pos.top + pos.height / 2 - (actualHeight * .75), left: pos.left - actualWidth};
  75. break;
  76. }
  77. $tip
  78. .css(tp)
  79. .addClass(placement)
  80. .addClass('in');
  81. }
  82. }
  83. });
  84. $.fn.popover = $.extend(function (option) {
  85. return this.each(function () {
  86. var $this = $(this)
  87. , data = $this.data('popover')
  88. , options = typeof option == 'object' && option;
  89. if (!data) $this.data('popover', (data = new Popover(this, options)));
  90. if (typeof option == 'string') data[option]();
  91. });
  92. }, _super);
  93. })(jQuery);