Bootstrap 3 provides Bootstrap: event messages: success, info, warning, danger
.
However sometimes the view doesn\'t have enough space to show up
I've made a service and controller which depends of eachother:
.service('AlertService', function($uibModal){
/*
headerText - presents text in header
bodyText - presents text in body
buttonText - presents text in button. On its click if method parameters is not passed, modal will be closed.
In situation that the method parameters is passed, on its click, method will be called. For situations
like that, there is parameter buttonText2 which will be used as cancel modal functionality.
method - presents passed function which will be called on confirmation
buttonText2 - presents text in button for cancel
*/
var alert = function(headerText, bodyText, buttonText, method, buttonText2){
method = method || function(){};
buttonText2 = buttonText2 || '';
$uibModal.open({
animation: true,
templateUrl: '/static/angular_templates/alert-modal.html',
controller: 'AlertModalInstanceCtrl',
size: 'md',
resolve: {
headerText: function () {
return headerText;
},
bodyText: function () {
return bodyText;
},
buttonText: function () {
return buttonText;
},
method: function () {
return method;
},
buttonText2: function () {
return buttonText2;
}
}
});
};
return{
alert: alert
};
})
.controller('AlertModalInstanceCtrl', function ($scope, $uibModalInstance, headerText, bodyText, buttonText, method, buttonText2) {
$scope.headerText = headerText;
$scope.bodyText = bodyText;
$scope.buttonText = buttonText;
$scope.method = method;
$scope.buttonText2 = buttonText2;
$scope.ok = function () {
$scope.method();
$uibModalInstance.dismiss('cancel');
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
and html file:
<!--Modal used for alerts in AlertService-->
<div class="modal-header">
<h3 class="modal-title">{[{ headerText }]}</h3>
</div>
<div class="modal-body">
<p>{[{ bodyText }]}</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" ng-click="cancel()" ng-if="buttonText2">{[{ buttonText2 }]}</button>
<button class="btn btn-primary" ng-click="ok()">{[{ buttonText }]}</button>
</div>
Now, depending for what type you want to use it, you have a few options: -If you pass headerText, bodyText and buttonText, it will behave like a classic alert modal
AlertService.alert('Some header', 'Some message', 'Text button');
-If you pass headerText, bodyText, buttonText and method, it will behave like a classic alert modal but with the function which you can pass and later handle in the controller
AlertService.alert('Are you sure?', 'Are you sure you want to create this round', 'Ok', $scope.createRound);
$scope.createRound = function(){
//do something
}
-And the last one. If you pass all the parameters, it will act like the previous one, just with the possibility to cancel and close modal.
AlertService.alert('Are you sure?', 'Are you sure you want to create this round', 'Ok', $scope.createRound, 'Cancel');
$scope.createRound = function(){
//do something
}
Of course, if you want to use this, you'll have to inject angular ui bootstrap. I wasted a lot of time to develop this, but it worth. It was annoying to create every time a new controller, new template and all the other things.
From the controller then you can easily use it, just inject it first.
Thanks for answering your own question, it was helpful.
Here's a version as a service you can wire in and fire off from any controller without needing to include directive mark-up.
It uses the latest angular UI Bootstrap paradigm for modals.
It has some convenience methods (info, error, warn, success).
It fires off an event when closed with the data as an event argument in case you need to know that.
Enjoy!
angular.module('modal.alert.service', [], function ($provide) {
'use strict';
$provide.factory('ModalAlertService', ['$rootScope', '$uibModal',
function ($rootScope, $uibModal) {
var factory = {
alert: function(mode, title, text) {
var modalData = {
mode : mode,
title : title,
text : text
};
var modalInstance = $uibModal.open({
template: '<div class="modal-body" style="padding:0px">' +
'<div class="alert alert-{{data.mode}}" style="margin-bottom:0px">' +
'<button type="button" class="close" data-ng-click="close()" >' +
'<span class="glyphicon glyphicon-remove-circle"></span>' +
'</button><strong>{{data.title}}</strong>: {{data.text}}</div></div>',
controller : 'ModalAlertController',
backdrop : true,
keyboard : true,
backdropClick : true,
size : 'lg',
resolve : {
data : function() {
return modalData;
}
}
});
modalInstance.result.then(function(data) {
$rootScope.$broadcast('modal-alert-closed', { 'data' : data });
});
},
info: function(title, text) {
factory.alert('info', title, text);
},
error: function(title, text) {
factory.alert('danger', title, text);
},
warn: function(title, text) {
factory.alert('warning', title, text);
},
success: function(title, text) {
factory.alert('success', title, text);
}
};
return factory;
}]);
}).controller('ModalAlertController', function ($scope, $uibModalInstance, data) {
$scope.data = data;
$scope.close = function() {
$uibModalInstance.close($scope.data);
};
});
I'll answer on my own question.
The flow is pretty simple and straightforward. We don't reinvent the wheel here.
We don't need nor header neither footer:
Dialog template HTML:
<div class="modal-body" style="padding:0px">
<div class="alert alert-{{data.mode}}" style="margin-bottom:0px">
<button type="button" class="close" data-ng-click="close()" >
<span class="glyphicon glyphicon-remove-circle"></span>
</button>
<strong>{{data.boldTextTitle}}</strong> {{data.textAlert}}
</div>
</div>
We even don't need to use ng-class
:
class="alert-{{data.mode}}"
where mode might be: success, info, warning, danger
Modal Instance Controller:
var ModalInstanceCtrl = function ($scope, $modalInstance, data) {
$scope.data = data;
$scope.close = function(/*result*/){
$modalInstance.close($scope.data);
};
};
And this is modal configuration and content:
$scope.data = {
boldTextTitle: "Done",
textAlert : "Some content",
mode : 'info'
}
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
backdrop: true,
keyboard: true,
backdropClick: true,
size: 'lg',
resolve: {
data: function () {
return $scope.data;
}
}
});
Demo Plunker
Demo 2 Plunker
We can put all above written code into directive for better maintenance:
HTML
<button class="btn btn-success" ng-click="open()" >success
<my-alert
bold-text-title="Done"
text-alert="Some content"
mode="success"
></my-alert>
</button>
Directive
.directive('myAlert', function($modal,$log) {
return {
restrict: 'E',
scope: {
mode: '@',
boldTextTitle: '@',
textAlert : '@'
},
link: function(scope, elm, attrs) {
scope.data= {
mode:scope.mode,
boldTextTitle:scope.boldTextTitle,
textAlert:scope.textAlert
}
var ModalInstanceCtrl = function ($scope, $modalInstance, data) {
console.log(data);
scope.data= {
mode:scope.mode || 'info',
boldTextTitle:scope.boldTextTitle || 'title',
textAlert:scope.textAlert || 'text'
}
};
elm.parent().bind("click", function(e){
scope.open();
});
scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
backdrop: true,
keyboard: true,
backdropClick: true,
size: 'lg',
resolve: {
data: function () {
return scope.data;
}
}
});
modalInstance.result.then(function (selectedItem) {
scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
}
}
};
})
Hope it will save time to someone.