Last active
October 18, 2023 04:11
-
-
Save adamreisnz/2664df320da873c69e0f to your computer and use it in GitHub Desktop.
A collection of random useful Angular directives
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Angular directives |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Layout.BackgroundImage.Directive', []) | |
/** | |
* Directive definition | |
*/ | |
.directive('backgroundImage', function($document, $animate) { | |
return { | |
restrict: 'A', | |
link: function(scope, element, attrs) { | |
attrs.$observe('backgroundImage', function(src) { | |
//Add loading class and reset background image | |
element.addClass('loading').css({ | |
'background-image': null | |
}); | |
//Create image element | |
var img = $document[0].createElement('img'); | |
//Append onload event | |
img.onload = function() { | |
//Remove loading class using the animate service (to trigger CSS animations) | |
$animate.removeClass(element, 'loading'); | |
element.css({ | |
'background-image': 'url(' + this.src + ')' | |
}); | |
}; | |
//Set source on image now | |
img.src = src; | |
}); | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Events.DetectScrolling.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('detectScrolling', function($rootScope) { | |
return { | |
restrict: 'A', | |
link: function(scope, element, attrs) { | |
//Attach event to element | |
element.on('scroll', function() { | |
var scrollOffset = 0; | |
if (angular.isDefined(element[0].scrollTop)) { | |
scrollOffset = element[0].scrollTop; | |
} | |
else if (element[0].context && angular.isDefined(element[0].context.scrollTop)) { | |
scrollOffset = element[0].context.scrollTop; | |
} | |
//Broadcast event | |
scope.$apply(function() { | |
scope.isScrolling = (scrollOffset > 0); | |
$rootScope.$broadcast('detectedScrolling', scrollOffset, element); | |
}); | |
}); | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Events.DetectWindowScrolling.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('detectWindowScrolling', function($window, $rootScope) { | |
return { | |
restrict: 'A', | |
link: function(scope, element, attrs) { | |
angular.element($window).on('scroll resize', function() { | |
scope.$apply(function() { | |
scope.isScrolling = ($window.pageYOffset > 0); | |
$rootScope.$broadcast('detectedScrolling', $window.pageYOffset, $window); | |
}); | |
}); | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Layout.DisableAnimate.Directive', []) | |
/** | |
* Animate disabler | |
*/ | |
.directive('disableAnimate', function($animate) { | |
return function(scope, element) { | |
$animate.enabled(false, element); | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Validation.EqualOrMore.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('equalOrMore', function($parse) { | |
return { | |
require: 'ngModel', | |
link: function(scope, element, attrs, ngModel) { | |
//Match getter | |
var matchGetter = $parse(attrs.equalOrMore); | |
var allowEmpty = (attrs.allowEmpty === 'true'); | |
//Match value helper | |
function getMatchValue() { | |
var match = matchGetter(scope); | |
if (angular.isObject(match) && match.hasOwnProperty('$viewValue')) { | |
match = match.$viewValue; | |
} | |
return match; | |
} | |
//Re-validate on change of the match value | |
scope.$watch(getMatchValue, function() { | |
ngModel.$validate(); | |
}); | |
//Add validator | |
ngModel.$validators.equalOrMore = function(modelValue, viewValue) { | |
//Get match value and our value | |
var value = modelValue || viewValue; | |
var match = getMatchValue(); | |
//Must have match | |
if (match === null || !angular.isDefined(match)) { | |
return true; | |
} | |
//Allow empty? | |
if (allowEmpty && (value === null || !angular.isDefined(value) || value === '')) { | |
return true; | |
} | |
//Check match | |
return value >= match; | |
}; | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Ui.FullScreen.Directive', []) | |
/** | |
* Service definition | |
*/ | |
.factory('FullScreen', function($document, $rootScope) { | |
//Get document element | |
var document = $document[0]; | |
//Create service instance | |
var FullScreen = { | |
/** | |
* Enable full screen on the complete document | |
*/ | |
all: function() { | |
FullScreen.enable(document.documentElement); | |
}, | |
/** | |
* Enable full screen on a specific element | |
*/ | |
enable: function(element) { | |
if (element.requestFullScreen) { | |
element.requestFullScreen(); | |
} | |
else if(element.mozRequestFullScreen) { | |
element.mozRequestFullScreen(); | |
} | |
else if(element.webkitRequestFullScreen) { | |
element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); | |
} | |
else if (element.msRequestFullscreen) { | |
element.msRequestFullscreen(); | |
} | |
}, | |
/** | |
* Disable full screen | |
*/ | |
disable: function() { | |
if (document.cancelFullScreen) { | |
document.cancelFullScreen(); | |
} | |
else if (document.mozCancelFullScreen) { | |
document.mozCancelFullScreen(); | |
} | |
else if (document.webkitCancelFullScreen) { | |
document.webkitCancelFullScreen(); | |
} | |
else if (document.msExitFullscreen) { | |
document.msExitFullscreen(); | |
} | |
}, | |
/** | |
* Check to see if full screen is enabled | |
*/ | |
isEnabled: function() { | |
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; | |
return fullscreenElement; | |
}, | |
/** | |
* Check to see if full screen mode is supported | |
*/ | |
isSupported: function() { | |
return document.documentElement.requestFullScreen || | |
document.documentElement.mozRequestFullScreen || | |
document.documentElement.webkitRequestFullScreen || | |
document.documentElement.msRequestFullscreen; | |
} | |
}; | |
//Return the instance | |
return FullScreen; | |
}) | |
/** | |
* Directive | |
*/ | |
.directive('fullscreen', function($rootScope, FullScreen) { | |
return { | |
link: function (scope, element, attrs) { | |
//Watch for changes on scope if model is provided | |
if (attrs.fullscreen) { | |
scope.$watch(attrs.fullscreen, function(value) { | |
var isEnabled = FullScreen.isEnabled(); | |
if (value && !isEnabled) { | |
FullScreen.enable(element[0]); | |
element.addClass('full-screen'); | |
} | |
else if (!value && isEnabled) { | |
FullScreen.cancel(); | |
element.removeClass('full-screen'); | |
} | |
}); | |
element.on('fullscreenchange webkitfullscreenchange mozfullscreenchange', function() { | |
if (!FullScreen.isEnabled()){ | |
scope.$evalAsync(function() { | |
scope[attrs.fullscreen] = false; | |
element.removeClass('full-screen'); | |
}); | |
} | |
}); | |
} | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Validation.IsolatedForm.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('isolatedForm', function($animate) { | |
return { | |
restrict: 'A', | |
require: '?form', | |
link: function(scope, element, attrs, ngModel) { | |
//Must have model controller | |
if (!ngModel) { | |
return; | |
} | |
//Copy the controller | |
var ngModelCopy = {}; | |
angular.copy(ngModel, ngModelCopy); | |
//Get the parent element of the form | |
var parent = element.parent().controller('form'); | |
//Remove parent link to the controller | |
parent.$removeControl(ngModel); | |
//Replace form controller with an isolated version | |
var ngModelIsolated = { | |
$setValidity: function(validationToken, isValid, control) { | |
ngModelCopy.$setValidity(validationToken, isValid, control); | |
parent.$setValidity(validationToken, true, ngModel); | |
}, | |
$setDirty: function() { | |
$animate.removeClass(element, 'ng-pristine'); | |
$animate.addClass(element, 'ng-dirty'); | |
ngModel.$dirty = true; | |
ngModel.$pristine = false; | |
}, | |
$setSubmitted: function() { | |
$animate.addClass(element, 'ng-submitted'); | |
ngModel.$submitted = true; | |
} | |
}; | |
//Extend the controller now | |
angular.extend(ngModel, ngModelIsolated); | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Layout.IsOverflowing.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('isOverflowing', function() { | |
/** | |
* Helper to determine if overflowing | |
*/ | |
function isOverflowing(element) { | |
//Remember current overflow, and set to hidden | |
var curOverflow = element[0].style.overflow; | |
element[0].style.overflow = 'hidden'; | |
//Determine if overflowing and set back to original value | |
var overflowing = element[0].clientWidth < element[0].scrollWidth || | |
element[0].clientHeight < element[0].scrollHeight; | |
element[0].style.overflow = curOverflow; | |
//Return | |
return overflowing; | |
} | |
/** | |
* Directive | |
*/ | |
return { | |
link: function(scope, element, attrs) { | |
//Determine overflow class | |
var overflowClass = attrs.checkOverflow || 'overflowing'; | |
//Watch content | |
scope.$watch(function() { | |
return element[0].text; | |
}, function() { | |
if (isOverflowing(element)) { | |
element.addClass(overflowClass); | |
} | |
else { | |
element.removeClass(overflowClass); | |
} | |
}); | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Validation.Match.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('match', function($parse) { | |
return { | |
require: 'ngModel', | |
link: function(scope, element, attrs, ngModel) { | |
//Match getter | |
var matchGetter = $parse(attrs.match); | |
var allowEmpty = (attrs.allowEmpty === 'true'); | |
//Match value helper | |
function getMatchValue() { | |
var match = matchGetter(scope); | |
if (angular.isObject(match) && match.hasOwnProperty('$viewValue')) { | |
match = match.$viewValue; | |
} | |
return match; | |
} | |
//Re-validate on change of the match value | |
scope.$watch(getMatchValue, function() { | |
ngModel.$validate(); | |
}); | |
//Add validator | |
ngModel.$validators.match = function(modelValue, viewValue) { | |
//Get match value and our value | |
var value = modelValue || viewValue; | |
var match = getMatchValue(); | |
//Must have match | |
if (match === null || !angular.isDefined(match)) { | |
return true; | |
} | |
//Allow empty? | |
if (allowEmpty && (value === null || !angular.isDefined(value) || value === '')) { | |
return true; | |
} | |
//Check match | |
return value === match; | |
}; | |
} | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module definition and dependencies | |
*/ | |
angular.module('Validation.MaxFileSize.Directive', []) | |
/** | |
* Directive | |
*/ | |
.directive('maxFileSize', function() { | |
return { | |
require: 'ngModel', | |
link: function(scope, element, attrs, ngModel) { | |
//Get max file size | |
var maxSize = parseInt(attrs.maxFileSize, 10); | |
//Add validator | |
ngModel.$validators.fileSize = function(modelValue, viewValue) { | |
//No max size limit? | |
if (maxSize === 0) { | |
return true; | |
} | |
//Get files list | |
var model = modelValue || viewValue; | |
if (!model.files) { | |
return true; | |
} | |
//Loop and check each file | |
for (var i = 0; i < model.files.length; i++) { | |
if (model.files[i].size && model.files[i].size > maxSize) { | |
return false; | |
} | |
if (model.files[i].fileSize && model.files[i].fileSize > maxSize) { | |
return false; | |
} | |
} | |
//By default, pass through | |
return true; | |
}; | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome...Excited for Angular 5 version for these !!!