Calling parent directive method from child directive through attrs - angularjs

This is the scenario :
<export-team>
<ul>
<li>
<button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
</li>
<li>
<button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
</li>
</ul>
</export-team>
The buyTicket directive
(function() {
'use strict';
angular
.module('myApp')
.directive('buyTicket', buyTicket);
/** #ngInject */
function buyTicket($parse, ngDialog, authService, APPCONFIG, $rootScope, shareToken, contestsFactory, shareCurrentTicket, shareIdSession, shareSessionAAMS, $location) {
var vm = this;
var directive = {
restrict: 'A',
link : function(scope, element, attributes) {
var buyCompatible = attributes['buyCompatible'];
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
var buyTicket = function(contest) {
var d = new Date();
var y = d.getFullYear();
var m = addZero(d.getMonth()+1);
var day = addZero(d.getDate());
var h = addZero(d.getHours());
var min = addZero(d.getMinutes());
var s = addZero(d.getSeconds());
var date = ''+y+m+day+h+min+s+'';
var transactionId = $rootScope.TRANSACTIONID;
var currentTOKEN = shareToken.get();
var data = {
idSessione:currentTOKEN, // ->TOKEN
userAgent:navigator.userAgent,
sessioneAAMS:contest.aams_session_id,
gameId:APPCONFIG.GAME_ID,
transactionId:transactionId,
dateTime:date,
buyIn:contest.buy_in
}
var dialogLoading = ngDialog.open({
closeByDocument : false,
closeByEscape : false,
showClose : false,
id : 'ft-modal-loading',
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/loading.html';
$scope.title = 'Acquisto Ticket';
$scope.error = 'Il sistema sta procedendo all\'acquisto del ticket';
}]
});
contestsFactory.buyTicket(data).success(function(response){
dialogLoading.close();
if (response.esito == "0") {
if (!buyCompatible) {
shareCurrentTicket.set(response.ticketSogei);
shareSessionAAMS.set(contest.aams_session_id);
shareIdSession.set(contest.id_session);
$location.path('my-contests/'+contest.id_contest+'/'+contest.contest_status);
}
} else {
var message = response.descrizione;
var ids = ngDialog.getOpenDialogs();
var dialogError = ngDialog.open({
id : "ft-modal-error-2",
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/error.html';
$scope.title = 'Errore';
$scope.error = message;
}]
});
}
})
.error(function(){
var dialogErrorNotEndled = ngDialog.close('ft-modal-loading');
ngDialog.open({
id : 'ft-modal-error',
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/error.html';
$scope.title = 'Errore';
$scope.error = 'Il servizio non è attualmente disponibile';
}]
});
})
}
var openConfirmBuyTicket = function(contest) {
contest = JSON.parse(contest);
if (ngDialog.isOpen('ft-modal-contest-detail')) {
ngDialog.close('ft-modal-contest-detail');
};
if (!authService.isLogged()) {
ngDialog.open({
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/not_logged.html';
$scope.title = 'Spiacenti';
$scope.error = 'Devi essere loggato per poter partecipare ad un contest';
}]
});
} else {
ngDialog.openConfirm({
controller: ['$scope', function($scope){
$scope.title = 'CONFERMA';
$scope.bodyUrl = 'app/components/modals/body/confirm_buy.html';
$scope.contest_name = contest.name_contest;
$scope.buy_in = contest.buy_in;
$scope.currency = APPCONFIG.CURRENCY_SYMBOL;
}],
}).then(function (confirm) {
buyTicket(contest);
}, function(reject) {
});
}
}
element.on('click', function(e){
var contest = attributes['buyTicket'];
openConfirmBuyTicket(contest);
})
}
};
return directive;
}
})();
The export directive
(function() {
'use strict';
angular
.module('myApp')
.directive('exportTeam', exportTeam);
/** #ngInject */
function exportTeam(contestsFactory, ngDialog, APPCONFIG, formatDateFactory) {
var vm = this;
var directive = {
restrict: 'AE',
transclude: true,
controller : function($scope) {
$scope.test = function() {
alert('hey');
}
},
link : function(scope, element, attributes) {
element.on('click', function(e){
var ticket = attributes['exportTeam'];
var id_session = attributes['idsession'];
scope.openExportTeamDialog(ticket, id_session, false);
})
scope.openExportTeamDialog = function(ticket, aams_session_id, afterSave) {
ngDialog.open({
id : 'ft-modal-exportTeam-detail',
className : 'ngdialog ngdialog-theme-default ft-dialog-exportTeam',
controller: ['$scope', 'contestsFactory', 'APPCONFIG', function($scope, contestsFactory, APPCONFIG){
$scope.title = "Aggiungi contest compatibili";
$scope.bodyUrl = 'app/components/modals/body/exportTeam.html';
$scope.contentLoading = true;
$scope.currency = APPCONFIG.CURRENCY_SYMBOL;
$scope.afterSave = afterSave;
$scope.CompatibleContests = [];
contestsFactory.getCompatibleContests(ticket).then(function(response){
angular.forEach(response.data[0], function(item, i){
var multientryOptions = [];
if(item.multientry > 1) {
item.isMultientry = false;
var n = parseInt(item.multientry);
for (i = 1; i <= n; i++) {
multientryOptions.push({
text : i+" team",
value : i
})
}
item.multientryOptions = multientryOptions;
item.multientryOptionSelected = multientryOptions[0];
}else{
item.isMultientry = true;
};
})
$scope.CompatibleContests = response.data[0];
$scope.contentLoading = false;
})
}]
});
}
scope.openExportTeamDialog('N3E94100A725F9QG', 'M3E921013C6DCFCT', false);
}
};
return directive;
}
})();
The buy-ticket directive makes an http call, on the response i want to be able to call the onBuyTicket method of the <export> directive.
I'm trying to understand the best way to do that.
Thanks everyone

This sample show to you how can call an function from your directive
In this sample you can see we just insert data in our directive, and then we handle the data and other action in the directive.
var app = angular.module("app", []);
app.controller("ctrl", function ($scope) {
$scope.dataFromYourController = [
{ name: "Concert Jennifer", value: 200 },
{ name: "007", value: 100 }
];
})
.directive("export", function () {
var template = "<div>" +
"<ul>" +
"<li ng-repeat=\"array in arrays\">" +
"<button ng-click=\"onBuyTicket()\">buy Ticket {{array.name}}</button><hr>" +
"</li>" +
"</ul>" +
"</div>";
return {
restrict: "E",
template: template,
scope: {
data: "="
},
link: function (scope, elem, attrs, ngModel) {
scope.arrays = scope.data;
scope.onBuyTicket = function () {
alert("calling function from directive");
}
}
};
})
<!doctype html>
<html ng-app="app" ng-controller="ctrl">
<head>
</head>
<body>
<h1>call action from your directive</h1>
<export data="dataFromYourController"></export>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>

#eesdil
var directive = {
restrict: 'AE',
transclude: true,
controller : function($scope) {
$scope.onBuyTicket = function() {
alert('hey');
}
}
}
Ho can I call that from the buy-ticket directive ?

Use the $parent
<button buy-ticket="{{data}}" buy-callback="$parent.onBuyTicket()">buy</button>
So the expor directive something like:
var directive = {
restrict: 'AE',
template: '<ng-tansclude></ng-transclude>',
transclude: true,
controller : function($scope) {
$scope.onBuyTicket = function() {
alert('hey');
}
}
}
UPDATED:
see the plunker:
https://plnkr.co/edit/fmyJ4oPLvTiI0TzO7h1b?p=preview
It really depends what you can call and what you cannot based on the scopes... here if you would remove the scope from the export directive would work without the $parent also as export would share the same scope as the parent (main view)

The best way to communicate events from a child directive to a parent directive (or controller) is to use the $emit method of the scope.
What you want to do is take an ng-click event, get additional information with an $http call, and $emit an event with the additional information to be used by your parent directive (or controller).
HTML
<button buy-ticket="data" ng-click="onBuyTicket()">buy</button>
The directive:
angular.module("myApp").directive("buyTicket", function($http) {
function linkFn(scope,elem,attrs) {
scope.onBuyTicket = function() {
var buyData = scope.$eval(attrs.buyTicket);
var url = someFunction(buyData);
$http.get(url).then (function (response) {
var httpData = response.data;
scope.$emit("buyTicket.click", buyData, httpData);
});
};
};
return {
restrict: "AE",
link: linkFn
};
});
In the parent controller:
$scope.$on("buyTicket.click", function (buyData, httpData) {
console.log(buyData);
console.log(httpData);
});
Notice that I used the $eval method to get the data from the variable named by the buy-ticket attribute.
When choosing a name for the event, I recommend including the name of the directive in the event's name. It makes it clear the source of the event and is unlikely to be duplicated elsewhere.

Related

Error: [ng:areq] Argument 'AddInstallationCtrl' is not a function, got Object

i cant find my fail :(
can help me?
in my project i have:
controller principal
define([
"./directives/subscribe",
"./controllers/subscribe",
"./controllers/script",
"angular",
"../models/app.models",
"../login/app.login",
], function (directives, controllers) {
var module = angular.module("app.matrix", ["app.models", "app.login"]).config(['$routeProvider', function ($routeProvder) {
$routeProvder
.when('/matrix', {
templateUrl: 'modules/matrix/templates/main.html',
controller: 'MatrixCtrl'
})
.when('/modals', {
templateUrl: 'modules/matrix/templates/index.html',
controller: 'AddInstallationCtrl'
});
}]);
module = directives.subscribe(module);
return controllers.subscribe(module);
(function () {
"use strict";
var app = angular.module('myApp', [
'ap.lateralSlideMenu',
]);
// service
app.service('number', function () {
return {
isPositive: function (operationPrice) {
return String(operationPrice).indexOf("-") == -1;
}
};
});
})
();
});
controller Secondary
define([
"./matrix",
"./sidebar",
"./script"
], function (matrix, sidebar, script) {
return {
subscribe: function (app) {
app.controller('MatrixCtrl', matrix).controller('SidebarCtrl', sidebar);
app.controller('AddInstallationCtrl', script);
app.directive('sidebarDirective', function () {
return {
link: function (scope, element, attr) {
scope.$watch(attr.sidebarDirective, function (newVal) {
if (newVal) {
element.addClass('show');
return;
}
element.removeClass('show');
});
}
};
});
return app;
}
};
});
Controller Finaly
define(["angular"], function () {
// Code goes here
var app = angular.module('myApp', ['ngAnimate', 'ngSanitize']);
app.config([
'$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
// Angular before v1.2 uses $compileProvider.urlSanitizationWhitelist(...)
}
]);
app.directive('modalDialog', function ($window, $templateCache, $compile, $http) {
return {
restrict: 'EA',
scope: {
show: '=',
modalUser: '=',
saveUser: '&',
templateUser: '#'
},
replace: true, // Replace with the template below
//transclude: true, // we want to insert custom content inside the directive
link: function (scope, element, attrs) {
$http.get(scope.templateUser, { cache: $templateCache }).success(function (tplContent) {
element.replaceWith($compile(tplContent)(scope));
});
scope.dialogStyle = {};
if (attrs.width) {
scope.dialogStyle.width = attrs.width + '%';
scope.dialogStyle.left = ((100 - attrs.width) / 2) + '%';
}
if (attrs.height) {
scope.dialogStyle.height = attrs.height + '%';
scope.dialogStyle.top = ((100 - attrs.height) / 2) + '%';
}
scope.hideModal = function () {
scope.show = false;
};
scope.clone = function (obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
var temp = obj.constructor(); // give temp the original obj's constructor
for (var key in obj) {
temp[key] = scope.clone(obj[key]);
}
return temp;
};
var tempUser = scope.clone(scope.modalUser);
scope.save = function () {
scope.saveUser(scope.modalUser);
scope.show = false;
};
scope.cancel = function () {
scope.modalUser = scope.clone(tempUser);
scope.show = false;
};
}
//template: "<div class='ng-modal' ng-show='show'><div class='ng-modal-overlay'></div><div class='ng-modal-dialog' ng-style='dialogStyle'><div class='ng-modal-close' ng-click='hideModal()'>X</div><div class='ng-modal-dialog-content' ng-transclude></div></div></div>"
//templateUrl: 'my-customer.html'
//templateUrl: scope.templateUser
};
});
app.controller('AddInstallationCtrl', function ($scope, $window) {
$scope.modalShown = false;
$scope.modalShown2 = false;
$scope.user = { name: "Mara", surname: "Sanchez", shortKey: "1111" };
$scope.userMod = {};
$scope.toggleModal = function () {
$scope.modalShown = !$scope.modalShown;
};
$scope.toggleModal2 = function () {
$scope.modalShown2 = !$scope.modalShown2;
};
$scope.saveUser = function (usr) {
$scope.userMod = usr;
$window.alert('Desde metodo SALVAR del controller fuera de la ventana: ' + $scope.userMod.shortKey);
}
});
});
With the first controller I declare that the url: modules / matrix / templates / index.html
It is managed by the AddInstallationCtrl driver
With the second controller I declare that
The application has the AddInstallationCtrl driver
And that the controller is in the variable script
App.controller ('AddInstallationCtrl', script);
In the final controller I declare all the functions that I want to execute the letter
Even there is right, right?
Because when you entered modules / matrix / templates / index.html
Does it tell me that AddInstallationCtrl is not a controller?

