Skip to content

Instantly share code, notes, and snippets.

@sudodoki
Last active February 15, 2017 15:17
Show Gist options
  • Save sudodoki/7475106 to your computer and use it in GitHub Desktop.
Save sudodoki/7475106 to your computer and use it in GitHub Desktop.
jQuery outside events wrapper for Angular JS

jQuery outside events wrapper for Angular js.

In case you are willing to use jquery outside events plugin by @cowboy with Angular JS, and don't want to get your hands dirty, try this wrapper.
It defines oc-clickoutside, oc-dblclickoutside, oc-mouseoveroustide, oc-focusoutside directives you can use in your code.
In order to use with amd, don't forget to set path for outsideEvents.js and its dependency jQuery.
use just like you

 <popup oc-clickoutside="hidePopup()">Your awesome popup content.</popup>

In case you don't need amd, just strip out the define(['angular', 'outsideEvents'],function(angular){...}) part. Don't forget to load module while initializing your own. module('myAwesomeApp', ['outsideEvents'])

/* Defines oc-clickoutside, oc-dblclickoutside, oc-mouseoveroustide, oc-focusoutside */
define(
['angular', 'outsideEvents'],
function (angular) {
"use strict";
var outsideEventsDirectives = {};
angular.forEach(
['clickoutside', 'dblclickoutside', 'mouseoveroutside', 'focusoutside'],
function(name) {
var directiveName = 'oc' + name.charAt(0).toUpperCase() + name.slice(1)
outsideEventsDirectives[directiveName] = ['$parse', function($parse) {
return {
compile: function($element, attr) {
var fn = $parse(attr[directiveName]);
return function(scope, element, attr) {
element.on(name, function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
});
};
}
};
}];
}
);
angular.module('outsideEvents', []).directive(outsideEventsDirectives);
}
);
/*!
* jQuery outside events - v1.1 - 3/16/2010
* http://benalman.com/projects/jquery-outside-events-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery outside events
//
// *Version: 1.1, Last updated: 3/16/2010*
//
// Project Home - http://benalman.com/projects/jquery-outside-events-plugin/
// GitHub - http://github.com/cowboy/jquery-outside-events/
// Source - http://github.com/cowboy/jquery-outside-events/raw/master/jquery.ba-outside-events.js
// (Minified) - http://github.com/cowboy/jquery-outside-events/raw/master/jquery.ba-outside-events.min.js (0.9kb)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// clickoutside - http://benalman.com/code/projects/jquery-outside-events/examples/clickoutside/
// dblclickoutside - http://benalman.com/code/projects/jquery-outside-events/examples/dblclickoutside/
// mouseoveroutside - http://benalman.com/code/projects/jquery-outside-events/examples/mouseoveroutside/
// focusoutside - http://benalman.com/code/projects/jquery-outside-events/examples/focusoutside/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1.
// Unit Tests - http://benalman.com/code/projects/jquery-outside-events/unit/
//
// About: Release History
//
// 1.1 - (3/16/2010) Made "clickoutside" plugin more general, resulting in a
// whole new plugin with more than a dozen default "outside" events and
// a method that can be used to add new ones.
// 1.0 - (2/27/2010) Initial release
//
// Topic: Default "outside" events
//
// Note that each "outside" event is powered by an "originating" event. Only
// when the originating event is triggered on an element outside the element
// to which that outside event is bound will the bound event be triggered.
//
// Because each outside event is powered by a separate originating event,
// stopping propagation of that originating event will prevent its related
// outside event from triggering.
//
// OUTSIDE EVENT - ORIGINATING EVENT
// clickoutside - click
// dblclickoutside - dblclick
// focusoutside - focusin
// bluroutside - focusout
// mousemoveoutside - mousemove
// mousedownoutside - mousedown
// mouseupoutside - mouseup
// mouseoveroutside - mouseover
// mouseoutoutside - mouseout
// keydownoutside - keydown
// keypressoutside - keypress
// keyupoutside - keyup
// changeoutside - change
// selectoutside - select
// submitoutside - submit
(function($,doc,outside){
'$:nomunge'; // Used by YUI compressor.
$.map(
// All these events will get an "outside" event counterpart by default.
'click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup'.split(' '),
function( event_name ) { jq_addOutsideEvent( event_name ); }
);
// The focus and blur events are really focusin and focusout when it comes
// to delegation, so they are a special case.
jq_addOutsideEvent( 'focusin', 'focus' + outside );
jq_addOutsideEvent( 'focusout', 'blur' + outside );
// Method: jQuery.addOutsideEvent
//
// Register a new "outside" event to be with this method. Adding an outside
// event that already exists will probably blow things up, so check the
// <Default "outside" events> list before trying to add a new one.
//
// Usage:
//
// > jQuery.addOutsideEvent( event_name [, outside_event_name ] );
//
// Arguments:
//
// event_name - (String) The name of the originating event that the new
// "outside" event will be powered by. This event can be a native or
// custom event, as long as it bubbles up the DOM tree.
// outside_event_name - (String) An optional name for the new "outside"
// event. If omitted, the outside event will be named whatever the
// value of `event_name` is plus the "outside" suffix.
//
// Returns:
//
// Nothing.
$.addOutsideEvent = jq_addOutsideEvent;
function jq_addOutsideEvent( event_name, outside_event_name ) {
// The "outside" event name.
outside_event_name = outside_event_name || event_name + outside;
// A jQuery object containing all elements to which the "outside" event is
// bound.
var elems = $(),
// The "originating" event, namespaced for easy unbinding.
event_namespaced = event_name + '.' + outside_event_name + '-special-event';
// Event: outside events
//
// An "outside" event is triggered on an element when its corresponding
// "originating" event is triggered on an element outside the element in
// question. See the <Default "outside" events> list for more information.
//
// Usage:
//
// > jQuery('selector').bind( 'clickoutside', function(event) {
// > var clicked_elem = $(event.target);
// > ...
// > });
//
// > jQuery('selector').bind( 'dblclickoutside', function(event) {
// > var double_clicked_elem = $(event.target);
// > ...
// > });
//
// > jQuery('selector').bind( 'mouseoveroutside', function(event) {
// > var moused_over_elem = $(event.target);
// > ...
// > });
//
// > jQuery('selector').bind( 'focusoutside', function(event) {
// > var focused_elem = $(event.target);
// > ...
// > });
//
// You get the idea, right?
$.event.special[ outside_event_name ] = {
// Called only when the first "outside" event callback is bound per
// element.
setup: function(){
// Add this element to the list of elements to which this "outside"
// event is bound.
elems = elems.add( this );
// If this is the first element getting the event bound, bind a handler
// to document to catch all corresponding "originating" events.
if ( elems.length === 1 ) {
$(doc).bind( event_namespaced, handle_event );
}
},
// Called only when the last "outside" event callback is unbound per
// element.
teardown: function(){
// Remove this element from the list of elements to which this
// "outside" event is bound.
elems = elems.not( this );
// If this is the last element removed, remove the "originating" event
// handler on document that powers this "outside" event.
if ( elems.length === 0 ) {
$(doc).unbind( event_namespaced );
}
},
// Called every time a "outside" event callback is bound to an element.
add: function( handleObj ) {
var old_handler = handleObj.handler;
// This function is executed every time the event is triggered. This is
// used to override the default event.target reference with one that is
// more useful.
handleObj.handler = function( event, elem ) {
// Set the event object's .target property to the element that the
// user interacted with, not the element that the "outside" event was
// was triggered on.
event.target = elem;
// Execute the actual bound handler.
old_handler.apply( this, arguments );
};
}
};
// When the "originating" event is triggered..
function handle_event( event ) {
// Iterate over all elements to which this "outside" event is bound.
$(elems).each(function(){
var elem = $(this);
// If this element isn't the element on which the event was triggered,
// and this element doesn't contain said element, then said element is
// considered to be outside, and the "outside" event will be triggered!
if ( this !== event.target && !elem.has(event.target).length ) {
// Use triggerHandler instead of trigger so that the "outside" event
// doesn't bubble. Pass in the "originating" event's .target so that
// the "outside" event.target can be overridden with something more
// meaningful.
elem.triggerHandler( outside_event_name, [ event.target ] );
}
});
};
};
})(jQuery,document,"outside");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment