Blame view
resources/js/common/directives/frClickOut.js
2.54 KB
e77200db5 Initial commit |
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 |
/** * A directive that will execute a function when user clicks out of the current * element. By specifying filter, one can also extend this functionality to other * elements, meaning that when user clicks on that element it will not count as * an out click. By specifying include you can tell which elements will count as * an out click. Include is useful only when you want to trigger an out click on * of the children of the element itself. * * Example * * ```html * <div fr-click-out="close()" fr-click-out-filter="#openBtn, .header-nav" fr-click-out-include=".close-btn"> * ... * </div> * ``` */ angular.module('fr.clickOut', []) .directive('frClickOut', ['$document', '$parse', function ($document, $parse) { // Checks if any of elements defined by selectors in filter contain target. // In other words checks if one of the filtered elements has been clicked. function targetInFilter(target, filter) { var filteredElements = angular.element($document[0].querySelectorAll(filter)); var totalElements = filteredElements.length; for (var i = 0; i < totalElements; ++i) { if (filteredElements[i].contains(target)) { return true; } } return false; } // Run the checks to see if we need to run click out handler or not. function isClickOut(element, event, filter, include) { // Make sure clicked element is not one of the included elements. if (include && targetInFilter(event.target, include)) { return true; } // Make sure clicked element is not inside our element. if (element[0].contains(event.target)) { return; } // Make sure clicked element is not one of filtered elements. if (filter && targetInFilter(event.target, filter)) { return; } return true; } return { restrict: 'A', link: function (scope, element, attrs) { var clickOutHandler = $parse(attrs.frClickOut)(scope); var filter = attrs.frClickOutFilter; var include = attrs.frClickOutInclude; // Listen for clicks on the whole document. $document.bind('click', handle); scope.$on('$destroy', function () { $document.off('click', handle); }); function handle(event) { if (isClickOut(element, event, filter, include)) { clickOutHandler(event); scope.$apply(); } } }, }; }]); |