Bootstrap uib modal with multiple controllers - javascript

I am trying to use a bootstrap modal and I am passing the main controller in the $uibModal.open({controller : "mainCtrl"}).
So far its all good now I want to have several tabs in the modal and I want each tab to have its own controller using ng-controller. This is where I am getting the error : [$injector:unpr] Unknown provider: $uibModalInstanceProvider <- $uibModalInstance <- tabController
which is expected because it seems we cannot have ng-controller inside uibModalInstance.
Is there an alternate way of achieving this?

It should work for you like in this |- demo fiddle - |- demo plnkr with template files -| I've create for you. Please compare this solution carefully with yours. You can have as many ng-controller defined in your uibModal template as you want. Also ensure that your controller is a part of the same module.
View
<div ng-app="ui.bootstrap.demo">
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header" ng-controller="ModalDemoSecondCtrl">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body" ng-controller="ModalDemoThirdCtrl">
Demo form submit:
<br/>
<form ng-submit="ok()">
<div class="input-group animated fadeIn">
<input type="text" class="form-control finderBar" ng-model="searchTerm" placeholder="City, State..." autofocus>
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="ok()">Go!</button>
</span>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Open me!</button>
</div>
</div>
AngularJS application
angular.module('ui.bootstrap.demo', ['ui.bootstrap'])
.controller('ModalDemoCtrl', function($rootScope, $scope, $log, $uibModal) {
$scope.open = function(size, template) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: template || 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size
});
};
$scope.toggleAnimation = function() {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
}).controller('ModalDemoSecondCtrl', function($rootScope, $scope, $log, $uibModal) {
}).controller('ModalDemoThirdCtrl', function($rootScope, $scope, $log, $uibModal) {});
angular.module('ui.bootstrap.demo')
.controller('ModalInstanceCtrl', function($scope, $uibModalInstance) {
$scope.ok = function() {
$uibModalInstance.dismiss('cancel');
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});

Related

ui-bootstrap modal won't close or dismiss

New to ui-bootstrap and I've gotten the modal to appear, but can't get it to dismiss with a button press. I've tried a many combinations but nothing seems to work (or it makes the modal not appear at all).
The modal is in a separate file as:
<div ng-controller = 'entryCtrl' class="modal" id="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"></div>
<div class="modal-body">
<div class="modal-inner-content">
</div>
<div class="modal-footer" id="modal-footer">
<button type="button" class="btn btn-success" ng-click="cancel()"><i class="glyphicon glyphicon-backward"></i> Back</button>
<button type="button" class="btn btn-danger" ng-click="ok()"><i class="glyphicon glyphicon-forward"></i> Continue</button>
</div>
</div>
</div>
</div>
</div>
It's called in a different html file with the same controller (I tried having them as different controllers, but then variables wouldn't appear to inject at all, i.e. the modal instance would be undefined).
In the controller, I can get the thing to open as:
xControllers.controller('entryCtrl', [
'$scope', '$window', '$modal', '$log',
'SharedProperties',
function ($scope, $window, $modal, $log,
SharedProperties) {
$scope.open = function (size) {
$scope.modal = $modal({
templateUrl: './views/modals/possible_slurs.html',
controllerAs: ['$window', '$log', '$modalInstance', function ($window, $log, $modalInstance) {
this.ok = function () {
$modalInstance.close();
};
this.cancel = function () {
$modalInstance.dismiss('cancel');
$window.history.back();
};
}],
scope: $scope
});
};
}]);
For some reason the $modal.open() doesn't work, and template, and controller parameters don't either (it only accepts templateUrl and controllerAs).
I attempted to have controllerAs set as a different controller, but then that separate controller wouldn't recognize the modal instance (it came up as undefined).
I have my dependencies set as:
var x = angular.module('x-app', [
'xControllers',
'ngAnimate',
'ngRoute',
'ngResource',
'mgcrea.ngStrap',
'angularUtils.directives.dirPagination',
'ui.bootstrap'
]);
And their versions:
"dependencies": {
"socket.io": "^2.2.0",
"angular": "^1.7.8",
"angular-animate": "^1.7.8",
"angular-motion": "^0.4.4",
"angular-resource": "^1.7.8",
"angular-strap": "^2.3.12",
"bootstrap": "^4.3.1",
"jquery": "^3.4.1",
"angular-bootstrap": "^2.5.0"
}
Thank you so much and please let me know if more information is needed to help with this!
This is the most convoluted thing I've ever come across. After several hours and days going back and forth in documentation, I've found the answer: which is, of course, that there were many, many problems going on and the fact that anything was showing up at all was a total fluke.
I'll just post what I got working, but suffice it to say: the Angular version is very important here.
The new working modal (notice that there is no controller specified here nor any of those wrapping divs):
<div class="modal-header"></div>
<div class="modal-body">
<div class="modal-inner-content">
</div>
<div class="modal-footer" id="modal-footer">
<button type="button" class="btn btn-success" ng-click="cancel()"><i class="glyphicon glyphicon-backward"></i> Back</button>
<button type="button" class="btn btn-danger" ng-click="ok()"><i class="glyphicon glyphicon-forward"></i> Continue</button>
</div>
</div>
The new working controller which opens the modal (note the switch to $uibModal):
xControllers.controller('entryCtrl', [
'$scope', '$window', '$uibModal', '$log',
'SharedProperties',
function ($scope, $window, $uibModal, $log,
SharedProperties) {
$scope.open = function (size) {
$uibModal.open({
templateUrl: './views/modals/modal.html',
controller: 'modalInstanceCtrl',
scope: $scope
});
};
}]);
And the new modal controller called within that controller:
xControllers.controller('modalInstanceCtrl', [
'$scope', '$window', '$uibModalInstance',
function ($scope, $window, $uibModalInstance) {
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.close();
$window.history.back();
};
}]);
And that seemed to do the trick. A large thanks to whoever created this Plunker (http://embed.plnkr.co/4VcNom/) because the official documentation was essentially the opposite of useful in this regard (https://angular-ui.github.io/bootstrap/; it only handles the case where a modal's HTML is loaded in the same HTML doc as the main HTML, not for separate files).
Anywho, hope this helps others.

How can I develop a popup that open on a button click (Angularjs)

Any one can refer me a link or a demo of code for developing a popup using angularjs.
I have tried the following code but it's not working.
var myApp = angular.module('myApp', ['ngRoute', 'ngMap', 'ui.bootstrap']);
myApp.config(function($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$routeProvider
.when("/", {
templateUrl: "views/home.php",
controller: 'PopupDemoCont'
})
.when("/profile.php", {
templateUrl: "views/profile.php"
})
.otherwise({
redirectTo: "/"
});
});
myApp.controller("ImageController", ["$scope", function($scope) {
$scope.logoimage = "images/logo.png";
$scope.bgtextimage = "images/bgtextimage.png";
}]);
myApp.controller("PopupDemoCont", ["$scope", "$modal", function($scope, $modal) {
$scope.open = function() {
console.log('opening pop up');
var modalInstance = $modal.open({
templateUrl: 'views/popup.php',
controller: 'PopupCont'
});
};
}]);
myApp.controller("PopupCont", ["$scope", "$modalInstance", function($scope, $modalInstance) {
$scope.close = function() {
$modalInstance.dismiss('cancel');
};
}]);
In bellow html, I set ng-controller but it isn't working.
<div class="book_div">
<div class="book_content">
<p id="book-text">Facing Immigration
<br> Problems?
</p>
<p>Helpful Guid To Navigate Your Case</p>
<div class="hidden-sm hidden-xs"><img ng-src="{}" class="center-block img-responsive">
</div>
<a class="submit-button book_btn" ng-click="open()">Free download</a>
</div>
</div>
It is giving the Error:
[$injector:unpr].
You can use uibModalinstance.
On button click call the function open.
code for open function:
$scope.open = function(uuid,name){
var instance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'common/common/partials/delete-
confirm.tpl.html',
controller: function ($uibModalInstance,
$scope) {
$scope.name = Name;
$scope.icon = "fa-cogs";
$scope.description = "Yo have opened uib
Popup"
$scope.delete = function () {
$uibModalInstance.close($scope.deleteValue);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
}
I have used this code for deleting my record. You can use in your way, if you want to take response of Popup you can use:
instance.result.then(function (option) {
// Your code here
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
HTML template will be like:
<div class="modal-header gray_background">
<h4><b>Permanently Delete - <i class="fa {{icon}} folderIcon" aria-hidden="true"></i> {{name}} </b></h4>
</div>
<div class="modal-body">
<span data-ng-bind-html="description"></span>
<center style="margin-top: 10px;">
<div>Type "delete" to confirm
<input type="text" class="input" ng-model="deleteValue" required />
</div>
</center>
</div>
<div class="modal-footer gray_background">
<button class="btn btn-default" type="button" ng-click="cancel()">Cancel</button>
<button class="btn btn-danger" type="button" ng-click="delete()">Delete</button>
</div>
Hope this would be helpful, if you have any further query you can ask.
Thanks!

Using Angular controller inside Bootstrap Modal

[html]
<div class="modal fade" id="proj-edit" tabindex="-1" role="dialog" aria-hidden="true" data-remote="update.html">
<div class="modal-dialog">
<div class="modal-content" ng-controller="UpdateProjectController"></div>
</div>
</div>
[javascript]
var ProjectApp = angular.module('ProjectApp', ["ui.bootstrap"]);
ProjectApp.controller('UpdateProjectController', ["$scope","$http", function($scope, $http){
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}]);
[update.html]
<div class="modal-header" >
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 id="myModalLabel" class="modal-title">Update Project</h4>
</div>
<div class="modal-body">
{{message}}
</div>
<div class="modal-footer">
<button type="submit" class="btn blue-soft" ng-click="UpdateProject()">Update</button>
<button type="button" class="btn default" data-dismiss="modal">Cancel</button>
</div>
Issue: Modal is being invoked from JQuery using .modal('show') method. My intention is to render the controller whenever the modal is opened. However, it seems that the modal does not recognise the controller and no message nor function from the controller can be executed. Appreciate your help on this matter. TQ.
HI please check the example
index.html
<!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>
example.js
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
};
for reference http://embed.plnkr.co/As959V/
The reason is update.html is quite a massive form and preferred not to
include inside main html file. So, the modal is basically calling the
remote html file.
Your remote html file and your modal file maybe using 2 different instances of the UpdateProjectController.
As said by Martijn, you coud use ui-bootstrap for this but if you don't want to, you could solve it by using a directive.
// directive to open the modal
var app = angular.module('myApp', []);
app.directive('myModal', myModal);
myModal.$inject = [];
function myModal() {
return {
restrict: 'A',
link: link
}
function link($scope, $element, $attributes) {
$element.click(function (event) {
angular.element($attributes.modalId).modal();
});
}
}
app.controller('ModalCtrl', ModalCtrl);
ModalCtrl.$inject = [];
function ModalCtrl() {
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}
Modal is being invoked from JQuery using .modal('show') method.
So in case you use a button to do this render the modal, you could easily include the directive as an attribute to the modal instead of ng-click()
Lastly, include the modal file in your template file
<body>
<div ng-controller="UpdateProjectController">
// So in case you use a button to do this render the modal,
// you could easily include the directive as an attribute to the modal instead of ng-click()
<a href="javascript:;" my-modal modal-id="#modalUpdateProject">
Update Project
</a>
</div>
<!-- modals -->
<div ng-controller="ModalCtrl">
<ng-include src="'path/to/modal.html'"></ng-include>
</div>
<!-- end modals -->
</body>

Display dynamic content in Angular Modal from parent controller

I am using angular-modal-service. I wish to modify the content of modal body as custom input text from the user. My index.html looks like :
<head>
<link rel="import" href="notify.html">
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<input type="text" ng-model="custom_text" />
<input type="button" value="Click here for notification" ng- click="showNotification()" />
</body>
</html>
My app.js :
var app = angular.module("someApp", ['angularModalService']);
app.controller("mainController", function($scope, ModalService){
$scope.showNotification = function(){
document.getElementById('my_text').innerHTML = $scope.custom_text;
alert($scope.custom_text);
ModalService.showModal({
templateUrl: "notify.html",
controller: "YesNoController"
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = result ? "You said Yes" : "You said No";
});
});
}
});
app.controller('YesNoController', ['$scope', 'close', function($scope, close) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
}]);
My notify.html has :
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close(false)" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Yes or No?</h4>
</div>
<div class="modal-body">
<p><span id="my_text"></span></p>
</div>
<div class="modal-footer">
<button type="button" ng-click="close(false)" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" ng-click="close(true)" class="btn btn-primary" data-dismiss="modal">Yes</button>
</div>
</div>
I am actually trying to modify notify.html modal body in the controller by accessing it through DOM. But it is giving me the error : Cannot set property 'innerHTML' of null.
How can I do this. Please help.
First you should only manipulate the DOM in angular with directives. So your approach of accessing the DOM in this way would probably cause you problems even if it was working.
That being said. You just pass the scope value to the Modal and bind the value directly to the template with handlebars {{custom_text}}
Update .showModal Method to pass scope values:
ModalService.showModal({
templateUrl: "notify.html",
controller: "YesNoController",
inputs: {
'custom_text': $scope.custom_text
}
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = result ? "You said Yes" : "You said No";
});
});
Modal HTML:
<div class="modal-body">
<p><span id="my_text">{{custom_text}}</span></p>
</div>

