I have the following problems:
1- When my model is open and I click 'cancel' to close it, it reloads the page.
2- When I click 'OK', my 'DELETE'-request is not sent to the server (it doesn't receive anything) and the page is reloaded. I'm also not redirected to the page I'm meant to go to.
HTML
<div>
<input type="button" class="btn btn-primary" ng-click="suppr()" value="ok"/>
<input type="button" class="btn btn-default" ng-click="annulSupp()" value="cancel" />
</div>
file js
(function() {
'use strict';
var progress = angular.module('demret.progress', ['ui.bootstrap.modal']);
progress.directive('progressDem', function() {
return {
restrict : 'E',
templateUrl : "progress/progress.html",
controller : [ '$scope', '$http', 'Demande', '$window', '$modal', function($scope, $http, Demande, $window, $modal) {
// TODO
$scope.supprimerDemande = function() {
var urlSetDem = cfg.urlDDRRest + 'demande/' + Demande.get().id;
var config = {
method : 'DELETE',
url : urlSetDem,
jsonExpected : true
};
$http(config).then(function(http) {
$window.location.href = cfg.urlPortail;
})['catch'](function(http) {
$scope.errT= 'Une erreur technique';
})['finally'](function() {
});
}
// ==========================================
// open fenetre modal
// ==========================================
$scope.modalSuppressionDem = function(size) {
// déclaration de la fenetre
var modalInstance = $modal.open({
animation : true,
templateUrl : 'progress/suppression-modal.html',
controller : 'ModalSuppressionDem',
size : size,
backdrop : 'static',
resolve : {
functionSupp : function() {
return $scope.supprimerDemande;
}
}
});
modalInstance.result.then(function() {
// close
});
};
} ]
}
});
// Controleur de la fenetre modale
progress.controller('ModalSuppressionDem', [ '$scope', '$modalInstance', 'functionSupp', function($scope, $modalInstance, functionSupp) {
$scope.suppr = function() {
functionSupp();
$modalInstance.close();
};
$scope.annulSupp = function() {
$modalInstance.close();
};
} ]);
})();
config.js
(function() {
'use strict';
window.cfg = {
urlDDRRest : '/TOTO-rs/api/',
urlPortail : '/TOTO/',
};
})();
Does anyone know why this happens?
Thank you in advance!
Try this:
replace
<input type="button" class="btn btn-default" ng-click="annulSupp()" value="cancel" />
with
<input type="button" class="btn btn-default" ng-click="annulSupp($event)" value="cancel" />
and replace $scope.annulSupp() function with below code
$scope.annulSupp = function(event) {
event.preventDefault();
$modalInstance.close();
};
Related
Using angularjs here:
I have looked at the following forum for my query but not able to resolve this :returning data from angularjs modal dialog service
I have the following modal html:
<div class="confirm-modal-header">
<h4 class="modal-title">{{modalOptions.headerText}}</h4>
</div>
<div class="modal-body">
<p>{{modalOptions.bodyText}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn"
data-ng-click="modalOptions.close()">
{{modalOptions.closeButtonText}}
</button>
<button type="button" class="btn btn-danger"
data-ng-click="modalOptions.ok();">
{{modalOptions.actionButtonText}}
</button>
</div>
I also have the service for this:
CTApp.factory("dialogModalService", ["$q", "$timeout", "$state", "$modal",
function ($q, $timeout, $state, $modal) {
var service = {}
var modalDefaults = {
backdrop: true,
keyboard: true,
modalFade: true,
templateUrl: '/app/modal.html'
};
var modalOptions = {
closeButtonText: 'Close',
actionButtonText: 'OK',
headerText: 'Proceed?',
bodyText: 'Perform this action?'
};
service.showModal = function (customModalDefaults, customModalOptions) {
if (!customModalDefaults) customModalDefaults = {};
customModalDefaults.backdrop = 'static';
return this.show(customModalDefaults, customModalOptions);
};
service.show = function (customModalDefaults, customModalOptions) {
//Create temp objects to work with since we're in a singleton service
var tempModalDefaults = {};
var tempModalOptions = {};
//Map angular-ui modal custom defaults to modal defaults defined in service
angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
//Map modal.html $scope custom properties to defaults defined in service
angular.extend(tempModalOptions, modalOptions, customModalOptions);
if (!tempModalDefaults.controller) {
tempModalDefaults.controller = function ($scope, $modalInstance) {
$scope.modalOptions = tempModalOptions;
$scope.modalOptions.ok = function (result) {
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
$modalInstance.dismiss('cancel');
};
}
}
return $modal.open(tempModalDefaults).result;
};
return service;
}
]);
And the above modal is being called from my controller as:
dialogModalService.showModal({}, modalOptions).then(function (result)
{
//check for result returned
}
Now in my controller I want to check whether the user pressed the cancel button or not. How can I check that?
I tried to pass the cancel along with
modalOptions.close('cancel')
But it never enters my controller loop of the dialogModalService.showModal.
In my browser also I tried to put a breakpoint inside the call above but again its never hit.
What am I doing wrong here?
In your Modal service try changing:
$modalInstance.dismiss('cancel');
to
$modalInstance.close('cancel');
I am trying to show a simple yes/no modal but I run from one issue into another. The current error message I am getting is:
Error: [$injector:unpr] http://errors.angularjs.org/1.6.1/$injector/unpr?p0=%24modalInstanceProvider%20%3C-%20%24modalInstance%20%3C-%20MessageDialogCtrl
at http://localhost:8080/web/bower_components/angular/angular.min.js:6:425
at http://localhost:8080/web/bower_components/angular/angular.min.js:44:395
at Object.d [as get] (http://localhost:8080/web/bower_components/angular/angular.min.js:42:92)
at http://localhost:8080/web/bower_components/angular/angular.min.js:44:457
at d (http://localhost:8080/web/bower_components/angular/angular.min.js:42:92)
at e (http://localhost:8080/web/bower_components/angular/angular.min.js:42:333)
at Object.invoke (http://localhost:8080/web/bower_components/angular/angular.min.js:42:418)
at R.instance (http://localhost:8080/web/bower_components/angular/angular.min.js:93:35)
at http://localhost:8080/web/bower_components/angular-bootstrap/ui-bootstrap.min.js:8:30298
at http://localhost:8080/web/bower_components/angular/angular.min.js:133:460 Possibly unhandled rejection: {}
Here are the essential parts which are responsible for the modal to show up:
index.js
var emaApp = angular.module('emaApp', ['ui.bootstrap']);
function showMessageDialog($scope, $uibModal, title, message, buttons) {
var messageScope = $scope.$new(true);
messageScope.title = title;
messageScope.message = message;
messageScope.buttons = buttons;
var modalInstance = $uibModal.open({
templateUrl: 'js/messages/message-dlg.html',
controller: 'MessageDialogCtrl',
scope: messageScope
});
//setupKeyHandling(modalInstance);
return modalInstance;
}
emaApp.controller('mainCtrl', ['$scope', '$http', '$uibModal', function($scope, $http, $uibModal) {
$scope.deleteModel = function(modelId) {
showMessageDialog($scope, $uibModal, 'Delete model',
'Do you really want to delete the model "' + modelId + '"?',
['Yes', 'No', 'Cancel'])
.result.then(function(result) {
alert('working..');
});
}
}]);
message-dlg-controller.js
/**
* The controller for the yes/no/cancel.
*/
emaApp.controller('MessageDialogCtrl', [ '$scope', '$modalInstance', function($scope, $modalInstance) {
$scope.primary = [ 'yes', 'ok' ];
$scope.caption = {
'yes' : 'Ja',
'no' : 'Nein',
'ok' : 'OK',
'cancel' : 'Abbrechen'
};
$scope.close = function(button) {
if (button == 'cancel') {
$modalInstance.dismiss();
} else {
$modalInstance.close(button);
}
}
} ]);
message-dlg.html
<div class="modal-header">
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
<p>{{message}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn"
data-ng-class="primary.indexOf(b) != -1 ? 'btn-primary' : 'btn-default'"
data-ng-repeat="b in buttons" data-ng-click="close(b)">{{caption[b]}}</button>
</div>
Included scripts:
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
<script src="js/index.js"></script>
<script src="js/messages/message-dlg-controller.js"></script>
plnkr.co/edit/CeVr0heB2Av7vveCTUQ?p=preview
Changes : Use $uibModalInstance instead of $modalInstance
I am using Angular based UI grid. I want to show another grid on row right-click. The the ID field of the row is to be passed to DB using http.post. The returned data to be displayed in another grid in modal. Here is what I am doing
rowTemplate :
rowTemplate: '....'
appScopeProvider:
appScopeProvider: $scope.myAppScopeProvider,
$scope.myAppScopeProvider = {
showMenu: function (row) {
var modalInstance = $modal.open({
controller: 'ContextController',
templateUrl: 'ngTemplate/ContextMenu.html',
resolve: {
selectedRow: function () {
//getTable(row.entity);
return row.entity;
}
}
});
modalInstance.result.then(function (selectedItem) {
console.log('modal selected Row: ' + selectedItem);
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
},
app.controller('ContextController',
['$scope', '$modal', '$modalInstance', '$filter', '$interval','$http' , 'selectedRow',
function ($scope, $modal, $modalInstance, $filter, $interval, $http, selectedRow) {
$scope.selectedRow = selectedRow;
$scope.rel_details = function () {
$scope.nodeName_rel = selectedRow.NodeName;
$scope.fromTime_rel = "2015-11-11";
$scope.toTime_rel = "2016-12-21";
$http.post('../getData', { nodeName: $scope.nodeName_rel, trapType: 'All', startTime: $scope.fromTime_rel, endTime: $scope.toTime_rel })
.success(function (data) {
console.log(data);
$scope.gridOptions1.data = data;
});
//$scope.selectedRow = null;
//$modalInstance.close();
};
ContextMenu.html :
<script type="text/ng-template" id="ngTemplate/ContextMenu.html">
<div class="modal-header">
<h4>Context Menu</h4>
</div>
<div class="modal-body">
<button class="btn btn-primary btnCustom" ng- click="rel_details()">Grouped Details</button>
<div id="grid_rel" ui-grid="gridOptions1" class="grid"></div>
</div>
<div class="modal-footer">
<button class="btn btn-primary btnCustom" ng-click="ok()">OK</button>
<!--<button class="btn btn-primary btnCustom" ng- click="cancel()">Cancel</button>-->
</div>
</script>
I'd like to use angular component with ui.bootstrap.modal. angular version is 1.5.
I tried to use like below.
component
function MyComponentController($uibModalInstance){
var ctrl = this;
ctrl.doSomething = function() {
//doSomething
}
}
app.component('myComponent', {
contoller: MyComponentController,
templateUrl: '/path/to/myComponent.html'
}
parent controller
function parentController($uibModal){
var ctrl = this;
ctrl.openModal = function(){
var modalInstance = $uibModal.open({
template: '<my-component></my-component>'
}
}
And when I execute parentController.openModal() , I got the error of $injector:unpr Unknown Provider although modal window is open.
Is there a way to use angular component with ui.bootstrap.modal?
If you need more information, please let me know that.
Thank you.
EDIT
I've got a way to use component with ui.bootstrap.modal from Renato Machado, Thanks Renato.
But I feel It's a little bit complicated and not convenient. So finally I think that it's better to use component inside the modal.
Modal is opened with regular way(just set controller and template in $uibModal.open({}) ) and the modal contains the component which has logics you want to use commonly.
Modal should have only simple logics that are related with modal like close modal window.
Another logics mainly related with business/Application should be in component.
It makes easy to commonalize.
EDIT: As of UI Bootstrap 2.1.0 there is native support for component in bootstrap modals. It looks like there have been several quick releases after 2.1.0 to fix some issues with the modals, so I'd be sure to grab the latest.
See this Plunk for a version using UI Bootstrap 2.1.0+
http://plnkr.co/edit/jy8WHfJLnMMldMQRj1tf?p=preview
angular.module('app', ['ngAnimate', 'ui.bootstrap']);
angular.module('app')
.component('myContent', {
template: 'I am content! <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open Modal</button>',
controller: function($uibModal) {
$ctrl = this;
$ctrl.dataForModal = {
name: 'NameToEdit',
value: 'ValueToEdit'
}
$ctrl.open = function() {
$uibModal.open({
component: "myModal",
resolve: {
modalData: function() {
return $ctrl.dataForModal;
}
}
}).result.then(function(result) {
console.info("I was closed, so do what I need to do myContent's controller now. Result was->");
console.info(result);
}, function(reason) {
console.info("I was dimissed, so do what I need to do myContent's controller now. Reason was->" + reason);
});
};
}
});
angular.module('app')
.component('myModal', {
template: `<div class="modal-body"><div>{{$ctrl.greeting}}</div>
<label>Name To Edit</label> <input ng-model="$ctrl.modalData.name"><br>
<label>Value To Edit</label> <input ng-model="$ctrl.modalData.value"><br>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleClose()">Close Modal</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleDismiss()">Dimiss Modal</button>
</div>`,
bindings: {
modalInstance: "<",
resolve: "<"
},
controller: [function() {
var $ctrl = this;
$ctrl.$onInit = function() {
$ctrl.modalData = $ctrl.resolve.modalData;
}
$ctrl.handleClose = function() {
console.info("in handle close");
$ctrl.modalInstance.close($ctrl.modalData);
};
$ctrl.handleDismiss = function() {
console.info("in handle dismiss");
$ctrl.modalInstance.dismiss("cancel");
};
}]
});
Original answer is below:
I was trying to figure this out the other day too. I took the information I found in this post along with this link to try and come up with an alternate way to accomplish this. These are some reference links I found that helped me:
https://github.com/angular-ui/bootstrap/issues/5683
http://www.codelord.net/ (this one helped in understanding passing arguments to callbacks in components)
Also here is a Plunk: http://plnkr.co/edit/PjQdBUq0akXP2fn5sYZs?p=preview
I tried to demonstrate a common real world scenario of using a modal to edit some data.
angular.module('app', ['ngAnimate', 'ui.bootstrap']);
angular.module('app')
.component('myContent', {
template: 'I am content! <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open Modal</button>',
controller: function($uibModal) {
$ctrl = this;
$ctrl.dataForModal = {
name: 'NameToEdit',
value: 'ValueToEdit'
}
$ctrl.open = function() {
$uibModal.open({
template: '<my-modal greeting="$ctrl.greeting" modal-data="$ctrl.modalData" $close="$close(result)" $dismiss="$dismiss(reason)"></my-modal>',
controller: ['modalData', function(modalData) {
var $ctrl = this;
$ctrl.greeting = 'I am a modal!'
$ctrl.modalData = modalData;
}],
controllerAs: '$ctrl',
resolve: {
modalData: $ctrl.dataForModal
}
}).result.then(function(result) {
console.info("I was closed, so do what I need to do myContent's controller now and result was->");
console.info(result);
}, function(reason) {
console.info("I was dimissed, so do what I need to do myContent's controller now and reason was->" + reason);
});
};
}
});
angular.module('app')
.component('myModal', {
template: `<div class="modal-body"><div>{{$ctrl.greeting}}</div>
<label>Name To Edit</label> <input ng-model="$ctrl.modalData.name"><br>
<label>Value To Edit</label> <input ng-model="$ctrl.modalData.value"><br>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleClose()">Close Modal</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleDismiss()">Dimiss Modal</button>
</div>`,
bindings: {
$close: '&',
$dismiss: '&',
greeting: '<',
modalData: '<'
},
controller: [function() {
var $ctrl = this;
$ctrl.handleClose = function() {
console.info("in handle close");
$ctrl.$close({
result: $ctrl.modalData
});
};
$ctrl.handleDismiss = function() {
console.info("in handle dismiss");
$ctrl.$dismiss({
reason: 'cancel'
});
};
}],
});
There is no need to make it more complicated by passing along the parent controller, you can just access it from within the .component that displays the modal.
Component
/**
* #ngdoc component
* #name fsad.component:video
*
* #description <fsad-video> component, in development...
*
*/
(function () {
'use strict';
angular.module('fsad').component('fsadVideo', {
bindings: {},
templateUrl: function(appConstant){return appConstant.paths.modules.fsad + 'leefloon/fsad-video.html'},
controller: controller
});
controller.$inject = ['$scope'];
function controller($scope){
var $ctrl = this;
setDataModel();
/****************************************************************/
$ctrl.ui.close = close;
/****************************************************************/
function setDataModel(){
$ctrl.ui = {};
}
function close(){
$scope.$parent.$close();
}
}
}());
Opening the modal
var modalInstance = $uibModal.open({
backdrop: 'static',
keyboard: true,
backdropClick: false,
template: '<fsad-video></fsad-video>',
windowClass: 'edit-contactenblad',
});
Since you are stating that the template is a component, the $scope.$parent will always be pointing to the modal instance. Allowing you to access the $close() function.
Passing and receiving data
If you need to pass data to the component, or receive data back from the component, you can do it like this.
var modalInstance = $uibModal.open({
backdrop: 'static',
keyboard: true,
backdropClick: false,
template: '<fsad-video method="$ctrl.method" on-viewed="$ctrl.userHasViewedVideo(time)"></fsad-ideo>',
controller: function(){
this.method = method;
this.userHasViewedVideo = function(time){}
},
controllerAs: '$ctrl',
windowClass: 'edit-medewerker',
});
Just on a side note, i'm using this structure style guide to create the component.
If you want access to the $uibModal's $close() and $dismiss() functions, along with some parent data and function binding within your component, you can pass them all along as such:
Open Modal Logic
$uibModal.open({
template: '<login close="$close()" dismiss="$dismiss()" ' +
'email="$ctrl.cookieEmail" check-login="$ctrl.ajaxLogin(user, pass)"></login>',
controller: function () {
this.cookieEmail = $cookies.get('savedEmail');
this.ajaxLogin = AjaxLoginService.login;
},
controllerAs: '$ctrl'
});
Modal Login Component
{
templateUrl: 'view/login.html',
bindings: {
email: '<',
checkLogin: '&',
close: '&',
dismiss: '&'
},
controller: function () {
var viewModel = this;
viewModel.password = '';
viewModel.submit = function () {
viewModel.checkLogin(
{ user: viewModel.email, pass: viewModel.password }
).then(function (success) {
viewModel.close();
});
}
}
}
Modal HTML
<form ng-submit="$ctrl.submit()">
<input type="text" ng-model="$ctrl.email" />
<input type="password" ng-model="$ctrl.password" />
<button type="button" ng-click="$ctrl.dismiss()">Cancel</button>
<button type="submit">Login</button>
</form>
The AngularJS 1.5 docs are a little sparse, but they show the usage of the & binding as a function wrapper: https://docs.angularjs.org/guide/component
You need to pass the parent controller to the modal component with the modal instance on it. To do that you need to append the generate HTML of the modal in the parent component
parent component
$ctrl.openModal = function(){
$ctrl.modalInstance = $uibModal.open({
template: '<your-modal></your-modal>',
appendTo : $document.find('parentComponent')
});
}
modal component
.component('yourModal', {
templateUrl: 'path/to/modal.html',
replace: true,
require: {
parent : '^parentComponent'
},
controller: ModalCtrl
});
function ModalCtrl() {
var $ctrl = this;
$ctrl.$onInit = function(){
var instance = $ctrl.parent.modalInstance;
$ctrl.items = ['item1', 'item2', 'item3'];
$ctrl.selected = {
item: $ctrl.items[0]
};
$ctrl.ok = function () {
instance.close($ctrl.selected);
};
$ctrl.cancel = function () {
instance.dismiss('cancel');
};
instance.result.then(function (selectedItem) {
$ctrl.selected = selectedItem;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
}
Be carefull because the required controller will only be available after the $onInit.
I have an angular-bootstrap modal that I have created a custom directive for so that the input field will autofocus on open. I have added the directive template to my input tag, but on inspect element, it's nowhere to be seen. Code:
Directive (copied from: How to set focus on input field?)
'use strict';
angular.module('portfolioManager.directives', []).directive('focusMe', function($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function(scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function(value) {
console.log('value=',value);
if(value === true) {
$timeout(function() {
element[0].focus();
});
}
});
// to address #blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function() {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
});
HTML:
<div class='panel-heading report'>
<h1 class='port-title port-manager-header title custom-inline'>Portfolios</h1>
<div ng-controller="ModalCtrl" class='create-new-frame'>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">New Portfolio</h3>
</div>
<form name='eventForm'>
<div class="modal-body">
<input class='form-control' ng-model='portfolios.portName' placeholder='Portfolio name' ng-required='true' maxlength="35" focus-me="shouldBeOpen">
<span class="help-inline" ng-show="notUnique">Portfolio name already used</span>
<br>
<div ng-init="radioModel = 'Right'; portfolios.groupSelection = false" class="btn-group">
<label class="btn btn-primary" ng-model="radioModel" ng-click='portfolios.groupSelection = true' btn-radio="'Left'">Group</label>
<label class="btn btn-primary" ng-model="radioModel" ng-click='portfolios.groupSelection = false' btn-radio="'Right'">Private</label>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok(portfolios.portName)" ng-disabled="eventForm.$invalid || notUnique" id='portfolio-modal-create-button'>Create</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</form>
</script>
<button class="btn btn-sm btn-primary create-new-frame-btn" ng-click="open('sm')">Create New</button>
</div>
</div>
ModalCtrl:
'use strict';
angular.module('portfolioManager').controller('ModalCtrl', 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());
});
};
});
You need to create the modal somehow in your code and trigger it to be displayed. You just defined the template, now you have to use it. See http://angular-ui.github.io/bootstrap/#/modal
Example from the docs:
angular.module('ui.bootstrap.demo').controller('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());
});
};
});
Use the templateUrl attribute to link to your modal template and create a trigger to call open from the UI (for instance: <span ng-click="open()">Open Modal</span>).