Bootstrap alert message represented as modal, angular
Solution 1
I'll answer on my own question.
Simple way
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
Directive way
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.
Solution 2
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.
Maxim Shoustin
Enthusiastic full-stack developer with a passion for science, architect and team leader. Strong proponent of open licensing. Love helping people Work at AppsFlyer
Updated on July 09, 2022Comments
-
Maxim Shoustin almost 2 years
Bootstrap 3 provides Bootstrap: event messages:
success, info, warning, danger
.However sometimes the view doesn't have enough space to show up the event message.
Is there easy way to wrap event with modal in Angular?
This is a template I started to play with
-
harishr over 9 yearsthanks for it. requesting you to add 2 features: 1) option to make it non blocking, with no fading effect 2) auto close after sometime..
-
harishr over 9 yearsit would be great if you can submit it as a modules on ngmodules.com
-
Anton Dozortsev over 8 years@MaximShoustin Nice alert but how I can open it in JS code just invoking function for example
... myAlert(); ...
? In other words show alert without HTML button -
Maxim Shoustin over 8 years@AntonDozortsev not at all, the modal lays under directive so you can easily grab modal code and call it without directive
-
Anton Dozortsev over 8 years@MaximShoustin But that is a problem I don't want copy mode code all time
-
Maxim Shoustin over 8 years@AntonDozortsev so create somewhere this directive once , add watcher and call some parameter in directive that should trigger watcher and show up the modal
-
Anton Dozortsev over 8 years@MaximShoustin OK. I will try you suggestions. Thanks for all.