ng-click and ng-submit doesn't work

i have a angular application with phonegap where i have a login form and login controller.
The problem is that the ng-submit doesn't work. Normaly the submit call the fonction formConnexion() but nothing happens. So, i tried with just a alert, but it's the same result...
After i tried with a ng-click and same result. Then, i wanted try to call a sample variable in the scope in the template ($scope.test) and it doesn't display. And the console.log('salut!!') doesn't dispaly when i am on the login page.
Which made me think that my controller it doesn't associate to the template.
But i have the ng-controller in my div with the good name controller.
Then, i thought that angular it's was worse installing but no because the other directives work (ng-if, ng-src, ...)
So, if you have a idea to solve this problem, I do not mind :)
here the code for the template :
login.html
<div class="row jumbotron" style="margin:10px" ng-controller="LoginCtrl">
<div class="col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2 col-sm-8 col-sm-offset-2 col-xs-8 col-xs-offset-2">
<h1>{{ test }}</h1>
<form class="form-horizontal" ng-submit="alert('alert')">
<div class="form-group">
<label for="login" class="control-label">Login</label>
<input type="text" name="login" class="form-control" ng-model="formData.login">
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<input type="password" name="password" class="form-control" ng-model="formData.password">
</div>
<button type="submit" class="btn btn-md btn-success">Connexion</button>
</form>
click
<img ng-src="images/accueil.png" class="accueil img-responsive">
</div>
</div>
and here the controller :
login.js
'use strict';
appStat.controller('LoginCtrl', function ($scope, $rootScope, $http, $location) {
console.log("salut!!");
$scope.formData = {};
$scope.test = "test";
$scope.toto = function() { alert('alert'); };
/**
* Connect l'user
*/
$scope.formConnexion = function () {...}
});
and here my app.js :
app.js
'use strict';
var appStat = angular.module('posStatsPhoneGap', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngMessages',
'ngAnimate',
'ngAria',
'ngTouch',
'picardy.fontawesome'
])
.config(['$routeProvider', '$compileProvider', function ($routeProvider, $compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|tel):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|tel):/);
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/stat', {
templateUrl: 'views/stat.html',
controller: 'StatCtrl'
})
.otherwise({
redirectTo: '/'
});
}
]);
Thank you in advance !
Following from my comment Try something like this:
Create a Controller file & a controller within it Create a angular
module within the controller file
Create a controller.js file then create a angular module see code below:
//Within your controller.js file
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope, $http){
$scope.Data = "Alert Alert";
// Create a function within the scope of the module
$scope.myFunc = function(){
alert($scope.Data)
};
});
Then within your HTML file call the function on-Click see code below:
Note: Don't forget to add the controller you created into your HTML code. I usually add it in the body tag
<body ng-controller="myController">
<button ng-click="myFunc()">Make Request Button</button>
</body>
See a live example here:
http://plnkr.co/edit/sQ0z7TlyWv5fM5XyfujK?p=preview
Also a note: ng-click is mostly used for any click events you are trying to perform within your angular app but ng-submit is mostly used when working with a HTML form submission.
Use ng-submit in you form as:
<form ng-submit="submit()">
function Ctrl($scope) {
$scope.list = [];
$scope.text = 'hello';
$scope.submit = function () {
if ($scope.text) {
$scope.list.push($scope.text);
$scope.text = '';
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit()">Enter text and hit enter:
<input type="text" ng-model="text" name="text" />
<input type="submit" id="submit" value="Submit" /> <pre>list={{list}}</pre>
</form>
<button ng-click="submit()">Submit 2</button>
</div>
</div>
I found the error. It was caused by having 2 controllers with the name 'LoginCtrl'. It was a stupid copy/paste error.
I have created one working code for the above question for 4 different type of HTML element, for complete code please follow the below URL -
http://plnkr.co/edit/Tm2Rtbt3xsv4pKzcPQCw?p=preview
<body ng-controller="ExampleController">
<button ng-click="setButton()">set button</button>
<div content="snippetContentFirst"></div>
<div content="snippetContentSecond"></div>
<div content="snippetContentThird"></div>
<div>
<ul content="snippetContentFour"></ul>
</div>
</body>

Categories