AngularJS inject issue with Angular Bootstrap modal - javascript

I am integrating the modal from Angular Bootstrap and trying to adapt code sample from here to my app. I get the error: Error: [$injector:unpr] Unknown provider: $modalInstanceProvider <- $modalInstance
What do I need to do to make $modalInstance work? I see from code sample that they have written it so that it is within the scope of the function but I am not sure how to write things when chaining controllers.
angular.module('myApp', ['ui.bootstrap']).
controller('ModalInstanceCtrl', function($scope, $modalInstance) {
}).
factory('AuthService', ['$http', '$rootScope', '$modal',
function($http, $rootScope, $modal) {
return {
loginModal: function(callback) {
var modalInstance = $modal.open({
templateUrl: '/partials/main/signin',
controller: 'ModalInstanceCtrl'
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {});
}
};
}
]);

Ok - the issue was actually with my template. I had modified the partial from the sample to be:
<div ng-controller="ModalInstanceCtrl">
<div class="modal-header">
<h3>I am 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>
</div>
While in fact I needed to remove the ng-controller reference.
<div>
<div class="modal-header">
<h3>I am 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>
</div>
I still feel like I am stumbling around with Angular but this seemed to do the trick!

As shown in modal example angular ui, you don't have to specify the ng-controller element. You can specify the controller attribute when defining the modal.
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
},
dataModel: function () {
return $scope.data;
}
}
});

Related

Can't open a modal window in angularjs, using bootstrap

This is my app.js file:
const app = angular.module('CurseTransport', [
'ui.router',
'ui.bootstrap',
'ngMessages',
'raceModule',
])
app.config(['$stateProvider', '$urlRouterProvider', '$qProvider', function($stateProvider, $urlRouterProvider, $qProvider) {
$qProvider.errorOnUnhandledRejections(false)
$urlRouterProvider.otherwise('/races')
$stateProvider
.state('races', {
url : '/races',
templateUrl :'views/races.html',
controller:'racesController'
})
.state('racesInsert', {
url: '/races/insert',
onEnter: ['$stateParams', '$state', '$modal',
function($stateParams, $state, $modal) {
$modal
// handle modal open
.open({
template: 'views/racesInsert',
windowClass : 'show',
controller: ['$scope',
function($scope) {
// handle after clicking Cancel button
$scope.cancel = function() {
$scope.$dismiss();
};
// close modal after clicking OK button
$scope.ok = function() {
$scope.$close(true);
};
}
]
})
// change route after modal result
.result.then(function() {
// change route after clicking OK button
$state.transitionTo('races');
}, function() {
// change route after clicking Cancel button or clicking background
$state.transitionTo('races');
});
}
]
});
}])
My view for modal window:
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
When i click my button for open the modal window, it is not working. I have no error in my console. I also included in my scripts.
My modal is located in a different html file.
Have you read the documentation? https://angular-ui.github.io/bootstrap/#/modal
You need to use templateUrl, not template when referencing your modal template, and be sure to include the file extension:
$modal.open({
templateUrl: 'views/racesInsert.html',
windowClass : 'show',
...
Only use template if you are defining the template inline like this:
$modal.open({
template: '<div class="modal-header"><h1>Modal Heading</h1></div>...',
windowClass: 'show',
...
If you are using an inline template as a script, you need to declare the template with a proper script tag. And, do NOT include the outer dialog container:
<script id="racesInsert.html" type="text/ng-template">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</script>
$modal.open({
templateUrl: 'racesInsert.html',
windowClass : 'show',
...
You did not mention which version of Angular UI Bootstrap you are using. The current version uses $uibModal not $modal as the imported module.
Here is the js function you need to call for modal-
$scope.functionName=function(){
var uibModalInstance = $uibModal.open({
animation: true,
templateUrl: 'html page path',
controller: 'controllerName',
size: 'lg',
resolve: {
deps: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'app Name',
insertBefore: '#ng_load_plugins_before',
files: ['js controller file path']
});
}]
}
});
uibModalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
});
}
Call the function functionName when you need to open the popup.
You need to add $uibModal as dependencies in current controller and the model controller should have $uibModalInstance as dependencies.

Execute a javascript function within a controller from a directive

