angular bootstrap modal controllerAs doesn't work - angularjs

I have an angular app that shows a modal dialog and I cannot get the controllerAs functionality to work. Here is my app definition:
var deps = ['ngResource', 'ngRoute', 'swaggerUi', 'http-auth-interceptor', 'ngAnimate', 'angular-spinkit', 'ui.bootstrap'];
var myapp = angular.module('myApp', deps);
Here is my controller that invokes the modal and the controller bound to the modal
myapp.controller('UsersController', ['$scope', '$log', '$uibModal', 'UsersService', function ($scope, $log, $uibModal, UsersService) {
$scope.users = UsersService.getAll();
$scope.openAddUserModal = function () {
$uibModal.open({
animation: false,
templateUrl: 'partials/addUserModal.html',
/* I've even tried controller:'AddUserModalCtrl as addUserModalCtrl' */
controller: 'AddUserModalCtrl',
controllerAs: 'addUserModalCtrl',
bindToController: true
});
};
}]).controller('AddUserModalCtrl', ['$scope', '$log', '$uibModalInstance', function ($scope, $log, $uibModalInstance) {
$scope.cancel = function () {
console.log('userToAdd: ' + JSON.stringify($scope.userToAdd));
$uibModalInstance.dismiss('cancel');
};
$scope.addUser = function () {
console.log($scope.username);
}
}])
And here is the modal html:
<div class="modal-header">
<h3 class="modal-title">Add new user</h3>
</div>
<div class="modal-body">
<form role="form">
<button ng-click="addUser()" type="submit" class="btn btn-default">Submit</button>
<!-- this works if I remove the 'addUserModalCtrl' -->
<button ng-click="addUserModalCtrl.cancel()" type="submit" class="btn btn-default">Cancel</button>
</form>
</div>

It's because you are adding the methods to $scope. You don't do that when using controllerAs syntax. You should use this. notation for your functions in AddUserModalCtrl.
this.cancel = function () {
console.log('userToAdd: ' + JSON.stringify(this.userToAdd));
$uibModalInstance.dismiss('cancel');
};
this.addUser = function () {
console.log(this.username);
}

Related

how can I get data of $scope.selAppt from bookingToolCtrl into reasonDialogCtrl?

I am a beginner in Angularjs and working on some else project.
how can I get data of $scope.selAppt from bookingToolCtrl into reasonDialogCtrl?
(function () {
app = angular.module('bookingToolApp', ['ngSanitize', 'ui.bootstrap', 'isteven-multi-select', 'angucomplete-alt', 'ngTable', 'dialogs.main', 'ngMap', 'BookingToolServices', 'BookingToolDirectives']);
app.run(['$templateCache', function ($templateCache) {
$templateCache.put('/dialogs/reason.html', '<div class="modal-header"> <h4 class="modal-title"><span class="glyphicon glyphicon-calendar"></span> Reserve Service {{selAppt.selected.eventid}}</h4></div><div class="modal-body"><ng-form name="nameDialog" novalidate role="form"><div class="form-group input-group-lg" ng-class="{true: \'has-error\'}[nameDialog.username.$dirty && nameDialog.username.$invalid]"> <label class="control-label" for="course">Reason:</label> <input type="text" class="form-control" name="reason" id="reason" ng-model="reason" ng-keyup="hitEnter($event)" required> <span class="help-block">Enter the reason for reserving this service.</span></div></ng-form></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button><button type="button" class="btn btn-primary" ng-click="save()" ng-disabled="(nameDialog.$dirty && nameDialog.$invalid) || nameDialog.$pristine">Submit</button></div>');
}]);
app.controller('bookingToolCtrl', ['$scope', 'dataService', '$sce', 'NgTableParams', '$filter', '$compile', '$rootScope', 'loadingEventService', 'claimantLatLngEventService', 'dialogs', '$timeout', 'ngTableEventsChannel', function ($scope, dataService, $sce, NgTableParams, $filter, $compile, $rootScope, loadingEventService, claimantLatLngEventService, dialogs, $timeout, ngTableEventsChannel) {
$scope.selAppt = {"selected": false};
}]);
app.controller('reasonDialogCtrl', function ($scope, $modalInstance, data) {
});
})();
I tried the following but it doesn’t work:
app.controller('reasonDialogCtrl', ['$scope', '$modalInstance', 'data', 'dataService', '$controller','$rootScope', function ($scope, $modalInstance, data, dataService, $controller,$rootScope) {
//-- Variables --//
$scope.data = dataService.data;
$scope.service = dataService;
var testCtrl1ViewModel = $controller('bookingToolCtrl');
alert(testCtrl1ViewModel.selAppt);
}]);
$scope.selAppt get values when I select an appointment.
In bookingToolCtrl
$scope.selAppt = {"selected": false};
dataService.data = $scope.selAppt //... you missed this
and in reasonDialogCtrl
$scope.data = dataService.data;