read file directive with controller as

I need some help. I build the following directve to translate docx file into html string.
(function(){
'use strict';
angular
.module('app.core')
.directive('uploadFile', uploadFile);
function uploadFile($rootScope, $parse){
var directive = {
restrict: "A",
scope:{result : '='},
controller: 'refertazioneController',
controllerAs: "vm",
link: linkFunction,
};
function linkFunction(scope, element, attrs, controller){
document.getElementById("document")
.addEventListener("change", handleFileSelect, false);
function handleFileSelect(event) {
readFileInputEventAsArrayBuffer(event, function(arrayBuffer) {
mammoth.convertToHtml({arrayBuffer: arrayBuffer})
.then(displayResult)
.done();
});
}
function displayResult(result) {
scope.vm.result = resutl.value;
/* document.getElementById("output").innerHTML = result.value;
var messageHtml = result.messages.map(function(message) {
return '<li class="' + message.type + '">' + escapeHtml(message.message) + "</li>";
}).join("");
document.getElementById("messages").innerHTML = "<ul>" + messageHtml + "</ul>";*/
}
function readFileInputEventAsArrayBuffer(event, callback) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function(loadEvent) {
var arrayBuffer = loadEvent.target.result;
callback(arrayBuffer);
};
reader.readAsArrayBuffer(file);
}
function escapeHtml(value) {
return value
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
};
return directive;
}
})();
the problem is that i'm not able to retrivie the translate string in the controller, defined as follows:
(function(){
'use strict';
angular
.module('app.core')
.controller('refertazioneController', refertazioneController);
function refertazioneController($stateParams, refertationService, $window, examinationService, dataService, $scope){
var vm = this;
vm.prova="refertazioneController";
vm.tinymceModel = '';
vm.sospeso=true;
vm.datiDaRefertare = $stateParams;
vm.paziente = dataService.getPatient(vm.datiDaRefertare.patientId);
examinationService.getPatientExamsDef(vm.datiDaRefertare.patientId).then(function(r){
vm.subjectExam = r.data[0].data;
})
console.log(vm.paziente);
vm.currentUser = sessionStorage;
vm.tinymceOptions = {
onChange: function(e) {
// put logic here for keypress and cut/paste changes
},
inline: false,
slector: 'textarea',
// toolbar: 'undo redo | styleselect | bold italic | link image | print save cancel',
height: 500,
plugins : 'advlist autolink link image lists charmap print preview template save paste',
skin: 'lightgray',
theme : 'modern',
language:'it',
statusbar: false,
templates:[ {title: 'Titolo1', description: 'Descrizione1', content: '<p style="text-align: center;">'+
'<strong>A.S.L. 02 LANCIANO-VASTO-CHIETI</strong>'+
'</p>'},
{title: 'Titolo2', description: 'Secondo referto', url: 'sections/refertazione/referto1.html'}
]
};
vm.html = {};
//vm.html.content = '<p>qui per esempio ci va il template che mi ridà il back end</p><h2>altra roba</h2>';
refertationService.openRefert(1,2);
refertationService.closeRefert(1,2);
refertationService.saveRefert(1,2);
/* vm.testoHtml = "";*/
}
})();
I thought that the line : scope.vm.result = result.value was able to bind the string to my controller and then that i was able to render it in the view as refertazione.result (refertazione is the name of my controller). But this not works, where I'm wrong?
A slightly better pattern that relies on events. You could pull this same pattern off with a scope variable that is two way.
Idea is you use an event to tell the controller data has changed.
function uploadFile($rootScope, $parse) {
var directive = {
restrict: "A",
scope: {},
link: linkFunction,
};
function linkFunction(scope, element, attrs) {
var fn = $parse(attrs.uploadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
console.log(reader);
reader.onload = function(onLoadEvent) {
$rootScope.$broadcast('fileupdate', onLoadEvent.target.result);
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
return directive;
}
Inside of your controller you would listen for the fileupdate event.
//inside your controller:
$scope.$on('fileupdate', showContent);
function showContent(event, $fileContent){
vm.content = $fileContent;
}

Angularjs, Range.insertNode, ngClick : After $compile Angular isn't aware of element - ngClick not working

ngClick is still not responding even after $compile. The new element is being applied to the DOM and is accessible via jQuery and JS. I assume that the issue is with the range.insertNode function. What am I missing here?
Here's my directive:
.directive('selectText', [
'$rootScope',
'$compile',
'$window',
function ($rootScope, $compile, $window) {
return {
restrict: 'A',
scope: {
hlid: "=",
tu: "="
},
link: function (scope, element, attrs) {
element.on('mouseup', function () {
//console.log("Attrs: "+JSON.stringify(attrs));
if ($window.getSelection().toString()) {
var text = $window.getSelection().toString();
if(text == '') {
console.log("No selection");
return;
}
var selection = $window.getSelection();
var range = selection.getRangeAt(0);
var selectionContents = range.extractContents();
var clk = "edSel('hl_"+scope.hlid+"','"+attrs.id+"');";
// var span = $compile(angular.element('<hlight id="hl_'+scope.hlid+'" class="cr-pr noselect clickable" title="Text Selection" ng-click="'+clk+'">'+text+'</hlight>'))(scope);
var span = angular.element($compile('<hlight id="hl_'+scope.hlid+'" class="cr-pr noselect clickable" title="Text Selection" ng-click="'+clk+'">'+text+'</hlight>')(scope));
console.log(span);
range.insertNode(span[0]);
scope.tu.target = element.html();
//selection.removeAllRanges();
var arr = {};
arr.action = 'add';
arr.tuid = attrs.id;
arr.hlid = 'hl_'+scope.hlid;
arr.content = element.html();
scope.$emit('hlChange', arr);
scope.hlid++;
console.log(element.html());
var modal = UIkit.modal("#hl_modal");
modal.show();
}
});
scope.edSel = function(id,tuid) {
console.log('ID: '+id+" - tuID: "+tuid);
}
}
};
}])
Thanks for any help

How to call function in directive from button click

How do I call a function in a directive from a button click? I have been trying and have come up with this (but it is not working):
HTML
<div ng-controller="myMapCTRL as myMapctrl">
<div id="panel">
<input ng-click="updateMap()" type=button value="Remove Path">
</div>
<my-map-with-path id="map-canvas" class="map-canvas" ng-if="dataHasLoaded" ></my-map-with-path>
</div>
Controller
app.controller('myMapCTRL', ['$scope', 'PathService', function($scope, PathService){
//console.log('in controller');
$scope.removed = false;
if(typeof $scope.paths ==='undefined') {
$scope.dataHasLoaded = false;
$scope.center = new google.maps.LatLng(51.5130300, -0.3202410);
PathService.getPaths().then(function(data){
$scope.paths = data;
$scope.dataHasLoaded = true;
//console.log('paths loaded');
});
};
}]);
Directive
app.directive('myMapWithPath', [function() {
return{
restrict: 'AE',
template: '<div></div>',
replace: true,
controller: 'myMapCTRL',
link: function(scope, element, attrs){
//console.log('in link');
scope.updateMap = function() {
console.log('inside updateMap()');
}
var map, path = new google.maps.MVCArray(),
service = new google.maps.DirectionsService(), poly;
//var center = new google.maps.LatLng(51.5130300, -0.3202410);
var myOptions = {
zoom: 15,
center: scope.center,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID,
google.maps.MapTypeId.SATELLITE]
},
disableDoubleClickZoom: true,
scrollwheel: false,
draggableCursor: "crosshair"
}
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
poly = new google.maps.Polyline({ map: map });
for(var i = 0; i < scope.paths['j'].length; i++) {
var lat = scope.paths['j'][i]['k']
var lng = scope.paths['j'][i]['D']
var lat_lng = new google.maps.LatLng(lat, lng);
path.push(lat_lng);
}
poly.setPath(path);
google.maps.event.addListener(map, "click", function(evt) {
if (path.getLength() === 0) {
path.push(evt.latLng);
poly.setPath(path);
} else {
service.route({
origin: path.getAt(path.getLength() - 1),
destination: evt.latLng,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length;
i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
}
});
}
//console.log(path);
});
}
}
}]);
I want to call scope.updateMap from the button click but it is not firing in the console.
This won't work because the ng-click is outside the directive.
You should move the function updateMap to the $scope of myMapCTRL
Having dug around a little more, it seems quite normal to use a shared service to communicate between a controller and a directive.
The general idea is this:
HTML
<div ng-controller="myMapCTRL as myMapctrl">
<div id="panel">
<input ng-click="updateMap()" type=button value="Remove Path">
</div>
<my-map-with-path id="map-canvas" class="map-canvas" ng-if="dataHasLoaded" ></my-map-with-path>
</div>
SharedService
app.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.doSomething = function() {
$rootScope.$broadcast('messageBroadcast');
};
return sharedService;
});
Controller
app.controller('myMapCTRL', ['$scope', 'mySharedService',
function($scope, sharedService){
$scope.updateMap = function() {
sharedService.doSomething();
}
}]);
Directive
app.directive('myMapWithPath', [function() {
return{
restrict: 'AE',
template: '<div></div>',
replace: true,
controller: 'myMapCTRL',
link: function(scope, element, attrs){
scope.$on('messageBroadcast', function() {
console.log('in directive broadcast message');
});
...
}
}
}]);
The idea seems to be that the controller calls a function in the shared service which "broadcasts" a message out. The directive waits for that message and when it is received, it does something amazing.
I am not sure if I need to inject the shared service into the directive or link function but it seems to work without it.