I need to execute a javascript function that resides inside a controller. I need to call the function from within a directive.
The arguments I'm passing are fine. My method name in the controller is "GetAttachments".
When I'm debugging, and using scope, the method name GetAttachments doesn't appear.
Can someone please help me to be able to execute the named function?
Here is my directive. I need to know the proper syntax of the line: scope.GetAttachments(attrs.downloadType, attrs.downloadId). Note that my arguments are fine...
.directive('download', ['$modal', function ($modal)
{
return {
restrict: 'E',
transclude: false,
replace: true,
template: '<a style="padding-right: 5px; color:#fff !important;" class="pull-right" href="#" ng-click="opendownload()"><i class="fa fa-files-o fa-lg" style="padding-right: 5px"></i>Download</a>',
link: function (scope, elem, attrs, controller)
{
scope.opendownload = function ()
{
$modal.open({
templateUrl: root + 'AccountingModule/modal/attachment/download-modal.html',
size: 'md',
backdrop: true,
controller: 'downloadSPDocumentsController as downloadCtrl',
resolve: {
attributes: function () { return attrs; },
}
});
scope.GetAttachments(attrs.downloadType, attrs.downloadId)
}
}
}
}])
Here is my JS function inside the controller:
module.controller('downloadSPDocumentsController', ['$scope', '$http', '$modalInstance', '$location', '$window', 'attributes',
function ($scope, $http, $modalInstance, $location, $window, attributes)
{
var viewModel = this;
viewModel.attributes = attributes;
var DocumentDownloadarr;
viewModel.GetAttachments = function (CheckID, FileID)
{
Here is the HTML
<!--<p>For Testing Purpose: Download Type: {{downloadCtrl.attributes.downloadType}}</p>
<p>For Testing Purpose: ID: {{downloadCtrl.attributes.downloadId}}</p>-->
<div class="modal-header">
<h3 class="modal-title">File Download</h3>
</div>
<div class="modal-body" cg-busy="{promise:downloadCtrl.promise}">
<ul ng-init="downloadCtrl.Init()" class="list-unstyled">
<li ng-repeat="item in downloadCtrl.DocumentDownloadarr">
<div class="col-sm-12">
<div class="form-group">
<div class="col-sm-10">
<input type="text" class="form-control" ng-value="item.FileDescription" ng-readonly="true" />{{item.ExternalDocumentId}}
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-default" ng-click="downloadCtrl.DownLoadAttachment(item.ExternalDocumentId, item.FileDescription)">Download</button>
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="modal-footer">
<div class=" btn-toolbar pull-right" role="toolbar">
<!--<div class="btn-group" role="group">
<button type="button" class="btn btn-default" ng-click="downloadCtrl.GetAttachments(downloadCtrl.attributes.downloadType, downloadCtrl.attributes.downloadId)">List Attachments</button>
</div>-->
<div class="btn-group" role="group">
<button type="button" class="btn btn-default" ng-click="$close()">Close</button>
</div>
</div>
</div>
You need to expose your function GetAttachments in the controller via the scope.
Instead of
viewModel.GetAttachments = function (CheckID, FileID)
try this:
$scope.GetAttachments = function (CheckID, FileID)
However please note that this will work only if the directive and the controller is sharing the scope (which I think is the case on your code). However if you want to use isolated scope (for better modularity and re-usability) of the directive , then you will have to pass a reference of the method (in your controller) to the directive's scope using '&' binding.
Take a look at this fiddler here for a demo of isolated scope and calling function in controller from directives
You might want to consider raising an event in your directive using something like:
$rootScope.$broadcast('myEventHappened');
And then in your controller listen for it with something like:
$scope.$on('myEventHappened', function() {});
This approach will keep you from tightly coupling your directive to your controller.

Angular Bootstrap-UI modal throw error

My Code is like this
<div id="palletapp" class="content" ng-app='myApp' ng-controller="MainCtrl" style="display: none">
<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>
</div>
angular.module('myApp', ['angular-loading-bar', 'ui.bootstrap']).controller('MainCtrl', [
'$http', '$scope', '$modal', '$filter', function ($http, $scope, $filter, $modal) {
$scope.open = function(size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
}
}
]);
everything looks okay to me. But on button click this throws an error.
TypeError: undefined is not a function. at line
var modalInstance = $modal.open({
I have correctly added Bootstrap-UI reference and all to page. Can any one point out what I am doing wrong?
You are injecting dependencies in wrong order:
'$http', '$scope', '$modal', '$filter', function ($http, $scope, $filter, $modal) {
Note that $modal service is the third one in list.

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

AngularjS $injector:unpr

I have a following controllers:
/** Calculation controller **/
app.controller('calculationController', ['$scope','$modal','content', function($scope, $modal, content) {
/** data recieved from get request **/
$scope.data = content.data; //promise
/** function to edit data **/
$scope.edit = function(item){
var htmlContents = {
title: 'Edit product',
body: 'Please confirm that you want to edit the product'
}
var modalInstance = $modal.open({
templateUrl : templateBase + 'views/modal/dialog.html',
controller : 'modalInstanceController',
resolve : {
items : function() { return item; },
html : function() { return htmlContents; }
}
});
}
/** function to delete data **/
$scope.trash = function(item){
}
}]);
app.controller('modalInstanceController', ['$scope', '$modalInstance','items','html', function($scope,$modalInstance,items,html) {
$scope.title = html.title;
$scope.body = html.body;
}]);
What I'm trying to accomplish is to open a dialog with contents from 'dialog.html' however once I click the :
<img ng-src="images/icn_edit.png" ng-click="edit(item)" alt="Edit">
$injector:unpr is appearing in console log.
dialog.html contents are :
<div ng-controller="modalInstanceController">
<div class="modal-header">
<h3>{{title}}</h3>
</div>
<div class="modal-body">
{{body}}
</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>
I know that I'm missing to inject something however after hours of looking at the code I'm unable to locate what...
From what I can observe '$scope', '$modalInstance','items','html' are being injected in modelInstanceController..
Any help appreciated.
thank you
From your dialog.html remove
Ng-controller="modalInstanceController"
It should be plain div and that will do the trick
Your html markup for dialog.html should look like this:
<div>
<div class="modal-header">
<h3>{{title}}</h3>
</div>
<div class="modal-body">
{{body}}
</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>

Categories

Resources