atms-popover.js 5.23 KB
Newer Older
frank.xa.zhang's avatar
frank.xa.zhang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
// Popover control inherit from bootstrap popover.

// Simplest eg. 
//<button title="Test Title" data-content="Here is an example popover" data-placement="right" atms-popover>PopTest</button>

// data-placement attribute.
// It is used to specify the placement of popover.
// Available values: 'bottom' 'top' 'left' 'right' 'topLeft' 'topRight' 'rightTop' 'rightBottom' 'bottomLeft' 'bottomRight' 'leftTop' 'leftBottom'

// Use 'auto' option in data-placement.
// This will allow popover to locate itself automatically which consider the boundary of its parent.
// It will go through an ordered placement list. If there is not enough space for current placement, then it will go to next.
// The placements specified in data-placement attribute will be add to the top of the ordered list.
// eg. <button title="Test Title" data-content="Here is an example popover" data-placement="auto right left top bottom" atms-popover>PopTest</button>

// popover-auto-hide attribute.
// It is used to specify whether hide the popover when mouse click out.
// Set it to 'true' to hide the popover otherwise 'false'.
// Default is 'false'.
// eg. <button popover-auto-hide="true" title="Test Title" data-content="Here is an example popover" atms-popover>PopTest</button>

// data-templateurl attribute.
// It is used to specify url of html template. This template will be load each time the popover openned.
// It will be compiled and link to the scope of this directive.
// eg. <button data-templateurl="/app/atms-popover-test.html" atms-popover>PopTest</button>
// 'onPopoverShown' will be triggered when popover is shown. for example, on-popover-shown="onPopupShown" 
// 'onPopoverHidden' will be triggered when popover is hidden. for exmaple, on-popover-hidden="onPopupHidden"

commonModule.directive('atmsPopover', ['$compile', '$document', '$parse', function ($compile, $document, $parse) {
    return {
        restrict: "A",
        link: function (scope, element, attr) {
            var popoverOptions = {
                compliler: $compile,
                scope: scope,
                // Disable fade animation for now. Because if you click the button to toggle popover multiple times, sometimes the 
                // popover is not removed from DOM and is invisible. This will block you to click the content behind it.
                animation: false
            };

            if (attr['useOptimizedPlacementAlgorithm']) {
                popoverOptions.useOptimizedPlacementAlgorithm = attr['useOptimizedPlacementAlgorithm'];
            }

            if (attr['popoverContainer']) {
                popoverOptions.container = attr['popoverContainer'];
            }

            if (attr['popoverTrigger']) {
                popoverOptions.trigger = attr['popoverTrigger'];
            }

            element.popover(popoverOptions);

            var popContent;
            var onClick = function (event) {
                if (!popContent)
                    return;
                var iswithinElement = popContent.find(event.target).length > 0 || popContent.context === event.target;
                var isOnCalendar = $(event.target).closest('.datepicker').length > 0;
                var isInTooltip = $(event.target).closest('.tooltip-inner').length > 0;
                //=>Alsace Updatev
                var isInChildPopver = $(event.target).closest('.child-popover').length > 0;
                if (iswithinElement || isOnCalendar || isInTooltip || isInChildPopver) {
                    event.stopPropagation();
                } else {
                    element.popover('hide');
                }
            };

            var onResize = function () {
                element.popover('hide');
            };

            var subscribeGlobalEvent = function () {
                $document.on('mousedown', onClick);
                $(window).on('resize', onResize);
            };

            var unsubscribeGlobalEvent = function () {
                $document.off('mousedown', onClick);
                $(window).off('resize', onResize);
            };

            var isAutoHide = attr['popoverAutoHide'] === 'true';
            var onShowPopover = attr['onShowPopover'];

            if (onShowPopover) {
                element.on('show.bs.popover', function (event) {
                    scope[onShowPopover](event);
                });
            }

            element.on('shown.bs.popover', function (event, popElement) {
                var onPopoverShown = attr['onPopoverShown'];
                if (onPopoverShown) {
                    var onPopoverShownAction = $parse(onPopoverShown);
                    onPopoverShownAction(scope).call();

                }

                if (isAutoHide) {
                    unsubscribeGlobalEvent();
                    subscribeGlobalEvent();
                    popContent = $(popElement);
                }
            });

            element.on('hidden.bs.popover', function (event) {
                var onPopoverHidden = attr['onPopoverHidden'];
                if (onPopoverHidden) {
                    scope[onPopoverHidden](event);
                }
                unsubscribeGlobalEvent();
            });

            scope.$on('atms-popover:event', function (event, action) {
                element.popover(action);
            });
        }
    };
}]);