Refactors most controllers and directives into classes for more organized and maintainable code
This commit is contained in:
16
app/assets/javascripts/directives/functional/autofocus.js
Normal file
16
app/assets/javascripts/directives/functional/autofocus.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* @ngInject */
|
||||
export function autofocus($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
shouldFocus: '='
|
||||
},
|
||||
link: function($scope, $element) {
|
||||
$timeout(function() {
|
||||
if ($scope.shouldFocus) {
|
||||
$element[0].focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* @ngInject */
|
||||
export function clickOutside($document) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
link: function($scope, $element, attrs) {
|
||||
var didApplyClickOutside = false;
|
||||
|
||||
$element.bind('click', function(e) {
|
||||
didApplyClickOutside = false;
|
||||
if (attrs.isOpen) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
$document.bind('click', function() {
|
||||
// Ignore click if on SKAlert
|
||||
if (event.target.closest(".sk-modal")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!didApplyClickOutside) {
|
||||
$scope.$apply(attrs.clickOutside);
|
||||
didApplyClickOutside = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
44
app/assets/javascripts/directives/functional/delay-hide.js
Normal file
44
app/assets/javascripts/directives/functional/delay-hide.js
Normal file
@@ -0,0 +1,44 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
14
app/assets/javascripts/directives/functional/elemReady.js
Normal file
14
app/assets/javascripts/directives/functional/elemReady.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* @ngInject */
|
||||
export function elemReady($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, elem, attrs) {
|
||||
elem.ready(function() {
|
||||
$scope.$apply(function() {
|
||||
var func = $parse(attrs.elemReady);
|
||||
func($scope);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
16
app/assets/javascripts/directives/functional/file-change.js
Normal file
16
app/assets/javascripts/directives/functional/file-change.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* @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 });
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
9
app/assets/javascripts/directives/functional/index.js
Normal file
9
app/assets/javascripts/directives/functional/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export { autofocus } from './autofocus';
|
||||
export { clickOutside } from './click-outside';
|
||||
export { delayHide } from './delay-hide';
|
||||
export { elemReady } from './elemReady';
|
||||
export { fileChange } from './file-change';
|
||||
export { infiniteScroll } from './infiniteScroll';
|
||||
export { lowercase } from './lowercase';
|
||||
export { selectOnClick } from './selectOnClick';
|
||||
export { snEnter } from './snEnter';
|
||||
@@ -0,0 +1,17 @@
|
||||
/* @ngInject */
|
||||
export function infiniteScroll($rootScope, $window, $timeout) {
|
||||
return {
|
||||
link: function(scope, elem, attrs) {
|
||||
const offset = parseInt(attrs.threshold) || 0;
|
||||
const e = elem[0];
|
||||
elem.on('scroll', function() {
|
||||
if (
|
||||
scope.$eval(attrs.canLoad) &&
|
||||
e.scrollTop + e.offsetHeight >= e.scrollHeight - offset
|
||||
) {
|
||||
scope.$apply(attrs.infiniteScroll);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
19
app/assets/javascripts/directives/functional/lowercase.js
Normal file
19
app/assets/javascripts/directives/functional/lowercase.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/* @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]);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/* @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);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
14
app/assets/javascripts/directives/functional/snEnter.js
Normal file
14
app/assets/javascripts/directives/functional/snEnter.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* @ngInject */
|
||||
export function snEnter() {
|
||||
return function(scope, element, attrs) {
|
||||
element.bind('keydown keypress', function(event) {
|
||||
if (event.which === 13) {
|
||||
scope.$apply(function() {
|
||||
scope.$eval(attrs.snEnter, { event: event });
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user