I will enter username and password in text field but I will not save. Without saving that data i will close the popup modal.
When I click outside of the modal, it will close.
If I open the popup again, the previous datas are still appearing. I need to clear those datas and want to make the field as empty.
Please check the following link. Plunkr
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.user = {
user: 'name',
password: null,
notes: null
};
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
}; // end of scope.open function
};
<!doctype html>
<html ng-app="plunker">
<head>
<script src="https://code.angularjs.org/1.2.18/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<form ng-submit="submit()">
<div class="modal-body">
<label>User name</label>
<input type="text" ng-model="user.user" />
<label>Password</label>
<input type="password" ng-model="user.password" />
<label>Add some notes</label>
<textarea rows="4" cols="50" ng-model="user.notes">
</textarea>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<input type="submit" class="btn primary-btn" value="Submit" />
</div>
</form>
</script>
<button class="btn" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
The problem is, you are actually binding the $scope.user in modal to the $scope.user from the ModalDemoCtrl. To solve this, you should make a copy of your user before using it in the modal controller:
$modal.open({
...
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = angular.copy(user);
...
}
});
See Angular.copy() documentation.
see Clear the form after submit angularjs for how to clear the form. you can trigger this in your submit function before the modal closes.
You can do that with ui bootstrap promise:
$scope.modal.result.then(function(result) {
console.log('client: resolved: ' + result);
}, function(reason) {
console.log('client: rejected: ' + reason);
});
I had run your code and it worked fine.
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.user = {
user: 'name',
password: null,
notes: null
};
$scope.open = function () {
var $theModal = $modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
$theModal.result.then(function(result) {
console.log('client: resolved: ' + result);
}, function(reason) {
$scope.user = {}
console.log('client: reject: ' + reason);
})
}; // end of scope.open function
};
Related
I have a model controller like such:
pcApp.controller("ModalInstanceController", function ($scope, $modalInstance, model) {
$scope.claim = model;
$scope.payNow = function () {
$modalInstance.close("now");
};
$scope.refuse = function () {
$modalInstance.close("later");
};
$scope.payLater = function () {
$modalInstance.dismiss("cancel");
};
});
The modal template is:
<script type="text/ng-template" id="newClaimPopup.html">
<div class="modal-header">
<h3 class="desktop">PayCaddy Claim</h3>
</div>
<div class="modal-body">
<p>{{claim.SenderFullName}} is claiming an amount of R{{claim.Amount}} for a golfing bet with him that you lost, with the message:</p>
<br />
<p>{{claim.Description}}</p>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="payNow()">Yes</button>
<button class="btn btn-danger" type="button" ng-click="refuse()">Refuse</button>
<button class="btn btn-warning" type="button" ng-click="payLater()">Later</button>
</div>
</script>
This is in a partial view included in _Layout.cshtml:
<div id="claim-notice-template">
#Html.Partial("_NewClaimPopupTemplate")
</div>
I show the modal using this code:
$scope.showNewClaimPopup = function (viewModel) {
$scope.claim = viewModel;
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: "newClaimPopup.html",
controller: "ModalInstanceController",
size: "sm",
resolve: {
model: function () {
return $scope.claim;
}
}
});
modalInstance.result.then(function () {
debugger;
$log.info("Modal accepted at: " + new Date());
}, function () {
$log.info("Modal dismissed at: " + new Date());
});
};
The viewModel parameter passed in to $scope.showNewClaimPopup is valid and fully populated. The resolve option for open is also working, because in ModalInstanceController I can see that the model parameter is the same valid viewmodel. Yet when the modal displays, the binding templates are all blank.
All code shown is in one MainController assigned to a div that surrounds everything, including the partial containing the modal template.
Why is the template not binding as expected?
You need to pass $scope to be used to compile modal template:
var modalInstance = $modal.open({
scope: $scope, // <--- this line is necessary
animation: $scope.animationsEnabled,
templateUrl: "newClaimPopup.html",
controller: "ModalInstanceController",
size: "sm",
resolve: {
model: function () {
return $scope.claim;
}
}
});
If you don't provide scope config then modal will create new child scope of the $rootScope, which obviously doesn't contain claim object.
I've a question to my problem. I'm using on each page an info button who's opening when you click on it. For the modal window I'm using an own defined service who's giving the values to the controller of the modal window. For each page exists an different info message and I want to use only one View for all info messages. But only the message for the corresponding page should be displayed. How can I define this?
Here is a code of Home view Info btn:
<button type="button" class="btn pull-right" ng-click="msgBtn()">
click on info
</button>
The same code is in Person view.
How can I tell the modalCtrl that the msgBtn() was clicked on Person view and give me the message of person info?
Here is my solution example:
//First the HomeCtrl:
$scope.info = function (message) {
modalService.infoDia(message);
};
//HomeView:
<button type="button" class="btn" ng-click="info('Home')">
Click Info
</button>
//PersonCtrl:
$scope.info = function (message) {
modalService.infoDia(message);
};
//PersonView:
<button type="button" class="btn" ng-click="info('Person')">
Click Info
</button>
//infoDia Service:
...
return {
infoDia: function (message) {
return $modal.open({
templateUrl: 'info.html',
controller: function ($scope, params) {
$scope.message = params.message;
},
resolve: {
params: function () {
return {
message: message;
}
}
}
});
}
}
//ModalView:
...
<div class="modal-body">
<p ng-if="message == 'Home'">
This is the home information dialog.
</p>
<p ng-if="message == 'Person'">
This is the person information dialog.
</p>
</div>
...
You can have a property named something like infoMsg in both homeCtrl and personCtrl and access it in you modal view using {{infoMsg}}. But this will force you to add infoMsg property to each of your controllers scope whereever you are going to use the modal. Better you can have your home and person controllers pass the message string to the modal controller through the service. This will reduce coupling and will give your code more flexibility. This is all I can tell without seeing your code.
If you just want to show a message then this is pretty easily achieved. To put #ankur's answer in a form of code, it could be something like below.
Have a Info service, taking message as a parameter.
app.factory('Info', function($modal) {
return {
show: function(message) {
$modal.open({
templateUrl: 'info-modal-template.html',
controller: function($scope, params) {
$scope.message = params.message;
},
resolve: {
params: function() {
return {
message: message
};
}
}
});
}
};
});
Then inject and call it from within your HomeCtrl.
app.controller('HomeCtrl', function(Info) {
var vm = this;
vm.info = function(message) {
Info.show(message);
};
});
Where HTML template is simply.
<div ng-controller="HomeCtrl as vm">
<button type="button"
class="btn btn-default"
ng-click="vm.info('Home message')">
Home button
</button>
</div>
Answer to your new question posted as an answer.
// Home
app.controller('HomeCtrl', function($scope, modalService) {
$scope.info = function() {
modalService.infoDia('Home');
};
});
<button type="button" class="btn" ng-click="info()">Click Info</button>
// Person
app.controller('PersonCtrl', function($scope, modalService) {
$scope.info = function() {
modalService.infoDia('Person');
};
});
<button type="button" class="btn" ng-click="info()">Click Info</button>
// Service
app.factory('modalService', function($modal) {
return {
infoDia: function(message) {
return $modal.open({
templateUrl: 'info.html',
controller: function($scope, params) {
$scope.message = params.message;
},
resolve: {
params: function() {
return {
message: message
};
}
}
});
}
};
});
<div class="modal-body">
<p>{{ message }}</p>
</div>
In web application there are a lot of modal template (angular foundation modal). When the modal is opened, we must give controller that are created in the page javascript file. but this controller are generally written inline. I want to get these controller as external or dynamically load.
It is like :
var modalInstance = $modal.open({ templateUrl: 'myModalContent.html',
controller: 'modal-controller.js' })
can it be done? if so, how can I do that this,
thank your helps
Would you try this?
angular.module('foundationDemoApp', ['mm.foundation']);
angular.module('foundationDemoApp').controller('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());
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('foundationDemoApp').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="foundationDemoApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.js"></script>
<script src="//pineconellc.github.io/angular-foundation/mm-foundation-tpls-0.5.1.js"></script>
<script src="example.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/foundation/5.2.0/css/foundation.css" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="small-12.columns">
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<h3>I'm a modal!</h3>
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
<p>Selected: <b>{{ selected.item }}</b></p>
<button class="button" ng-click="ok()">OK</button>
<a class="close-reveal-modal" ng-click="cancel()">×</a>
</script>
<button class="button" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</div>
</div>
use oclazyload
function nameOpen(name){
$ocLazyLoad.load('modal/name.ctrl.js').then(function(){
var modalInstance = $modal.open({
templateUrl: 'modal/name.html',
controller: 'nameCtrl',
controllerAs: 'vm',
resolve: {
phones: function () {
return name;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
//$log.info('Modal dismissed at: ' + new Date());
});
});
}
I have an angular-bootstrap modal that I have created a custom directive for so that the input field will autofocus on open. I have added the directive template to my input tag, but on inspect element, it's nowhere to be seen. Code:
Directive (copied from: How to set focus on input field?)
'use strict';
angular.module('portfolioManager.directives', []).directive('focusMe', function($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function(scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function(value) {
console.log('value=',value);
if(value === true) {
$timeout(function() {
element[0].focus();
});
}
});
// to address #blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function() {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
});
HTML:
<div class='panel-heading report'>
<h1 class='port-title port-manager-header title custom-inline'>Portfolios</h1>
<div ng-controller="ModalCtrl" class='create-new-frame'>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">New Portfolio</h3>
</div>
<form name='eventForm'>
<div class="modal-body">
<input class='form-control' ng-model='portfolios.portName' placeholder='Portfolio name' ng-required='true' maxlength="35" focus-me="shouldBeOpen">
<span class="help-inline" ng-show="notUnique">Portfolio name already used</span>
<br>
<div ng-init="radioModel = 'Right'; portfolios.groupSelection = false" class="btn-group">
<label class="btn btn-primary" ng-model="radioModel" ng-click='portfolios.groupSelection = true' btn-radio="'Left'">Group</label>
<label class="btn btn-primary" ng-model="radioModel" ng-click='portfolios.groupSelection = false' btn-radio="'Right'">Private</label>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok(portfolios.portName)" ng-disabled="eventForm.$invalid || notUnique" id='portfolio-modal-create-button'>Create</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</form>
</script>
<button class="btn btn-sm btn-primary create-new-frame-btn" ng-click="open('sm')">Create New</button>
</div>
</div>
ModalCtrl:
'use strict';
angular.module('portfolioManager').controller('ModalCtrl', 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());
});
};
});
You need to create the modal somehow in your code and trigger it to be displayed. You just defined the template, now you have to use it. See http://angular-ui.github.io/bootstrap/#/modal
Example from the docs:
angular.module('ui.bootstrap.demo').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());
});
};
});
Use the templateUrl attribute to link to your modal template and create a trigger to call open from the UI (for instance: <span ng-click="open()">Open Modal</span>).
I've been playing around with this bug but I can't seem to figure it out. The problem started when I pushed the angular-bootstrap models I had added to the prod server. The original error was this:
"AngularJS Error: Unknown provider: aProvider <- a"
I'm pretty sure I was getting that error because my files weren't minifying correctly. So I went through my controllers and found that I wasn't $injecting $modal instance into my controllers and that's when I ran into this problem.
Whenever I inject $modalInstance into my controller in the minified format I get this error. I am not using the format angular-bootstrap suggests because I have a lot going on and many controllers on the site I'm building so I combined everything into one controller instead of several functions.
My Controller:
.controller('CreateGroupCtrl', ['$scope', '$http', '$window', '$cookies', '$modal', '$log', 'FeedService', '$modalInstance',
function CreateGroupCtrl($scope, $http, $window, $cookies, $modal, $log, $modalInstance, FeedService) {
$scope.createGroupCall = function createGroupCall(teacher, name) {
if(teacher != null && name != null) {
FeedService.createGroupCall($cookies.token, $window.sessionStorage.user, teacher, name).success(function(data) {
console.log('GroupCreated');
}).error (function(status,data,token) {
console.log(status);
console.log(data);
});
} else {
alert("Error!");
}
}
/***********ANGULAR-UI MODAL CODE**********/
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'CreateGroupContent.html',
controller: CreateGroupCtrl,
size: size
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);
My Template:
<button ng-controller="CreateGroupCtrl" ng-click="open()" type="button" id="creategroup" class="btn ns-btn">
<img class="ns-add" src="images/createGroup.png">
<p class="create">Create Group</p>
</button>
<div>
<script type="text/ng-template" id="CreateGroupContent.html">
<div class="modal-header">
<h2 class="modal-title ns-modal-title">Create A Group</h2>
<button class="ns-modal-close" ng-click="cancel()"><img src="images/xCancel.png"></button>
</div>
<div class="modal-body">
<form class="form-signin" role="form">
<input type="text" class="form-control ns-modal-form" placeholder="Teacher" ng-model="create.teacher" required autofocus>
<input type="text" class="form-control ns-modal-form" placeholder="Group Name" ng-model="create.name" required>
</form>
</div>
<div class="modal-footer">
<button class="btn ns-modal-add ns-btn" ng-click="createGroupCall(create.teacher, create.name); ok();" type="submit">Create</button>
</div>
</div>
</script>
</div>
At first, you need to inject all in its order.
Also, you should inject $modal into the controller in which you would like to create your modal view. And the $modalInstance can be injected ONLY into the controller which is used for this $modal window. In your case you use the same controller, so you couldn't inject $modalInstance
Demo: http://plnkr.co/edit/khzNQ0?p=preview
Also, in your case (when you use only 1 controller) - you can pass as object field scope which will be used as parent of $scope for your modal view. By default it is $rootScope, but you can type:
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'CreateGroupContent.html',
controller: CreateGroupCtrl,
size: size,
scope: $scope
});
So now your functions ok() and cancel() will be available in your modal view and modal scope.
Looks like your FeedService and $modalInstance are mixed up. They need to be in the same order.