Angular Bootstrap Modal Add Directive - javascript

I have an Angular application which contains a simple timer that resets on a mousemove event. So far I have been able to handle this by adding the ng-mousemove event to my outer most scope. However, when a Angular Bootstrap Modal appears, it is positioned in the DOM after that scope, so the event gets ignored until the modal is closed.
My current application is structured as follows:
<!DOCTYPE html>
<html ng-app="app">
<head>
...
</head>
<body>
<div data-ng-controller="shell as vm">
<div ng-mousemove="vm.handleMouseMove()">
...
</div>
// MODAL APPEARS DOWN HERE
<div tabindex="-1" role="dialog" class="modal fade ng-isolate-scope warning in" ...>
</div>
</body>
</html>
Is there a way to:
a.) Add the ng-mousemove directive to the modal wrapper
or
b.) Move the modal into my scope, so that shell is a parent to the modal controller.

Not sure why you need that timer reset behaviour but you could do it like this.
Add your shell controller and ng-mousemove to the body-tag and style your body/html to fill the whole page with css width: 100%; height:100%.
Please have a look at the demo below and this jsfiddle.
var app = angular.module('myApp', ['ui.bootstrap']);
app.controller('shell', function($scope, $interval, $modal) {
$scope.test = 'hello world';
this.counter = 0;
var vm = this;
this.moveHandler = function() {
console.log('mouse moved, reset counter!');
vm.counter = 0;
};
var timer = function(iterCount) {
console.log('timer tick', vm.counter);
vm.counter++;
};
var intervalPromise = $interval(timer, 100);
$scope.$on("$destroy", function handler() {
// destruction code here
$interval.cancel(intervalPromise); // stop interval on destroy of ctrl.
});
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
});
// modal code from angular-ui-bootstrap demo
app.controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
html, body {
width: 100%;
height: 100%;
}
<script src="https://code.angularjs.org/1.3.1/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<body class="wrapper" ng-app="myApp" ng-controller="shell as vm" ng-mousemove="vm.moveHandler()">
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="open()">Open me!</button>
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
{{test}}
</div>
</body>

Related

bootstrap modal backdrop is not getting removed while routing in angularjs [duplicate]

