Setting checkbox value when modal closes in Angular - angularjs

I am trying to automatically check a checkbox when a modal closes. I am using one controller for the modal and another controller for the main page. The code below isn't working. Do I need to use a directive in order to accomplish this, or is there another way?
HTML - Main Page:
<label>
<input type="checkbox" ng-model="agreementForm.value1"> I agree.
</label>
HTML - Modal:
<div class="modal-footer">
<button ng-click="agreementForm.cancel()" class="btn btn-warning">Cancel</button>
<button ng-click="agreementForm.agree()" ng-disabled="agreementForm.$invalid" class="btn btn-primary" >I agree</button>
</div>
Javascript for Controllers:
myApp.controller('AgreementFormCtrl', function ($location, $stateParams, $modalInstance) {
var agreementForm = this;
agreementForm.cancel = function () {
$modalInstance.dismiss('cancel');
};
agreementForm.agree = function() {
agreementForm.value1=true;
$modalInstance.close(agreementForm.selected);
});
myApp.controller('ContactFormCtrl',
function ($location, $stateParams, Contacts) {
var contactForm = this;
});
contactForm.save = function () {
Contacts.$add(contactForm.contact).then(function (data) {
$location.path('/');
});
};
Router for Modal:
.state('payment.agreement', {
url: '/agreement',
onEnter: ['$stateParams', '$state', '$modal', function ($stateParams, $state, $modal) {
$modal.open({
templateUrl: 'views/agreement.html',
controller: 'AgreementFormCtrl as agreementForm'
}
)
.result.finally(function () {
$state.go('^');
});
}]
})

your can do it by using $rootScope and also you missed to initialzed the $scope
First you need to add ng-checked directive in the checkbox
<input type="checkbox" **ng-checked="agreementForm.IsChecked"**
ng-model="agreementForm.value1"> I agree.
Then you need initialize the rootscope in your controller
myApp.controller('AgreementFormCtrl', function ($location, $stateParams, $modalInstance,**$rootScope,$scope**) {
//code
};
and finally you can assign the value for checked object when a modal closes
$scope.agreementForm.cancel = function () {
$modalInstance.dismiss('cancel');
$rootScope.agreementForm.IsChecked="Checked";//True or false
};

Related

inject scope into angular material modal

I'm trying to open a modal using angular material and inject the scope of the parent, where my data is.
I am attempting to loosely follow the custom/advanced example here:
https://material.angularjs.org/latest/demo/dialog
I do not need the dialog to do anything once closed, so I've eliminated the Dialogcontroller, which seems to only handle 'cancel' and 'answer' upon close. (correct me if I'm wrong here)
The ultimate goal here is to have access to survey in the modal, which is an object in the scope of the parent.
My parent HTML has the review button:
<input type="button" value="Review" ng-click="vm.openReview($event)" />
which triggers the function:
(function () {
appModule
// parent controller
.controller('tenant.views.surveys.index', [
'$scope', 'abp.services.app.survey', '$filter', '$mdDialog',
function ($scope, surveyService, $filter, $mdDialog) {
var vm = this;
vm.openReview = function (ev) {
$mdDialog.show({
//controller: DialogController,// not needed
templateUrl: "/App/tenant/views/surveys/review_modal.html",
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: true
})
//.then(function (answer) {// not needed
// vm.modalStatus = 'You said the information was "' + answer + '".';
//}, function () {
// vm.modalStatus = 'You cancelled the dialog.';
//});
};
// not needed
//function DialogController($scope, $mdDialog) {
// $scope.hide = function() { $mdDialog.hide(); };
// $scope.cancel = function() { $mdDialog.cancel(); };
// $scope.answer = function(answer) { $mdDialog.hide(answer); };
//}
}
])
.
// then the modal controller
.controller('tenant.views.surveys.review', [
'$scope', 'abp.services.app.survey',
function ($scope, surveyService) {
var vmModal = this;
}
]);
})();
Now, in my modal, I have some content:
<div ng-controller="tenant.views.surveys.review as vmModal" class="md-padding dialogdemoBasicUsage" id="popupContainer" ng-cloak="">
<div ng-controller="tenant.views.surveys.review" class="md-padding dialogdemoBasicUsage" id="popupContainer" ng-cloak="">
<md-dialog aria-label="Mango (Fruit)">
<form ng-cloak>
{{vmModal.survey}}
</form>
</md-dialog>
</div>
But I think I'm missing a piece. I don't think vmModal actually contains the scope of the parent. I want access to vmModal.survey.
Do I need to / can I inject the scope directly into the modal controller?

Passing data between modal and controller

How can I make data available in a controller? I have created a really simple Plunk that should show data on the $scope in a modal. I’ll then need to update the data, and only update $scope on clicking “ok”. Clicking “cancel” will discard the changes.
But before I get to that step, I need to make the scope available to the modal. Most of the examples use two controllers. Do I need another controller as in this example: Passing Data to Twitter Bootstrap Modal in Angular? In my controller I have the following:
$scope.open = function(){
var modalInstance = $uibModal.open({
templateUrl: 'modal.html',
controller: 'ModalInstanceController',
resolve: {
users: function() {
return $scope.users;
}
}
});
};
How can I display the users in the template? The plunk is here: http://plnkr.co/edit/FuXjSwtljQtFYOtFRV18?p=preview
To be able to access scope of the controller you need to pass scope object to the modal when creating an instance of it:
$scope.open = function() {
var modalinstance = $uibModal.open({
scope: $scope,
templateUrl: 'modal.html',
resolve: {
users: function() {
return $scope.users;
}
}
})
};
This way Angular will create child scope of the controller $scope so you will be able to access items inside of modals scope:
Demo: http://plnkr.co/edit/0m9oktX2JHFmeiaDfOpO?p=preview
You can access scope in modal -
$scope.open = function(){
var modalinstance = $uibModal.open({
templateUrl: 'modal.html',
scope:$scope
})
};
you can do it with just one controller, is just that is a "dirty" solution, because both html files will share the same controller, which is potentially an issue.
the problem you are facing is that in the modal you don't have a defined scope, so the foreach (ng-repeat) you are doing is not getting any elements
you can fix it easily by changing your modal.html to
<div ng-controller="modalController"><div class="modal-header">
<h3 class="modal-title">Modal</h3>
</div>
<div class="modal-body">
<p>Existing users:</p>
<ul>
<li ng-repeat="user in users">{{user}}</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button">Close</button>
</div>
</div>
as you see, now this modal has a controller (the same as the main window) and so will have a scope
or else just pass the scope to the modal definition adding
var modalinstance = $uibModal.open({
scope: $scope,...
is dirty, and you are "polluting" the scope, but it works :)
Here is some code from my current project it works as expected if you want to use any ng-click on the modal your function has to reside in ModalInstanceController
app.controller('dashboardCtrl', function ($scope, $rootScope, $location, $http, Data, $uibModal ) {
$scope.users = '';
$scope.open = function(){
var modalInstance = $uibModal.open({
templateUrl: 'modal.html',
controller: 'ModalInstanceController',
resolve: {
users: function() {
return $scope.users;
}
}
})
}
});
app.controller('ModalInstanceController', function ($scope, $uibModal, $uibModalInstance, users, $rootScope, $http, Data) {
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
}
$scope.users = users ;
$scope.selected = {
users: $scope.users[0]
};
});

AngularJS $modalInstance - Can i do this in one controller?

I've spent some time having a play with the AngularJS Bootstrap popup, and for intents it's working great, but what i'd like to do is bind it, and it's dependant script to the same controller, what i can't get working is the close button now though. If i create a NEW controller, and inject $modalInstance it works great and i can wireup the close button without any issues at all, but i don't want a second controller, it seems to be over complication: i want all my controller logic in the formController really.
Why would i actually want two controllers? Passing the scope between two controllers just seems overkill to me, and the larger a project becomes the more un-managable it will become. Am i trying to over-simplify this unnecessarily? :)
The script:
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: 'formController'
});
};
$scope.closeModal = function () {
// Code needed here :)
};
})
})();
The HTML body (excuse the HTML in script for the purposes of the DEMO):
<div ng-controller="formController">
<button class="btn btn-default" ng-click="openModal()">Let's do some stuff!</button>
<script type="text/ng-template" id="SomeModal.html">
<div class="modal-header">Do some stuff in this modal y'all.</div>
<div class="modal-footer">
<button class="btn btn-info" ng-click="closeModal()">Close</button>
</div>
</script>
</div>
The answer based on Kaspars' input :)
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal, $log){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: [
'$scope', '$modalInstance', function($scope, $modalInstance){
$scope.closeModal = function () {
$modalInstance.close();
};
}
]
});
};
})
})();
I was struggling with the same problem and the best thing I came up with was to use anonymous function as a modal controller. In that way all the logic is in the same controller and you don't have to create separate controller for each modal window.
This would look like this:
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: [
'$scope', '$modalInstance', 'data', function($scope, $modalInstance, data) {
$scope.data = data;
$scope.ok = function() {
$modalInstance.close();
};
$scope.closeModal = function() {
$modalInstance.dismiss();
};
}
]
});
};
})
})();
PS. Haven't tested code above, just put it together from your provided code and fragments from one of my projects.
You can also try this
var modalInstance = $modal.open({
templateUrl : 'someTemplate.html',
scope : $scope,
size : 'md'
});