Directive inside $modal window throws "undefined is not a function"

Using ui-bootstrap I have a really simple custom directive that lists alerts at the top of the page. On normal pages it works like a champ. When I use my directive inside a $modal popup I get "undefined is not a function" at ngRepeatAction.
The directive I have behind the modal on the main page still works. I can see it behind the modal. It's just the one in the modal popup that breaks. What am I doing wrong?
Modal open code:
$modal.open({
templateUrl: 'partials/main/servers/serverAuths/edit.html',
controller: function($scope, $modalInstance) {
$scope.auth = angular.copy(auth);
$scope.auth.password = null;
$scope.saveAuth = function() {
Auths.editAuth($scope.auth).then(
function(resp) {
if (resp.rc===0) {
Alerts.addAlert('success', 'Auth `'+$scope.auth.name+'` saved.');
_.extend(auth, $scope.auth);
$modalInstance.close();
} else {
Alerts.addAlert('danger', 'Auth `'+$scope.auth.name+'` could not be saved. ' + resp.message, 'serverAuths');
}
}
);
};
$scope.resetAuth = function() {
$modalInstance.close();
};
}
}).result.then(
function() {
Auths.getAuthList().then(
function(resp) {
$scope.auths = resp;
}
);
}
);
Directive template:
<div class="alert-wrapper alert-{{ alert.type }}"
ng-repeat="alert in alerts"
ng-class="{ 'relative':relative }">
<div class="container">
<div alert type="alert.type" close="closeAlert($index)">{{alert.msg}}</div>
</div>
</div>
Directive code:
angular.module('app')
.directive('appAlerts', function() {
return {
restrict: 'A',
replace: true,
scope: {
watchForm: '=',
relative: '#'
},
templateUrl: 'partials/directives/appAlerts.html',
controller: function($scope, Alerts) {
$scope.closeAlert = function(idx) { Alerts.closeAlert(idx); };
$scope.alerts = Alerts.getAlerts();
}
};
});
Alerts Factory:
angular.module('app').factory('Alerts', function($timeout) {
var alerts = [];
function timeoutAlert(a) {
$timeout(function() {
a.splice(0, 1);
}, 2500);
}
var addAlert = function(type, msg) {
alerts.push({type:type, msg:msg});
timeoutAlert(alerts);
};
var closeAlert = function(index) {
alerts.splice(index, 1);
};
var getAlerts = function() {
return alerts;
};
var killAlert = function(msg) {
var alert = _.where(alerts, {msg:msg});
var idx = _.indexOf(alerts, alert[0]);
if (idx > -1) {
closeAlert(idx);
}
};
return {
addAlert:addAlert,
closeAlert:closeAlert,
getAlerts:getAlerts,
killAlert:killAlert
};
});

Resources