How to open modal window on button click in AngularJS

I can not figure out how to get a ui.bootstrap modal window to work with AngularJS. I'm getting the error messagse: Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal <- AdvancedSearchCtrl
Here's the code:
(function () {
angular.module('crm.ma')
.controller('AdvancedSearchCtrl', function ($modal) {
var vm = this;
vm.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'app/components/common/advancedSearchModal.html',
controller: advancedSearchInstanceCtrl
});
};
});
angular.module('crm.ma').controller('advancedSearchInstanceCtrl', function ($modalInstance) {
var modal = this;
modal.cancel = function () {
$modalInstance.close();
};
});
})();
<div class="row">
<button ng-click="vm.openModal()">Add User</button>
<script type="text/ng-template" id="advancedSearchModal.html">
<div class="modal-header">
<h3>Text for header</h3>
</div>
<div class="modal-body">
Text for body
</div>
<div class="modal-footer">
<button type="submit">Search</button>
<button class="btn btn-warning" ng-click="modal.cancel()">Cancel</button>
</div>
My module code:
(function () {
'use strict';
var app = angular
.module('crm.ma',
[
'ui.router',
'ui.bootstrap',
'angularUtils.directives.dirPagination',
'toastr',
'crm.ma.common',
]);
})();
Also, you've defined modalInstance in 'AdvancedSearchCtrl' but haven't called it.
modalInstance.result.then(function(x) { do something here} );

angularjs modal initialization using factory

Trying to make a modal window opening in controller, using app.factory.
Getting strange error and don't understand what the problem.
So, this is the error i got in js console:
Error: [$injector:unpr] http://errors.angularjs.org/1.3.15/$injector/unpr?p0=modalServiceProvider%20%3C-%20modalService%20%3C-%20MapController
Here is my files and structure:
Main controller:
app.controller('MainController', ['$scope', 'modalService', function($scope, modalService){
///Modal: Add item
//////////////////
console.log('dfdfdf');
$scope.AddItem = modalService.openAddItemDialog($scope);
}]);
open it on simple HTML:
<div ng-controller="MainController">
<button type="button" class="btn btn-block" ng-click="AddItem()"> </button>
</div>
Factory:
app.factory('modalService', ['$modal', function($modal) {
function openAddItemDialog($scope) {
console.log('dfdfdf');
$scope.animationsEnabled = true;
$scope.valueToPass = "I must be passed";
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'AddItemDialog.html',
controller: 'AddItemController',
resolve: {
aValue: function () {
return $scope.valueToPass;
}
}
});
modalInstance.result.then(function (paramFromDialog) {
$scope.paramFromDialog = paramFromDialog;
});
}
return {
openAddItemDialog: openAddItemDialog
};
}]);
Modal Controller:
app.controller('AddItemController',function($scope, $modalInstance, aValue) {
$scope.valuePassed = aValue;
$scope.close = function () {
$modalInstance.close("Someone Closed Me");
};
});
HTML template:
<div class="modal-header">
<h2>The title</h2>
</div>
<div class="modal-body">
The body of the dialog with the value to pass '{{valuePassed}}'
</div>
<div class="modal-footer">
<button class="btn" ng-click="close()">Close</button>
</div>
i even don't see the first console.log('dfdfdf'); func result. so it broke main controller's work in some way.. but blind, can't se, whats the problem? for me, looks like all should work.
** app is defined in separate file like var app = angular.module('MainPage', ['ui.bootstrap']);
Can you double check that you have included the service file in your app page?
You can find more info about this error here

Angular modal is not updating $scope in result

