Angular modal is not updating $scope in result - angularjs

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.

Related

AngularJS call AngularStrap Modal from service

I am trying to create a service to display Angular-Strap modals since I have many different parts of code that will need to trigger a modal and I don't want to run into a situation where I would have a circular reference.
This is code that works where you have access to $scope. For instance, in the applications controller.
function MyModalController($scope) {
$scope.title = 'Draw Object Properties';
$scope.content = 'Hello Modal<br />This is place holder test';
};
MyModalController.$inject = ['$scope'];
// Pre-fetch an external template populated with a custom scope
var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'webmapapi/modal/toolproperties.html', show: false });
// Show when some event occurs (use $promise property to ensure the template has been loaded)
$scope.showModal = function () {
myOtherModal.$promise.then(myOtherModal.show);
};
Like I said I need to call this from a service though.
(function (angular, undefined) {
'use strict';
angular.module('ModalService', ['service', 'webValues', 'msObjects', 'mgcrea.ngStrap',])
.config(function ($modalProvider) {
angular.extend($modalProvider.defaults, {
html: true
});
})
.factory("ModalService", function (MapApiService, webValues, VectorObjs,$modal) {
var modalSVC = {
};
modalSVC.showModal = function (modalType) {
var scope = angular.element(document.getElementById('mainContainer')).scope();
function MyModalController(scope) {
scope.title = 'Draw Object Properties';
scope.content = 'Hello Modal<br />This is place holder test';
};
MyModalController.$inject = ['scope'];
// Pre-fetch an external template populated with a custom scope
var myOtherModal = $modal({ controller: MyModalController, templateUrl: 'myURL.html', show: true });
// Show when some event occurs (use $promise property to ensure the template has been loaded)
myOtherModal.show;
};
return modalSVC;
})
}(angular));
The above does not like the scope I'm getting.
Okay, It's amazing how easy something can be once you know what you are doing!!
Essentially you will want to set up a service...
(function (angular, undefined) {
'use strict';
angular.module('ModalService', ['mgcrea.ngStrap'])
.controller('ModalServiceController', modalServiceController)
.factory("ModalService", function ($animate, $document, $compile, $controller, $http, $rootScope, $q, $templateRequest, $timeout, $modal) {
function ModalService() {
var self = this;
self.showModal = function (title,templateUrl) {
var modal = $modal({
title: title,
templateUrl: templateUrl,
show: true,
backdrop: 'static',
controller: 'ModalServiceController'
});
modal.show;
};
}
return new ModalService();
})
modalServiceController.$inject = ['$scope', '$modal'];
function modalServiceController($scope,$modal) {
//title and content need to be populated so I just left the default values
$scope.title = 'Draw Object Properties';
$scope.content = 'Hello Modal<br />This is place holder test';
};
}(angular));
Now that you have your controller set up and injecting $modal, all you have to do from anywhere you have your service reference injected is...
ModalService.showModal("Your Title",
"Your URL");
I have a template(must be formatted as ) set up as Template.html and the contents are...
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" ng-show="title">
<button type="button" class="close" ng-click="$hide()">×</button>
<h4 class="modal-title" ng-bind-html="title"></h4>
</div>
<div class="modal-body" ng-show="content">
<h4>Text in a modal</h4>
<p ng-bind-html="content"></p>
<pre>2 + 3 = {{ 2 + 3 }}</pre>
<h4>Popover in a modal</h4>
<p>This <a href="#" role="button" class="btn btn-default popover-test" data-title="A Title" data-content="And here's some amazing content. It's very engaging. right?" bs-popover>button</a> should trigger a popover on click.</p>
<h4>Tooltips in a modal</h4>
<p><a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>This link</a> and <a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>that link</a> should have tooltips on hover.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="$hide()">Close</button>
<button type="button" class="btn btn-primary" ng-click="$hide()">Save changes</button>
</div>
</div>
</div>
I hope this helps you!!

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;

Trying to show a modal popup but getting this error [$injector:unpr] in angularjs

Hi I am a newbie and I am learning angularjs. I am implementing a modal popup on click. But seems like there is an issue in dependency.
My index file
<body>
<div class="global-wrap">
<div class="container">
<div class="col-md-offset-3 col-md-6 col-md-offset-3 login">
<h1 class="align-cent">ShopOber</h1>
<div ng-controller="PosController">
<button ng-click="open()" class="btn btn-warning">Simple Popup</button>
</div>
</div>
</div>
</div>
</body>
</html>
my controller file
var posControllers = angular.module('posControllers', ['ui.bootstrap']);
posControllers.controller('PosController', ['$scope', '$http', '$routeParams', '$modal', function ($scope, $http, $routeParams, $modal) {
$scope.open = function () {
console.log('opening pop up');
var modalInstance = $modal.open({
templateUrl: 'popup.html',
});
};
}]);
and my app.js file
var myApp = angular.module('myApp', [
'ngRoute', // we are telling angular that we are using ngRouting feature that enables deeplinking first
'posControllers',
// we specify the JS that will handle this module
//'caControllers'
]);
Full error in console
"Error: [$injector:unpr] http://errors.angularjs.org/1.4.4/$injector/unpr?p0=%24uimodalProvider%20%3C-%20%24uimodal%20%3C-%20PosController
L/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:6:416
eb/q.$injector<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:40:307
d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:38:308
eb/u.$injector<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:40:379
d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:38:308
e#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:39:64
Xe/this.$get</</<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:80:149
K#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:61:140
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:326
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
g#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:54:349
V/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:53:388
yc/d/</<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:20:4
kf/this.$get</n.prototype.$eval#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:133:35
kf/this.$get</n.prototype.$apply#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:133:264
yc/d/<#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:477
e#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:39:94
yc/d#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:398
yc#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:20:179
Zd#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:19:1
#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:292:238
a#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:174:283
Hf/c#https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js:35:124
"
I am following this tutorial https://www.formget.com/angularjs-popup/.The pop up does not show up although it code does and when i write display:block in console the pop up does come
My popup.html
<div class="modal-header">
<h3 class="modal-title">Header</h3>
</div>
<div class="modal-body">
Popup example with close button
</div>
<div class="modal-footer">
<button class="btn btn-warning" type="button"
ng-click="close()">Close</button>
</div>
Since angular-bootstrap 1.0.0 newer version all the directive & services are prefixed with uib. Specifically service are prefixed with uib such as $modal=> $uibModal & directives are prefixed with uib- such as popover => uib-popover .Here you can see the changelog
So you should be injecting $uibModal instead of $modal
var posControllers = angular.module('posControllers', ['ui.bootstrap']);
posControllers.controller('PosController',
['$scope', '$http', '$routeParams', '$uibModal',
function($scope, $http, $routeParams, $uibModal) {
$scope.open = function() {
console.log('opening pop up');
var modalInstance = $uibModal.open({
templateUrl: 'popup.html',
});
};
}
]
);
Make sure you have referenced the library for angular-bootstrap
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
also module should be like this,
var myApp = angular.module('myApp', [
'ngRoute',
'posControllers',
'caControllers',
'ui.bootstrap'
]);
DEMO

angular bootstrap modal controllerAs doesn't work

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);
}

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

Resources