@ngal/ui
Version:
Addons for ui.bootstrap
379 lines (311 loc) • 12.1 kB
JavaScript
(function() {
angular.module("ngal.ui", [
"ngAnimate",
"ngSanitize",
"ngTouch",
"ui.bootstrap"
]);
})();
/* eslint-disable indent */
(function() {
"use strict";
var $injector;
var $window;
function Modal(controller, templateUrl) {
this.controller = controller;
this.controllerAs = "vm";
this.templateUrl = templateUrl;
}
Modal.prototype.open = function(config, options) {
var $uibModal;
var modalInstance;
if ($injector.has("$uibModal")) {
$uibModal = $injector.get("$uibModal");
options = angular.extend(options || {}, this, {
backdrop: "static",
resolve: {
config: config
}
});
modalInstance = $uibModal.open(options);
return modalInstance.result; // Promise
}
};
angular
.module("ngal.ui")
.factory("ngal.ui.models.modal",
["$injector", "$window",
function(__$injector__, __$window__) {
$injector = __$injector__;
$window = __$window__;
return Modal;
}])
.directive("uibModalTransclude", [function() {
return {
link: function (scope, elem /*, attrs */) {
if ($window.jQuery)
$window.jQuery(elem).draggable({ handle: ".modal-header" });
},
restrict: "A"
};
}]);
})();
(function() {
"use strict";
function callScriptFn(scope, scriptIn, paramNames) {
if (!(scope && scriptIn))
return undefined;
var matches;
var paramCount;
var parameters;
var paramObject;
var scriptOut;
// Break the scriptIn into three parts:
// All of the characters from the start up to and including the '('
// The characters within the parentheses (the parameters).
// All of the characters from the ')' to the end.
matches = scriptIn.match(/([^(]+\()([^)]*)(\).*)/);
if (!(matches && matches.length === 4))
return undefined;
// Strip all spaces from the parameter list and convert it into an array.
parameters = matches[2].replace(/\s/g, "").split(",");
// Determine the lessor of (1) The number of parameters in the list,
// or (2) The number of expected parameters (from the paramNames.)
paramNames = paramNames || [];
paramCount = Math.min(parameters.length, paramNames.length);
// Build a Javascript object (textual), that has property names for each of the paramNames.
// The right hand side is the corresponding parameter from the scriptIn.
paramObject = paramNames.reduce(function(acc, value, index) {
if (parameters[index]) {
acc += value + ": " + parameters[index];
if (index < paramCount && parameters[1 + index])
acc += ", ";
}
return acc;
}, "{ ");
paramObject += " }";
// Build the script to evaluate; using the constructed paramObject rather than the original parameter list.
// (This is the normal form for a component or directive calling through an attribute.)
scriptOut = matches[1] + paramObject + matches[3];
return scope.$eval(scriptOut);
}
function findParentElem(name, childElem) {
while (childElem && childElem.length) {
if (childElem[0].nodeName === name.toUpperCase())
return childElem;
childElem = childElem.parent();
}
return undefined;
}
angular
.module("ngal.ui")
.factory("ngal.ui.directiveUtil", [function() {
return {
callScriptFn: callScriptFn,
findParentElem: findParentElem
};
}]);
})();
/* eslint-disable quotes */
/* eslint-disable indent */
(function () {
"use strict";
/* config {
buttons: (array of button)
message: (string)
title: (string)
}
button {
cssClass: (string),
label: (string)
}
*/
/*
Example usage:
confirmationModal.open({
title: "Cancel Pending Changes",
message: '<p class="text-danger">You have made changes to the waiting room values. Do you really want to leave the page and lose your changes?</p>',
buttons: [{ cssClass: "btn-warning", label: "Leave"}, { cssClass: "btn-default", label: "Stay" }]
}).then(function(button) {
if (button.label === "Leave") OR (icon.name === "yes-filled")
accept();
});
*/
var TEMPLATE_URL = "/ngal.ui/confirmationModal/confirmationModal.template.html";
var TEMPLATE = '' +
'<div class="allmed-common-ui-confirmation-modal">' +
'<div class="modal-header">' +
'<span ng-bind-html="vm.title"></span>' +
'</div>' +
'<form name="confirmationModalForm" ng-submit="vm.formSubmit(confirmationModal)">' +
'<div class="modal-body">' +
'<p ng-bind-html="vm.message"></p>' +
'</div>' +
'<div class="modal-footer">' +
'<input type="button" class="btn {{ button.cssClass }}" value="{{ button.label }}" ng-click="vm.onTargetClick(button)" ng-repeat="button in vm.buttons">' +
'</div>' +
'</form>' +
'</div>';
var modalController =
["$sanitize", "$uibModalInstance", "config",
function ($sanitize, $uibModalInstance, config) {
var vm = this;
vm.buttons = [];
vm.message = "";
vm.title = "";
vm.onTargetClick = onTargetClick;
init();
function init() {
vm.buttons = config.buttons;
vm.message = $sanitize(config.message);
vm.title = $sanitize(config.title);
}
function onTargetClick(target) {
config.accept(target);
$uibModalInstance.close();
}
}];
angular
.module("ngal.ui")
.factory("ngal.ui.confirmationModal",
["$templateCache", "$q", "ngal.ui.models.modal",
function ($templateCache, $q, Modal) {
if (!$templateCache.get(TEMPLATE_URL))
$templateCache.put(TEMPLATE_URL, TEMPLATE);
var confirmationModal = new Modal(modalController, TEMPLATE_URL);
return {
open: function (confirmationConfig, options) {
return $q(function (accept) {
var config = angular.extend({}, confirmationConfig, { accept: accept });
confirmationModal.open(config, options);
});
}
};
}]);
})();
/* eslint-disable indent */
(function() {
"use strict";
angular
.module("ngal.ui")
.directive("ngalChangeThenLeave",
["ngal.ui.directiveUtil",
function(directiveUtil) {
function link(scope, elem, attrs, ngModelCtrl) {
var formElem;
var privateScope = scope.$root.$new(true);
function onLeave() {
if (privateScope.changed) {
privateScope.changed = false;
directiveUtil.callScriptFn(scope, attrs.ngalChangeThenLeave, ["model"]);
}
}
if (ngModelCtrl) {
ngModelCtrl.$viewChangeListeners.push(function() {
privateScope.changed = true;
});
formElem = directiveUtil.findParentElem("form", elem);
if (formElem) {
formElem.on("submit", function() { onLeave(); });
}
elem.on("blur mouseout", function() { onLeave();});
}
}
return {
link: link,
require: "?ngModel",
restrict: "A",
scope: false
};
}]);
})();
/* eslint-disable quotes */
/* eslint-disable indent */
(function() {
"use strict";
/* criteria:
{
column: (string: The name of the current column that is sorted),
direction: (string: "asc" or "desc"),
onClick: (function(columnName): handler in parent controller)
}
*/
// Note: The name of the column's property is specified by the 'name' attribute.
angular
.module("ngal.ui")
.directive("ngalSortable",
["$compile",
function($compile) {
var template =
'<span>' +
' <i class="fas fa-caret-up" ng-if="ngalSortable.column === name && ngalSortable.direction === \'asc\'" style="line-height: unset"></i>' +
'<i class="fas fa-caret-down" ng-if="ngalSortable.column === name && ngalSortable.direction === \'desc\'" style="line-height: unset"></i>' +
'</span>';
function link(scope, elem/*, attrs*/) {
if (elem[0].nodeName !== "TH") return;
if (scope.noSort) return;
if (!scope.name) throw new Error("name attribute missing or empty.");
// Put click handler on <th>
elem.on("click", function() {
if (angular.isFunction(scope.ngalSortable.onClick))
scope.$applyAsync(function() { scope.ngalSortable.onClick(scope.name); });
});
if (!elem[0].hasAttribute("no-sort-ui") || !scope.noSortUi) {
var element = angular.element(template);
var linkFn = $compile(element);
element = linkFn(scope);
elem.append(element);
}
}
return {
link: link,
restrict: 'A',
scope: {
name: '@',
ngalSortable: '<',
noSort: '<',
noSortUi: '<'
}
};
}]);
})();
/* eslint-disable quotes */
(function () {
"use strict";
var TEMPLATE = '' +
'<div class="ngal-ui-vertical-rolodex">' +
'<div ng-repeat="row in buttons.substr(13)" ng-init="rowIndex = $index">' +
'<span ng-bind="button"' +
'ng-class="{active: button === selectedButton}"' +
'ng-click="onClick(button)"' +
'ng-repeat="button in [buttons[rowIndex], buttons[13 + rowIndex]]">' +
'</span>' +
'</div>' +
'</div>';
angular
.module("ngal.ui")
.directive("verticalRolodex", [function () {
function link(scope, elem, attrs, ngModelCtrl) {
scope.buttons = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
scope.selectedButton = undefined;
scope.onClick = function(button) {
scope.selectedButton = button !== scope.selectedButton ? button : undefined;
if (ngModelCtrl)
ngModelCtrl.$setViewValue(scope.selectedButton);
};
if (ngModelCtrl) {
scope.$watch(function() { return ngModelCtrl.$modelValue; }, function(newValue) {
if (scope.selectedButton !== newValue)
scope.selectedButton = newValue;
});
}
}
return {
link: link,
require: "?ngModel",
restrict: "E",
scope: {},
template: TEMPLATE
};
}]);
})();