I'm trying to implement a modal window in Angular to prompt a user for an input, I've used almost the same code in a previous app and it worked, I really don't know what is going on here...
Here is the controller that opens the modal (in Coffee Script):
.controller('addStreamModal', [
'$scope', '$modal', '$log', '$http', '$rootScope'
($scope, $modal, $log, $http, $rootScope) ->
$scope.open = ->
modalInstance = $modal.open(
templateUrl: "addStream.html"
controller: 'addStreamModalInstance'
resolve:
public_key: ->
"placeholder"
)
modalInstance.result.then ((result) ->
return
), ->
$log.info "Modal dismissed at: " + new Date()
return
return
return
])
Now the modal instance controller:
.controller('addStreamModalInstance', [
'$scope', '$modalInstance', '$http', 'public_key'
($scope, $modalInstance, $http, public_key) ->
console.log(public_key)
$scope.public_key = public_key
$scope.ok = ->
console.log($scope.public_key)
$modalInstance.close $scope
return
$scope.cancel = ->
$modalInstance.dismiss "cancel"
return
return
])
And the HTML:
<div class="modal-header">
<h4>Please enter the private key for verification {{public_key}}</h4>
</div>
<div class="modal-body">
<div class="form-group">
<input type="text" class="form-control" id="exampleInputEmail1" ng-model="public_key">
</div>
</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>
So I click a button and the Modal opens with "placeholder" in the text box, I can also see this test bound to the modal title. As I endit text in the box, the title continues to update as expected due to binding, however when I click ok, it seems like the $scope.public_key reverts back to "placeholder". Trying to figure out why.
When you set the value in your addStreamModalInstance controller you are working within a different scope than addStreamModal. To update addStreamModal's scope with the value set in addStreamModalInstance you can return the selected value (you are doing this by returning $scope) and assign it in the .then invocation of your addStreamModal controller.
Your addStreamModal would become something like (sorry, my coffeescript is not great):
.controller('addStreamModal', [
'$scope', '$modal', '$log', '$http', '$rootScope'
($scope, $modal, $log, $http, $rootScope) ->
$scope.modalTitle = "placeholder" //defaults this value to placeholder
$scope.open = ->
modalInstance = $modal.open(
templateUrl: "addStream.html"
controller: 'addStreamModalInstance'
resolve:
public_key: ->
$scope.modalTitle
)
modalInstance.result.then ((modalScope) ->
$scope.modalTitle = modalScope.public_key //updates the default value with the value from the modal
return
), ->
$log.info "Modal dismissed at: " + new Date()
return
return
return
])
Ok I have it working now, I went back to the angular example, tested it then slowly adapted it to my needs, heres the code:
.controller "addStreamModal", ($scope, $modal, $http, $log) ->
$scope.public_key = ""
$scope.open = ->
modalInstance = $modal.open(
templateUrl: "addStream.html"
controller: "addStreamModalInstance"
resolve:
public_key: ->
$scope.public_key
)
modalInstance.result.then ((public_key) ->
console.log(public_key)
return
), ->
$log.info "Modal dismissed at: " + new Date()
return
return
return
And the instance:
.controller "addStreamModalInstance", ($scope, $modalInstance, public_key) ->
$scope.editable = public_key: public_key
$scope.ok = ->
$modalInstance.close $scope.editable.public_key
return
$scope.cancel = ->
$modalInstance.dismiss "cancel"
return
return
HTML:
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<input type="text" name="input" class="form-control" ng-model="editable.public_key">
</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>
So I think the difference is that I nest the public key into the .editable object in the instance controller. I don't exactly understand why this works but it does and I'm happy about that.

Angular Directive function call on ng-change

I have an angular-bootstrap modal popup box that contains a custom directive in the template:
Modal.html
<div class="modal-header">
<h3 class="modal-title">Modal Header</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<my-directive ng-model="test" ng-change="doSomething()" />
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="upload()">Upload</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
ModalCtrl.js
app.controller('ModalCtrl', function ModalCtrl( $scope, $modalInstance ) {
$scope.test = 'empty';
$scope.upload = function() {
$scope.test = 'change!';
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
I open the modal popup from my main controller like this:
MainCtrl.js
var app = angular.module( 'myApp', [ 'ui.bootstrap' ] );
app.controller('MainCtrl', function MainCtrl( $scope, $modal ) {
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: '/assets/modals/Modal.html',
controller: 'ModalCtrl',
size: 'md'
});
};
});
As you can see from the above code, the modal template contains my custom directive <my-directive> which takes $scope.test - defined in the ModalCtrl - as it's model and should call $scope.doSomething() when that model changes.
The custom directive looks like this:
MyDirective.js
angular.module( 'myApp' ).directive( 'myDirective', function() {
return {
controller: function( $scope ) {
$scope.doSomething = function() {
console.log( 'doSomething() called! $scope.test now = ' + $scope.test );
};
},
link: function( $scope, el, att ) {
console.log( '$scope.test = ' + $scope.test );
},
template: '<div class="thumbnail"></div>'
};
} );
When the modal popup opens the console prints out $scope.test = empty which is exactly what I expect to see. But when $scope.test is changed by calling the $scope.upload() function in ModalCtrl nothing happens! What I think should happen is $scope.doSomething() is called which then should print out in the console doSomething() called! $scope.test now = change!.
Any help would be much appreciated, this is driving me mad!
I figured it out. Instead of using ng-model and ng-change I added:
scope: {
test: '#'
}
to my directive and added this into my link function:
$scope.$watch( 'test', function() {
console.log( 'test changed' );
} );
Then I add test as a parameter in my directives tag like so:
<my-directive test="test" />
and finally whenever I change $scope.test I call $scope.$apply() and voila!

Resources