Dynamically adding modal information based on button clicked

I'm using AngularUI Modal and AngularUI Router with Bootstrap. I would like to populate the modal title and add an item to the submitted array based on which button a user clicks to initiate the modal. I can statically add this information, but am having trouble figuring out how to add this information dynamically.
[EDIT: Added code for modal below]
Javascript for Controller:
myApp.controller('NewProjectCtrl', function ($scope, $location, $stateParams, Projects, $modalInstance) {
var editProject = this;
editProject.title = 'Modal 1'; // This title should change based on which button is clicked
editProject.save = function () {
editProject.project.type = {type: 'Basic'}; //This item should change based on which button is clicked.
$modalInstance.close(editProject.selected);
Projects.$add(editProject.project).then(function(data) {editProject.projects.$save({ type: 'Basic' }); //'Basic' should change based on which button is clicked.
});
};
editProject.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Javascript for Modal:
.state('selection.new', {
url: '/new',
onEnter: ['$stateParams', '$state', '$modal', function ($stateParams, $state, $modal) {
$modal.open({
templateUrl: 'views/new-mark.html',
controller: 'NewProjectCtrl as editProject',
})
.result.finally(function () {
$state.go('^');
});
}]
})
HTML:
<!-- HTML for button that triggers modal 1 -->
<a ui-sref="selection.new">
<button type="button" class="btn btn-primary btn-lg" ng-click="open()">Select</button>
</a>
<!-- HTML for modal title -->
<div class="modal-header">
<h3 class="modal-title">{{editProjects.type}}</h3>
</div>
You can define options to pass into the modal instance like this:
JS to open modal:
$modal.open({
templateUrl: 'views/new-mark.html',
controller: 'NewProjectCtrl as editProject',
resolve: {
dialogOptions: function() {
return {
title: $stateParams.type === 'Basic' ? 'Basic Title' : 'Advanced Title',
type: $stateParams.type
};
}
}
})
Then inject and use dialogOptions in your modal instance controller:
myApp.controller('NewProjectCtrl', function ($scope, $location, $stateParams, Projects, $modalInstance, dialogOptions) {
var editProject = this;
editProject.title = dialogOptions.title;
editProject.save = function () {
editProject.project.type = dialogOptions.type;
The tricky part is that you're using onEnter for your state to open the dialog. The ng-click="open()" isn't doing anything right? So, maybe add a state parameter to represent the type - you could specify the ui-sref as follows (would need to update the state definition as well):
<a ui-sref="selection.new({type: 'Basic'})">
<a ui-sref="selection.new({type: 'Advanced'})">
State definition change if you set the type as a param in the state:
url: '/new?type',

Angular UI $modal error

I have downloaded some of the angular UI directives, as i do not need them all. I have downloaded the latest file for modal from http://angular-ui.github.io/bootstrap/ and using this code
App.controller('PagesController', ['$scope', '$modal', 'PageFactory', function ($scope, $modal, PageFactory) {
$scope.pages = [];
PageFactory.getPages().then(function (pages) {
$scope.pages = pages;
}, function (err) {
console.log(err.message);
});
$scope.deletePage = function (page) {
var modalInstance = $modal.open({
templateUrl: 'pages-delete-modal.html',
controller: ['$scope', '$modalInstance', function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]
});
modalInstance.result.then(function () {
// ok selected
}, function () {
});
};
}]);
Here is the template
<script type="text/ng-template" id="pages-delete-modal.html">
<div class="modal-header">
<h3 class="modal-title">Delete Confirmation</h3>
</div>
<div class="modal-body">
Are you sure you want to delete this page?
</div>
<div class="modal-footer">
<button class="btn btn-danger" ng-click="ok()">Delete</button>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
</div>
</script>
Now i seem to get an error saying
http://errors.angularjs.org/1.2.23/$injector/unpr?p0=%24modalProvider%20%3C-%20%24modal
I already have 'ui.bootstrap' injected into my app.js file here as you can see
var App = angular.module('MyApp', ['ui.router', 'ui.bootstrap']);
If i however use this link, instead of using the downloaded modal file, it works?
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>
I have also downloaded the transition directive as i believe the modal directive is dependant on this, but i cannot see that i am missing anything else.
I am using the tpl.min.js files for both transition and modal.
Any help much appreciated
You should try change the modalInstance controller to a string with the name of an actual controller in your project.
$scope.deletePage = function (page) {
var modalInstance = $modal.open({
templateUrl: 'pages-delete-modal.html',
controller: 'otherCtrl'
});
modalInstance.result.then(function () {
// ok selected
}, function () {
});
};
and then create the controller itself
App.controller('otherCtrl',['$scope','$modalInstance', function($scope,$modalInstance){
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);

Resources