<!DOCTYPE html>
<html ng-app="app">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//code.angularjs.org/1.4.8/angular-sanitize.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<script src="app.js"></script>
<script src="popup.service.min.js"></script>
</head>
<body>
<div ng-controller="appCtrl as vm" class="fluid panel-body">
<h2>Dialoge Box using UI Bootstrap</h2>
<h5>Inspired by <a href="http://ionicframework.com/docs/v1/api/service/$ionicPopup/" target="_blank">Ionic Popup</a></h5>
<div style=" padding-bottom: 10px;">
<strong class="text-danger mark">Launch in full window(or extend size of this window) to see the modal size effect.</strong>
</div>
<div>
<button class="btn btn-info" ng-click="vm.showConfirmWithOptions()">
Complex Confirm
</button>
<button class="btn btn-primary" ng-click="vm.showConfirm()">
Simple Confirm
</button>
<button class="btn btn-success" ng-click="vm.showAlert()">
Alert
</button>
<button class="btn btn-success" ng-click="vm.showAndClose()">
Alert (Close after 2 Sec)
</button>
</div>
<!--<button class="button button-dark" ng-click="vm.showPopup()">-->
<!-- show-->
<!-- </button>-->
<form>
<div class="form-group">
<label for="text1">Message Body </label>
<input type="text" class="form-control" id="text1" ng-model="vm.body">
</div>
<div class="form-group">
<label for="text2">Title </label>
<input type="text" class="form-control" id="text2" ng-model="vm.title">
</div>
<div class="form-group">
<label for="text3">Sub Title </label>
<input type="text" class="form-control" id="text3" ng-model="vm.subTitle">
</div>
<div class="alert alert-success">
All input supports html snippet as well!!
</div>
</form>
<hr>
</div>
</body>
</html>
angular.module('app', ['ngAnimate', 'ui.bootstrap', 'ngSanitize', 'popup'])
.controller('appCtrl', ['$scope', '$injector', appCtrl])
.config(['PopupSvcProvider', function(PopupSvcProvider) { //optionally configure popup svc
PopupSvcProvider.setDefaults({
//okText: 'Dismiss'
});
}]);
function appCtrl($scope, $injector) {
var vm = this;
vm.body = "<span class='text-success'>Hey!!</span>Modal width automatically adjust as per Message body length when you simply pass the string";
vm.title = "Attention!";
vm.subTitle = "You bet";
var PopupSvc = $injector.get('PopupSvc');
vm.showAlert = function() {
var modal = PopupSvc.alert(vm.body);
modal.then(function(response) {
vm.response = response;
});
};
vm.showAndClose = function() {
var modal = PopupSvc.alert(vm.body);
window.setTimeout(modal.close, 2000);
};
vm.showConfirm = function() {
PopupSvc.confirm(vm.body).then(function(response) {
vm.response = response;
});
};
vm.showConfirmWithOptions = function() {
PopupSvc.confirm({
title: vm.title,
subTitle: vm.subTitle,
body: vm.body,
okText: 'Agree',
cancelClass: 'btn-danger'
}).then(function(response) {
vm.response = response;
});
};
}
(function() {
/* popup.service.js by Amitesh Kumar*/
angular.module('popup', [])
.provider('PopupSvc', PopupProviderFunction);
function PopupProviderFunction() {
var DEFAULTS = {
//title, subTitle and body are not a part of configuration
// title: '', // String (optional). The title of the popup.
// subTitle: '', // String (optional). The sub-title of the popup. only applicable when title provided
// body: '', //String or html template to place in the popup body.
okText: 'OK', //text for OK button
okClass: 'btn-info', //class(es) to be added to OK button; e.g 'btn-info btn-small'
cancelText: 'Cancel', //not applicable for alert
cancelClass: 'btn-secondary',
headerClass: 'text-center', //class to be added to bootstrap modal-header
bodyClass: '', //class for bootstrap modal-body
footerClass: '', //class for bootstrap modal-footer
//Below are the three uibModal related properties, see uibModal Bootstrap documentation for details
backdrop: 'static', //Controls presence of a backdrop. Allowed values: true (default), false (no backdrop), 'static' (disables modal closing by click on the backdrop).
keyboard: false, //Indicates whether the dialog should be closable by hitting the ESC key.
size: 'sm', //modal or popup size, default is small
/*NOTE: Below are the app level configuration applicable when input parameter is string. It can be set during angular config phase.
*/
showStringAs: 'body', //it will display the text as modal body(left aligned smaller font text). Other value is 'title' (center aligned h5 element)
enableDynamicSize: true, //show medium size popup when input string extends the below character limit
extendSizeCharLength: 300
};
this.setDefaults = function(userDefaults) {
angular.extend(DEFAULTS, userDefaults);
};
this.$get = ["$uibModal", function($uibModal) {
return new PopupSvc(DEFAULTS, $uibModal);
}];
}
function PopupSvc(DEFAULTS, $uibModal) {
/* jshint -W043 */
var POPUP_TEMPLATE = '\
<div>\
<div class="modal-header" ng-class="vm.headerClass" ng-if="vm.title" style="border:none; padding-bottom: 0;">\
<h3 class="modal-title" ng-bind-html="vm.title"></h3>\
<h5 class="modal-sub-title" ng-bind-html="vm.subTitle" ng-if="vm.subTitle"></h5>\
</div>\
<div class="modal-body" ng-if="vm.body" ng-class="vm.bodyClass">\
<div ng-bind-html="vm.body"></div>\
</div>\
<div class="modal-footer" ng-class="vm.footerClass" style="text-align: center; padding-top: 10px; padding-bottom: 15px; border: none">\
<div xclass="btn-group">\
<button ng-repeat="button in vm.buttons" ng-click="vm.onButtonClick(button, $index)" style="min-width: 70px;" class="btn" ng-class="button.className" ng-bind-html="button.text"></button>\
</div>\
</div>\
</div>';
return {
alert: _alert,
confirm: _confirm
//prompt: _prompt,
//show: _show//generic one which can show multiple buttons
};
function _alert(opts) {
return _showPopup(extend([{
text: opts.okText || DEFAULTS.okText,
className: opts.okClass || DEFAULTS.okClass,
handler: function() {
return true;
}
}], opts || {}));
}
function _confirm(opts) {
return _showPopup(extend([{
text: opts.cancelText || DEFAULTS.cancelText,
className: opts.cancelClass || DEFAULTS.cancelClass,
handler: function() {
return false;
}
}, {
text: opts.okText || DEFAULTS.okText,
className: opts.okClass || DEFAULTS.okClass,
handler: function() {
return true;
}
}], opts || {}));
}
function extend(buttons, userOpts) {
var options = angular.copy(DEFAULTS);
userOpts = userOpts || 'You there?';
if (typeof userOpts === 'string') {
var obj = {};
obj[DEFAULTS.showStringAs] = userOpts;
if (DEFAULTS.enableDynamicSize && userOpts.length > DEFAULTS.extendSizeCharLength) {
obj.size = 'md';
}
userOpts = obj;
}
options.buttons = buttons;
return angular.extend(options, userOpts);
}
function _showPopup(options) {
var modalInstance = $uibModal.open({
template: POPUP_TEMPLATE,
size: options.size,
backdrop: options.backdrop,
keyboard: options.keyboard,
bindToController: true,
controllerAs: 'vm',
controller: ['$injector', 'options', ModelController],
resolve: {
options: function() {
return options;
}
}
});
var obj = modalInstance.result; //returned promise
obj.close = modalInstance.close; //augment close method
return obj;
}
function ModelController($injector, options) {
var vm = this;
sanitizeInput(options);
angular.extend(vm, options);
vm.onButtonClick = function(button, $index) {
var response = button.handler(); //true for alert, true and false for confirm
vm.$close(response);
};
function sanitizeInput(options) {
if ($injector.has('$sanitize')) {
return; //no need to sanitize
}
var $sce = $injector.get('$sce');
options.title = $sce.trustAsHtml(options.title);
options.subTitle = $sce.trustAsHtml(options.subTitle);
options.body = $sce.trustAsHtml(options.body);
options.buttons.forEach(function(button, index, buttons) {
button.text = $sce.trustAsHtml(button.text);
});
}
}
}
})();
/*! popup.service.min.js by Amitesh Kumar - 2017-06-25. Visit https://github.com/amiteshhh/utilities/angular/popup */
!function(){function t(){var t={okText:"OK",okClass:"btn-info",cancelText:"Cancel",cancelClass:"btn-secondary",headerClass:"text-center",bodyClass:"",footerClass:"",backdrop:"static",keyboard:!1,size:"sm",showStringAs:"body",enableDynamicSize:!0,extendSizeCharLength:300};this.setDefaults=function(n){angular.extend(t,n)},this.$get=["$uibModal",function(e){return new n(t,e)}]}function n(t,n){function e(n){return a(s([{text:n.okText||t.okText,className:n.okClass||t.okClass,handler:function(){return!0}}],n||{}))}function o(n){return a(s([{text:n.cancelText||t.cancelText,className:n.cancelClass||t.cancelClass,handler:function(){return!1}},{text:n.okText||t.okText,className:n.okClass||t.okClass,handler:function(){return!0}}],n||{}))}function s(n,e){var o=angular.copy(t);if("string"==typeof(e=e||"You there?")){var s={};s[t.showStringAs]=e,t.enableDynamicSize&&e.length>t.extendSizeCharLength&&(s.size="md"),e=s}return o.buttons=n,angular.extend(o,e)}function a(t){var e=n.open({template:i,size:t.size,backdrop:t.backdrop,keyboard:t.keyboard,bindToController:!0,controllerAs:"vm",controller:["$injector","options",l],resolve:{options:function(){return t}}}),o=e.result;return o.close=e.close,o}function l(t,n){var e=this;!function(n){if(!t.has("$sanitize")){var e=t.get("$sce");n.title=e.trustAsHtml(n.title),n.subTitle=e.trustAsHtml(n.subTitle),n.body=e.trustAsHtml(n.body),n.buttons.forEach(function(t,n,o){t.text=e.trustAsHtml(t.text)})}}(n),angular.extend(e,n),e.onButtonClick=function(t,n){var o=t.handler();e.$close(o)}}var i=' <div> <div class="modal-header" ng-class="vm.headerClass" ng-if="vm.title" style="border:none; padding-bottom: 0;"> <h3 class="modal-title" ng-bind-html="vm.title"></h3> <h5 class="modal-sub-title" ng-bind-html="vm.subTitle" ng-if="vm.subTitle"></h5> </div> <div class="modal-body" ng-if="vm.body" ng-class="vm.bodyClass"> <div ng-bind-html="vm.body"></div> </div> <div class="modal-footer" ng-class="vm.footerClass" style="text-align: center; padding-top: 10px; padding-bottom: 15px; border: none"> <div xclass="btn-group"> <button ng-repeat="button in vm.buttons" ng-click="vm.onButtonClick(button, $index)" style="min-width: 70px;" class="btn" ng-class="button.className" ng-bind-html="button.text"></button> </div> </div> </div>';return{alert:e,confirm:o}}angular.module("popup",[]).provider("PopupSvc",t)}();
# Angular Bootstrap Popup
A simple and elegant angular service inspired by [ionic popup](http://ionicframework.com/docs/v1/api/service/$ionicPopup) to show popup(or dialogue) window for `alert` and `confirm` with custom content and look.
PopupSvc exposes two methods `alert` and `confirm` which takes one parameter either string/html template or an [option](#advance-usage) object for customized look and feel.
These methods returns [promise](https://docs.angularjs.org/api/ng/service/$q) which is resolved when the popup is dismissed. It also returns `close` method to programmatically close it.
## Dependency
[Angular](https://code.angularjs.org/1.5.3/docs/api) (tested on v1.5.3)
[Angular UI Bootstrap](http://angular-ui.github.io/bootstrap/versioned-docs/1.3.3/) (tested on v1.3.3)
> PopupSvc should work fine with any Angular/UI Bootstrap version supporting [ControllerAs](https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/) syntax.
## Demo
Check out the demo at [Plunker](https://plnkr.co/edit/SNhye1/)
## Usage
```javascript
angular.module('myApp', ['popup']);//add popup module dependency
angular.controller('myCtrl', ['PopupSvc', function(PopupSvc){//Inject the PopupSvc service into your controller
//1. Basic Usage
PopupSvc.alert("<strong>Hey!</strong> How you doing");//html string
PopupSvc.confirm("Are you sure?");//normal text
//2. Reacting on popup dismissal/button click
var popup = PopupSvc.alert("Hey! How you doing");
popup.then(function(){
console.log('Alert dismissed');
});
PopupSvc.confirm("Hey! How you doing").then(function(response){
if(response){
console.log('Primary/OK button clicked');
}else{
console.log('Secondary/Cancel button clicked');
}
});
//Programmatically closing the popup using `close` method
//close method must be executed in next tick as popup creation is asynchronous
var popup = PopupSvc.alert("Hey! How you doing");
window.setTimeout(popup.close, 3000);
//3. Customized popup
var popupOption = {//only fewer options here
title: 'Confirm',
subTitle: '<span style="color: red;">Are you sure?</span>',
body: 'Operation can not be reverted',
okText: 'Delete',
okClass: 'btn-danger',
size: 'md'//show a medium size modal popup
};
PopupSvc.confirm(popupOption);
}]);
```
## Install
Download the script file directly from Github and add `script` reference to your html.
Once done, add `popup` module as dependency. Now you can use `PopupSvc` service.
Github Link: https://raw.githubusercontent.com/amiteshhh/utilities/master/angular/popup/popup.service.min.js
## Advance Usage
To have a custom look and feel (e.g button texts etc.) use below option as a parameter to `alert` or `confirm`. All of the option properties are optional. But Of course you will provide value for `body` or `title` to render some text.
> popup is created using bootstrap $uibModal hence there are few properties related to that as well
```javascript
{
title: '', // String. The title of the popup.
subTitle: '', // String. The sub-title of the popup. only applicable when title provided
body: '',//String to place in the popup body.
okText: 'OK',//text for OK button
okClass: 'btn-info',//class(es) to be added to OK button; e.g 'btn-info btn-small'
cancelText: 'Cancel',//not applicable for alert
cancelClass: 'btn-secondary',
headerClass: 'text-center',//class to be added to bootstrap modal-header
bodyClass: '',//class for bootstrap modal-body
footerClass: '',//class for bootstrap modal-footer
//Below are the three uibModal related properties, see uibModal Bootstrap documentation for details
backdrop: 'static',//Controls presence of a backdrop. Allowed values: true (default), false (no backdrop), 'static' (disables modal closing by click on the backdrop).
keyboard: false,//Indicates whether the dialog should be closable by hitting the ESC key.
size: 'sm',//modal or popup size, default is small
/*NOTE: Below are the app level configuration applicable when input parameter is string. It can be set during angular config phase.
*/
showStringAs: 'body',//it will display the text as modal body(left aligned smaller font text). Other value is 'title' (center aligned h5 element)
enableDynamicSize: true,//show medium size popup when input string extends the below character limit
extendSizeCharLength: 300
};
```
> Moreover all applicable string inputs can be `html string` hence you can easily control the style.
## Default Configuration
You can easily configure the default popup option for the application during config phase using `PopupSvcProvider` as below.
However the inline option will still take precedence over app level configuration.
```javascript
angular.module('myApp', ['popup'])
.config(['PopupSvcProvider', function(PopupSvcProvider){
PopupSvcProvider.setDefaults({
okText: 'Dismiss',//Now instead of 'OK' popup will show button with text 'Dismiss'
okClass: 'btn-primary',
cancelText: 'Close',
keyboard: true//popup can be closed now with ESC key.
});
}]);
```
## License
MIT