I'm using AngularUI to integrate Bootstrap components in my Angular 1.4 app, such as Modals.
I'm calling a Modal in my controller like so:
var modalInstance = $modal.open({
animation: true,
templateUrl: '/static/templates/support-report-modal.html',
controller: 'ModalInstanceCtrl'
});
Unfortunately, when I want to close the Modal by using:
modalInstance.close();
The modal itself dissapears, and the backdrop also fades out, but it isn't removed from the DOM, so it overlays the whole page leaving the page unresponsive.
When I inspect, I'm seeing this:
In the example in the Documentation on https://angular-ui.github.io/bootstrap/#/modal The class modal-open is removed from body and the whole modal-backdropis removed from the DOM on close.
Why is the Modal fading out but the backdrop not removed from the DOM in my example?
I've checked out many of the other questions about the backdrop of bootstrap Modals but I can't seem to figure out what's going wrong.
This is apparently due to a bug. AngularUI doesn't support Angular 1.4 yet. Once http://github.com/angular-ui/bootstrap/issues/3620 is resolved this will work.
Until the team gets this sorted here is a work around.
<div class="modal-footer">
<button class="btn btn-primary"
ng-click="registerModal.ok()"
remove-modal>OK</button>
<button class="btn btn-warning"
ng-click="registerModal.cancel()"
remove-modal>Cancel</button>
</div>
/*global angular */
(function () {
'use strict';
angular.module('CorvetteClub.removemodal.directive', [])
.directive('removeModal', ['$document', function ($document) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.bind('click', function () {
$document[0].body.classList.remove('modal-open');
angular.element($document[0].getElementsByClassName('modal-backdrop')).remove();
angular.element($document[0].getElementsByClassName('modal')).remove();
});
}
};
}]);
}());
Unfortunately it appears that the team is not on the same page concerning this issue as it was pushed to a separate thread by a contributor and then the thread it was pushed to was closed by another as it was considered "off topic" by another.
Simply you can do like this, first close the modal u have opened
$('#nameOfModal').modal('hide');
basically id of modal Second this to remove if any
$('body').removeClass('modal-open');
lastly to close backdrop
$('.modal-backdrop').remove();
<button type="button" class="close" onclick="$('.modal-backdrop').remove();"
data-dismiss="modal">
$(document).keypress(function(e) {
if (e.keyCode == 27) {
$('.modal-backdrop').remove();
}
});
I am using Angular version 1.3.13 and have a similar issue. I been researching the problem and believe this bug extends from angular version 1.3.13 to 1.4.1 details here https://github.com/angular-ui/bootstrap/pull/3400
And if you scroll to the bottom of that link you will see a post by fernandojunior showing the versions he tested and upgraded to still showing the same issue. He even created a plnker to simulate the issue http://plnkr.co/edit/xQOL58HDXTuvSDsHRbra and I've simulated the issue in the code snippet below using the Angular-UI modal code example.
// angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular
.module('ui.bootstrap.demo', [
'ngAnimate',
'ui.bootstrap',
]);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.animationsEnabled = true;
$scope.open = function (size) {
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.toggleAnimation = function () {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<!-- angular 1.4.1 -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.js"></script>
<!-- angular animate 1.4.1 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-animate.min.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="open()">Open me!</button>
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
<button class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
In you submit button or which ever button/selection that moves you to another page, just have data-dismiss="modal" and that should take care of the back drop. It is just telling to dismiss the modal when you have made your selection.
I am also using Angular 1.3.0 and I am also using UI bootstrap-tpls-0.11.2 and for some reason my issue was happening when I was redirecting to the new page and the backdrop was still displaying, so I ended up adding this code...
.then(function () {
$("#delete").on('hidden.bs.modal', function () {
$scope.$apply();
})
});
which I actually found here....
Hide Bootstrap 3 Modal & AngularJS redirect ($location.path)

Modal form not opening on click

I have the following angular html in an attempt to open a modal form on clicking a button. The code creates the button just fine but on click it doesn't do anything.
Why is the button not opening the form?
var myMod = angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function() {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function() {
return $scope.items;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
var ModalInstanceCtrl = function($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function() {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<h1>GWAT Websites and Designs</h1>
<button class="btn" ng-click="open()">Submit new post</button>
</div>
I made these changes:
include <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
add ng-app="plunker"
register controllers: myMod.controller('ModalDemoCtrl', ModalDemoCtrl);
myMod.controller('ModalInstanceCtrl', ModalInstanceCtrl);
Add <p>Selected: {{selected}}</p> to view selected item from modal
Change $modal to $uibModal and $modalInstance to $uibModalInstance
var myMod = angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function($scope, $uibModal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function() {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function() {
return $scope.items;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
var ModalInstanceCtrl = function($scope, $uibModalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function() {
$uibModalInstance.close($scope.selected.item);
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
};
myMod.controller('ModalDemoCtrl', ModalDemoCtrl);
myMod.controller('ModalInstanceCtrl', ModalInstanceCtrl);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<div ng-app='plunker' ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<h1>GWAT Websites and Designs</h1>
<p>Selected: {{selected}}</p>
<button class="btn" ng-click="open()">Submit new post</button>
</div>

cancel button not working when editing a ng-repeat item (in a modal) using angular copy

I have created a ng-repeat of blocks where I would like to edit a block in a modal window and cancel the window to discard any changes.
I have managed to get the modal window working and editing blocks as I want however I am trying to use angular.copy to create a backup of the original element and set it when cancel is clicked.
here is my html for my ng-repeat:
<div class="container" style="max-width: 600px;">
<div ng-repeat="block in blocks" class="text-muted" ng-drop="true" ng-drop-success="onDropComplete($index, $data ,$event)">
<div class="row" ng-show="textBlock(block)" ng-click="showEditButtons()" ng-drag="true" ng-drag-data="block">
<h4> {{ block.title }} </h4>
<p> {{ block.body }} </p>
<button class="btn btn-default" ng-show="showButtons" ng-click="editBlock(block); modalUpdate(block)">Edit!</button>
<button class="btn btn-default" ng-show="showButtons" ng-click="deleteBlock(block)">Delete!</button><br>
<br>
</div>
</div>
</div>
and here is my html for the modal:
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<form class="form-group">
<input class="form-control" placeholder="Title" type="text" ng-model="block.title" ng-model="titleText"/>
<input class="form-control" placeholder="Main Body" type="text" ng-model="block.body" ng-model="bodyText"/>
<button class="btn btn-success" type="submit" ng-click="saveBlock()"> Save </button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</form>
</div>
</script>
and here is the modal part of the controller:
$scope.modalUpdate = function (selectedBlock) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: function($scope, $uibModalInstance, block){
$scope.backUp = angular.copy(block);
$scope.block = block;
$scope.saveBlock = function () {
$uibModalInstance.close($scope.block);
};
$scope.cancel = function () {
block = $scope.backUp;
$uibModalInstance.dismiss('cancel');
};
},
size: 'sm',
resolve: {
block: function () {
return selectedBlock;
}
}
});
};
However every time I click cancel the changes to the block are still saved and nothing is reverted.
Any help would be awesome!
Try to remove the line
$scope.cancel = function () {
// block = $scope.backUp; <--- this one
$uibModalInstance.dismiss('cancel');
};
controller: function($scope, $uibModalInstance, block){
$scope.backUp = angular.copy(block);
$scope.block = block;
// the above line does not create new instance of $scope.block instead links to block, so whenever $scope.block gets updated, block also gets updated
Change Your code as :
HTML :
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<form class="form-group">
<input class="form-control" placeholder="Title" type="text" ng-model="data.title" ng-model="titleText" />
<input class="form-control" placeholder="Main Body" type="text" ng-model="data.body" ng-model="bodyText" />
<button class="btn btn-success" type="submit" ng-click="saveBlock()"> Save </button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</form>
</div>
</script>
Have changed ng-model to bind to data object
JS :
$scope.modalUpdate = function (selectedBlock) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: function ($scope, $uibModalInstance, block) {
$scope.data = {};
$scope.data.title = block.title;
$scope.data.body = block.body;
$scope.saveBlock = function () {
block.title = $scope.data.title;
block.body = $scope.data.body;
$uibModalInstance.close($scope.block);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
size: 'sm',
resolve: {
block: function () {
return selectedBlock;
}
}
});
};
Have assigned to $scope.block only if saveBlock is triggered otherwise nothing happens on cancel

Ionic popup template for username and password

I am using ionic to make a mobile app.I want to use a popup window to collect two pieces of data, a username and a password. I looked through a lot of website, it only shows how popup window can collect one piece of data, but not two. Also, I would like to make the popup window a purple color. How can I do that?
$scope.create = function() {
$scope.data = {};
// An elaborate, custom popup
var myPopup = $ionicPopup.show({
template: '<input type="password" ng-model="data.one">',
style: 'background-color:purple;',
title: 'Enter Wi-Fi Password',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>Save</b>',
type: 'button-balanced',
onTap: function(e) {
if ((!$scope.data.one)&&(!$scope.data.two)) {
e.preventDefault();
} else {
return $scope.data;
}
}
}
]
});
}
You can achieve this using $ionicModal
Here is a working example
HTML
<script id="add-or-edit-cart.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar>
<h1 class="title">{{ action }} Page</h1>
<div class="buttons">
<button ng-click="deleteCart()" class="button button-icon icon ion-close"></button>
</div>
</ion-header-bar>
<ion-content>
<div class="list list-inset">
<label class="item item-input">
Dummy Text
</label>
</div>
</ion-content>
</ion-modal-view>
</script>
Add ng-click to the View cart present in the footer
<ion-footer-bar class="bar-footer btn-footer bar-light">
<div class="row">
<div class="col">
<button ng-click="vm.showCart()" ng-controller="OverviewController as vm" class="button button-block button-positive"> View cart Page </button>
</div>
<div class="col">
<button class="button button-block button-calm"> View checkout page </button>
</div>
</div>
</ion-footer-bar>
JS
Add the Following Controller
.controller('OverviewController', function ($scope, $ionicModal) {
var vm = this;
$ionicModal.fromTemplateUrl('add-or-edit-cart.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function (modal) {
$scope.modal = modal;
});
vm.showCart = function () {
$scope.Cart = {};
$scope.action = 'Cart';
$scope.isAdd = true;
$scope.modal.show();
};
$scope.deleteCart = function () {
$scope.modal.hide();
};
$scope.$on('$destroy', function () {
$scope.modal.remove();
});
return vm;
and here is working CodePen

Alert box with a <select> in it

I'd like to ask the user to choose among a few possibility but without breaking the style of my page. So I'd like to prompt an alert box or something like that BUT with a dropdown list () in it.
Is it possible?
If so how?
According to the documentation
Official Example
Add angular-bootstrap.js in your project, and 'ui.bootstrap' in your module
in HTML
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="open()">Open me!</button>
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
JS
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};

Categories

Resources