Functional directives TS
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
/* @ngInject */
|
|
||||||
export function autofocus($timeout) {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
scope: {
|
|
||||||
shouldFocus: '='
|
|
||||||
},
|
|
||||||
link: function($scope, $element) {
|
|
||||||
$timeout(function() {
|
|
||||||
if ($scope.shouldFocus) {
|
|
||||||
$element[0].focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
19
app/assets/javascripts/directives/functional/autofocus.ts
Normal file
19
app/assets/javascripts/directives/functional/autofocus.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* @ngInject */
|
||||||
|
export function autofocus($timeout: ng.ITimeoutService) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
scope: {
|
||||||
|
shouldFocus: '='
|
||||||
|
},
|
||||||
|
link: function (
|
||||||
|
$scope: ng.IScope,
|
||||||
|
$element: JQLite
|
||||||
|
) {
|
||||||
|
$timeout(() => {
|
||||||
|
if (($scope as any).shouldFocus) {
|
||||||
|
$element[0].focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
export function clickOutside($document) {
|
export function clickOutside($document: ng.IDocumentService) {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
replace: false,
|
replace: false,
|
||||||
link: function ($scope, $element, attrs) {
|
link: function ($scope: ng.IScope, $element: JQLite, attrs: any) {
|
||||||
// Causes memory leak as-is:
|
// Causes memory leak as-is:
|
||||||
// let didApplyClickOutside = false;
|
// let didApplyClickOutside = false;
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import angular from 'angular';
|
|
||||||
|
|
||||||
/* @ngInject */
|
|
||||||
export function delayHide($timeout) {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
scope: {
|
|
||||||
show: '=',
|
|
||||||
delay: '@'
|
|
||||||
},
|
|
||||||
link: function(scope, elem, attrs) {
|
|
||||||
showElement(false);
|
|
||||||
|
|
||||||
// This is where all the magic happens!
|
|
||||||
// Whenever the scope variable updates we simply
|
|
||||||
// show if it evaluates to 'true' and hide if 'false'
|
|
||||||
scope.$watch('show', function(newVal) {
|
|
||||||
newVal ? showSpinner() : hideSpinner();
|
|
||||||
});
|
|
||||||
|
|
||||||
function showSpinner() {
|
|
||||||
if (scope.hidePromise) {
|
|
||||||
$timeout.cancel(scope.hidePromise);
|
|
||||||
scope.hidePromise = null;
|
|
||||||
}
|
|
||||||
showElement(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideSpinner() {
|
|
||||||
scope.hidePromise = $timeout(showElement.bind(this, false), getDelay());
|
|
||||||
}
|
|
||||||
|
|
||||||
function showElement(show) {
|
|
||||||
show ? elem.css({ display: '' }) : elem.css({ display: 'none' });
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDelay() {
|
|
||||||
var delay = parseInt(scope.delay);
|
|
||||||
|
|
||||||
return angular.isNumber(delay) ? delay : 200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
45
app/assets/javascripts/directives/functional/delay-hide.ts
Normal file
45
app/assets/javascripts/directives/functional/delay-hide.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import angular from 'angular';
|
||||||
|
|
||||||
|
/* @ngInject */
|
||||||
|
export function delayHide($timeout: ng.ITimeoutService) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
scope: {
|
||||||
|
show: '=',
|
||||||
|
delay: '@'
|
||||||
|
},
|
||||||
|
link: function (scope: ng.IScope, elem: JQLite) {
|
||||||
|
const scopeAny = scope as any;
|
||||||
|
const showSpinner = () => {
|
||||||
|
if (scopeAny.hidePromise) {
|
||||||
|
$timeout.cancel(scopeAny.hidePromise);
|
||||||
|
scopeAny.hidePromise = null;
|
||||||
|
}
|
||||||
|
showElement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideSpinner = () => {
|
||||||
|
scopeAny.hidePromise = $timeout(
|
||||||
|
showElement.bind(this as any, false),
|
||||||
|
getDelay()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const showElement = (show: boolean) => {
|
||||||
|
show ? elem.css({ display: '' }) : elem.css({ display: 'none' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDelay = () => {
|
||||||
|
const delay = parseInt(scopeAny.delay);
|
||||||
|
return angular.isNumber(delay) ? delay : 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
showElement(false);
|
||||||
|
// Whenever the scope variable updates we simply
|
||||||
|
// show if it evaluates to 'true' and hide if 'false'
|
||||||
|
scope.$watch('show', function (newVal) {
|
||||||
|
newVal ? showSpinner() : hideSpinner();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
export function elemReady($parse) {
|
export function elemReady($parse: ng.IParseService) {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function($scope, elem, attrs) {
|
link: function($scope: ng.IScope, elem: JQLite, attrs: any) {
|
||||||
elem.ready(function() {
|
elem.ready(function() {
|
||||||
$scope.$apply(function() {
|
$scope.$apply(function() {
|
||||||
var func = $parse(attrs.elemReady);
|
var func = $parse(attrs.elemReady);
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/* @ngInject */
|
|
||||||
export function fileChange() {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
scope: {
|
|
||||||
handler: '&'
|
|
||||||
},
|
|
||||||
link: function(scope, element) {
|
|
||||||
element.on('change', function(event) {
|
|
||||||
scope.$apply(function() {
|
|
||||||
scope.handler({ files: event.target.files });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
19
app/assets/javascripts/directives/functional/file-change.ts
Normal file
19
app/assets/javascripts/directives/functional/file-change.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* @ngInject */
|
||||||
|
export function fileChange() {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
scope: {
|
||||||
|
handler: '&'
|
||||||
|
},
|
||||||
|
link: function (scope: ng.IScope, element: JQLite) {
|
||||||
|
element.on('change', (event) => {
|
||||||
|
scope.$apply(() => {
|
||||||
|
const files = (event.target as HTMLInputElement).files;
|
||||||
|
(scope as any).handler({
|
||||||
|
files: files
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
export function infiniteScroll() {
|
export function infiniteScroll() {
|
||||||
return {
|
return {
|
||||||
link: function(scope, elem, attrs) {
|
link: function (scope: ng.IScope, elem: JQLite, attrs: any) {
|
||||||
|
const scopeAny = scope as any;
|
||||||
const offset = parseInt(attrs.threshold) || 0;
|
const offset = parseInt(attrs.threshold) || 0;
|
||||||
const e = elem[0];
|
const e = elem[0];
|
||||||
scope.onScroll = () => {
|
scopeAny.onScroll = () => {
|
||||||
if (
|
if (
|
||||||
scope.$eval(attrs.canLoad) &&
|
scope.$eval(attrs.canLoad) &&
|
||||||
e.scrollTop + e.offsetHeight >= e.scrollHeight - offset
|
e.scrollTop + e.offsetHeight >= e.scrollHeight - offset
|
||||||
@@ -12,9 +13,9 @@ export function infiniteScroll() {
|
|||||||
scope.$apply(attrs.infiniteScroll);
|
scope.$apply(attrs.infiniteScroll);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
elem.on('scroll', scope.onScroll);
|
elem.on('scroll', scopeAny.onScroll);
|
||||||
scope.$on('$destroy', () => {
|
scope.$on('$destroy', () => {
|
||||||
elem.off('scroll', scope.onScroll);;
|
elem.off('scroll', scopeAny.onScroll);;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/* @ngInject */
|
|
||||||
export function lowercase() {
|
|
||||||
return {
|
|
||||||
require: 'ngModel',
|
|
||||||
link: function(scope, element, attrs, modelCtrl) {
|
|
||||||
var lowercase = function(inputValue) {
|
|
||||||
if (inputValue === undefined) inputValue = '';
|
|
||||||
var lowercased = inputValue.toLowerCase();
|
|
||||||
if (lowercased !== inputValue) {
|
|
||||||
modelCtrl.$setViewValue(lowercased);
|
|
||||||
modelCtrl.$render();
|
|
||||||
}
|
|
||||||
return lowercased;
|
|
||||||
};
|
|
||||||
modelCtrl.$parsers.push(lowercase);
|
|
||||||
lowercase(scope[attrs.ngModel]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
24
app/assets/javascripts/directives/functional/lowercase.ts
Normal file
24
app/assets/javascripts/directives/functional/lowercase.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* @ngInject */
|
||||||
|
export function lowercase() {
|
||||||
|
return {
|
||||||
|
require: 'ngModel',
|
||||||
|
link: function (
|
||||||
|
scope: ng.IScope,
|
||||||
|
_: JQLite,
|
||||||
|
attrs: any,
|
||||||
|
ctrl: ng.IController
|
||||||
|
) {
|
||||||
|
const lowercase = (inputValue: string) => {
|
||||||
|
if (inputValue === undefined) inputValue = '';
|
||||||
|
const lowercased = inputValue.toLowerCase();
|
||||||
|
if (lowercased !== inputValue) {
|
||||||
|
ctrl.$setViewValue(lowercased);
|
||||||
|
ctrl.$render();
|
||||||
|
}
|
||||||
|
return lowercased;
|
||||||
|
};
|
||||||
|
ctrl.$parsers.push(lowercase);
|
||||||
|
lowercase((scope as any)[attrs.ngModel]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/* @ngInject */
|
|
||||||
export function selectOnClick($window) {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: function(scope, element, attrs) {
|
|
||||||
element.on('focus', function() {
|
|
||||||
if (!$window.getSelection().toString()) {
|
|
||||||
/** Required for mobile Safari */
|
|
||||||
this.setSelectionRange(0, this.value.length);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/* @ngInject */
|
||||||
|
export function selectOnClick($window: ng.IWindowService) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
link: function(scope: ng.IScope, element: JQLite) {
|
||||||
|
element.on('focus', function() {
|
||||||
|
if (!$window.getSelection()!.toString()) {
|
||||||
|
const input = element as any;
|
||||||
|
/** Required for mobile Safari */
|
||||||
|
input.setSelectionRange(0, input.value.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
export function snEnter() {
|
export function snEnter() {
|
||||||
return function(scope, element, attrs) {
|
return function (
|
||||||
element.bind('keydown keypress', function(event) {
|
scope: ng.IScope,
|
||||||
|
element: JQLite,
|
||||||
|
attrs: any
|
||||||
|
) {
|
||||||
|
element.bind('keydown keypress', function (event) {
|
||||||
if (event.which === 13) {
|
if (event.which === 13) {
|
||||||
scope.$apply(function() {
|
scope.$apply(function () {
|
||||||
scope.$eval(attrs.snEnter, { event: event });
|
scope.$eval(attrs.snEnter, { event: event });
|
||||||
});
|
});
|
||||||
|
|
||||||
Reference in New Issue
Block a user