Angular bootstrap modal - javascript

i have some directive:
.directive("modal", [function(){
var controller = function($scope, $attrs, $element, $uibModal){
var defaultOptions = {
title: "Modal title",
content: "Modal body"
},
userOptions = {
title: $attrs.title,
content: $attrs.content,
templateUrl: $attrs.templateUrl,
templateController: $attrs.templateController
};
options = angular.extend({},defaultOptions, userOptions || {});
$element.on($scope.event, function(){
$uibModal.open({
templateUrl: defaultTemplate,
controller: "DefaultModalController",
resolve: {
options: function () {
return options
}
}
});
});
},
defaultTemplate = "templates/default-modal-template.html";
return {
restrict: "A",
scope: {
event: "#"
},
controller: ["$scope", "$attrs", "$element", "$uibModal", controller]
}
}])
I using angular bootstrap modal, and I want something like this:
<section>
<header class="modal-header">
<h3 class="modal-title">{{modalOptions.title}}</h3>
</header>
<div class="modal-body" ng-if="modalOptions.templateUrl">
{{modalOptions.content}}
</div>
<div class="modal-body" ng-if="modalOptions.templateUrl" ng-include="modalOptions.templateUrl" ng-controller="modalOptions.templateController"></div>
<footer class="modal-footer">
<button type="button" class="btn btn-danger" ng-click="close()">Close</button>
</footer>
</section>
Of course it's not working because there is no controller like modalOptions.templateController, I want controller name under this variable.
Short: I need something like directive compile in bootstrap modal

Currently I created multiple views for different controllers

Related

AngularJS Bootstrap Modal $modalInstance.dismiss is not a function

When I click the cancel button on my modal, the $modalInstance.dismiss function binded with ng-click on my modal template isn't working.
The console has been throwing the error: "$modalInstance.dismiss is not a function"
MODAL TEMPLATE:
<div class="my-modal ng-scope" id="my-modal">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Create a new room</h3>
</div>
<div class="modal-body" id="modal-body">
<form>
Enter a room name<br>
<input type="text" name="new-room-name">
</form>
<div class="modal-footer">
<button class="btn btn-warning" type="button" ng-click="modal.cancel()">Cancel</button>
<button class="btn btn-primary" type="button" ng-click="modal.save()">Create Room</button>
</div>
</div>
MAIN CONTROLLER:
(function() {
function HomeCtrl(Room, $scope, $uibModal, $log, $document) {
var home = this;
home.chatRooms = Room.all;
//TO TEST ADD METHOD FROM ROOM.JS
// this.addRoom = Room.add();
home.open = function () {
modalInstance = $uibModal.open({
animation: true,
backdrop: true,
templateUrl: '../templates/modal.html',
controller: 'ModalInstanceCtrl',
controllerAs: 'modal',
bindToContoller: true,
scope: $scope,
size: 'lg',
resolve: {
'$modalInstance': function () { return function () { return modalInstance; } }
}
});
console.log(modalInstance);
modalInstance.result.then(function (newChatRoom) {
home.selected = newChatRoom;
console.log(newChatRoom);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
angular
.module('blocChat')
controller('HomeCtrl', ['Room', '$scope', '$uibModal', '$log', '$document', HomeCtrl]);
})();
MODAL CONTROLLER:
(function() {
function ModalInstanceCtrl(Room, $scope, $modalInstance, $log, $document) {
var modal = this;
this.save = function() {
$modalInstance.close(newChatRoom);
};
this.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
angular
.module('blocChat')
.controller('ModalInstanceCtrl', ['Room', '$scope', '$modalInstance', '$log', '$document', ModalInstanceCtrl]);
})();
I've spent about 3 hours messing around with my code, looking at the AngularJS Bootstrap UI documentation, several StackOverflow threads, and other sites and have gotten no where. Any help would be appreciated.
In the version of angular ui bootstrap you're using, the reference to the modal instance is called $uibModalInstance. So try changing your controller to this:
(function() {
function ModalInstanceCtrl(Room, $scope, $uibModalInstance, $log, $document)
{
var modal = this;
this.save = function() {
$uibModalInstance.close(newChatRoom);
};
this.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
}
angular
.module('blocChat')
.controller('ModalInstanceCtrl', ['Room', '$scope', '$uibModalInstance', '$log', '$document', ModalInstanceCtrl]);
})();

Issue with the controller of a UI Bootstrap Modal

I am new to Angular. I have created a component with a template (panel.html) and a controller (allPanelsRetrieved). When a specific button defined in the template is clicked, the showDetails() function specified in the controller is called. This function triggers the opening of a modal dialog specified by a template (panel-list.details-template.html) and a controller, which are both defined inside the allPanelsRetrieved controller. The problem is that the modal dialog is displayed but the controller doesn't work (the click of the OK button does nothing). Where the problem may be? Thanks in advance
angular.
module('panelList')
.component('panelList', {
templateUrl: '/panel-list/panel.html',
controller: ['Panel', 'NgTableParams','$scope', '$location', '$uibModal',
function PanelListController(Panel, NgTableParams, $scope, $location, $uibModal) {
this.allPanelsRetrieved = (index, before) => {
//..hidden code here
}
this.showDetails = function () {
$uibModal.open({
templateUrl: '/panel-list/panel-list.details-template.html',
controller: function ($uibModalInstance) {
let $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
},
}).result.then(
function (success) {
alert(success);
},
function (error) {
alert(error);
}
);
};
}]
});
Here is the template panel-list.details-template.html:
<div>
<script type="text/ng-template" id="/panel-list/panel-list.details-template.html">
<div class="modal-header">
<h3 class="modal-title">Modal title</h3>
</div>
<div class="modal-body">
Modal content
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$ctrl.ok()">Close</button>
</div>
</script>
Use $scope to make it work in the AngularJS way. Here is a working plnkr demo of what you try to achieve.
$uibModal.open({
templateUrl: '/panel-list/panel-list.details-template.html',
controller: function ($uibModalInstance, $scope) {
$scope.ok = function () {
$uibModalInstance.close();
};
}
}).result.then(
function (success) {
alert(success);
},
function (error) {
alert(error);
}
);
View
<script type="text/ng-template" id="/panel-list/panel-list.details-template.html">
<div class="modal-header">
<h3 class="modal-title">Modal title</h3>
</div>
<div class="modal-body">
Modal content
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">Close</button>
</div>
</script>
While the angular.component implementation provides a default for the controllerAs syntax...
controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
...it appears that angular-ui-bootstrap does not.
Simply provide a value for controllerAs in your $uibModal options to continue using the preferred syntax.
$uibModal.open({
templateUrl: '/panel-list/panel-list.details-template.html',
controllerAs: '$ctrl',
controller: function($uibModalInstance) {
let $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
}
}
http://plnkr.co/edit/q1arN18553XoUZEuPcPl?p=preview
The problem is with this keyword as you are using it. Use arrow function instead and it will work:
$uibModal.open({
templateUrl: '/panel-list/panel-list.details-template.html',
controller: ($uibModalInstance) => {
let $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
},
})

Having trouble to pass data to a modal in AngularJS

I have the following code
$scope.currentTask = undefined;
$scope.openModal = function (task, size, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'homeController',
controllerAs: '$ctrl',
scope: $scope,
size: size,
appendTo: parentElem,
resolve: {
items: function () {
return $scope.items;
}
}
});
$rootScope.currentModal = modalInstance;
$rootScope.currentModal.result.then(function () {
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
}
$scope.setTask = function(task) {
$scope.currentTask = task;
}
$scope.log = function (currentTask) {
console.log($scope.currentTask);
}
<div class="row" ng-init="processPages()">
<div class="panel panel-default col-xs-3" style="margin: 20px" ng-repeat = "list in pages[currentPage]">
<div class="panel panel-default">
<div class="panel-heading">
<h6 style = "float: right">({{list.tasks.length}})</h6>
<div class="panel-title">
<h4>{{list.name}}</h4>
</div>
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-hover" ng-init = "tasks = list.tasks">
<tr ng-repeat="task in tasks">
<td ng-click="setTask(task); openModal(task);>
<h5>{{task.name}}</h5>
</td>
</tr>
</table>
</div>
</div>
</div>
<script type="text/ng-template" id="myModalContent.html">
<div ng-init="editEnabled = false">
<div class="modal-header" ng-init = "log(currentTask)">
<h3 class="modal-title" id="modal-title" ng-show = "!editEnabled">Not editing</h3>
<h3 class="modal-title" id="modal-title" ng-show = "editEnabled">Editing</h3>
</div>
<div class="modal-body" id="modal-body">
<div ng-show="!editEnabled">
</div>
<div ng-show="editEnabled">
</div>
</div>
<div class="modal-footer">
<button style = "float: left" class="btn btn-primary" type="button" ng-show = "!editEnabled" ng-click="editEnabled = true">Editar</button>
<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>
</div>
</script>
Here's how the page is working:
First we have a list of tasks and if we click on one task...
...we get a model
I'd like the task information to be passed to the model, but everytime I set the task on the $scope to be the task on the list, even though it happens before the model is opened the log function prints the currentTask is still undefined. I've tried to change the currentTask definition at the beggining to be something concrete, but what happens then is the log function prints what was defined at the beggining and not after the change is made.
The only solution I could find that worked was creating a different controller for the modal and sharing data between modalController and homeController via service. It's working fine, here's the service:
var app = angular.module('agendaApp');
app.service('sharedModalProperties', function() {
var task = undefined;
var activeModal = undefined;
return {
setCurrentTask : function (task) {
this.task = task;
},
getCurrentTask : function () {
return this.task;
},
setActiveModal : function (modal) {
this.modal = modal;
},
getActiveModal : function () {
return this.modal;
}
}
});
The task being undefined indicates the modal popup's ($scope) is not aware of any such model data. I assume its creating a fresh scope object, so your call to setTask() does not work as it is working on old scope. You can try calling during your modal display code.
$scope.openModal = function (task, size, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'homeController',
controllerAs: '$ctrl',
scope: $scope,
size: size,
appendTo: parentElem,
resolve: {
items: function () {
return $scope.items;
}
}
});
$rootScope.currentModal = modalInstance;
$rootScope.currentModal.result.then(function () {
}, function () {
$log.info('Modal dismissed at: ' + new Date());
}
//Add this code
$scope.currentTask = task;
//Or Call Set Task Here.
setTask(task);
);
}
From our discussion in the comments try something like this for your uibmodal's controller (See the git repo for the changes I made)
...
$scope.items = ["items1", "items2", "items3"];
var modalInstance = $uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
size: size,
appendTo: parentElem,
resolve: {
modalItems: function() {
console.log("items to send to modal", $scope.items);
return $scope.items;
}
},
controller: ['$scope', 'modalItems', function($scope, modalItems) {
console.log("items sent to modal", modalItems);
$scope.modalItems = modalItems;
}]
});
...
HTML:
<script type="text/ng-template" id="myModalContent.html">
{{modalItems}} <!-- Should show the array of items -->
</script>

Angularjs + model + pass parameters and object

I am using angularjs. I am trying to send parameters and object into the popup.
Click here:
Html code:
<script src="https://code.angularjs.org/1.4.9/angular.min.js"></script>
<script src="https://rawgit.com/dwmkerr/angular-modal-service/master/dst/angular-modal-service.js"></script>
<div class="container" ng-app="app" ng-controller="Controller">
<h3>Angular Modal Service</h3>
<a class="btn btn-default" href ng-click="show()">Show a Modal</a>
<p>{{message}}</p>
<!-- The actual modal template, just a bit o bootstrap -->
<script type="text/ng-template" id="modal.html">
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close('Cancel')" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Yes ossssssssr No?</h4>
</div>
<div class="modal-body">
<p>It's your call...</p>
</div>
<div class="modal-footer">
<button type="button" ng-click="close('No')" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" ng-click="close('Yes')" class="btn btn-primary" data-dismiss="modal">Yes</button>
</div>
</div>
</div>
</div>
</script>
</div>
Js Code:
var app = angular.module('app', ['angularModalService']);
app.controller('Controller', function($scope, ModalService) {
$scope.url = 'google.com';
var obj= {};
obj.name = "test"
$scope.data = obj;
$scope.show = function() {
ModalService.showModal({
templateUrl: 'modal.html',
controller: "ModalController"
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = "You said " + result;
});
});
};
});
app.controller('ModalController', function($scope, close) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
});
How to pass the scope url and data values into the popup.
I saw few example to pass using resolve.
Please check my example
try this:
ModalService.showModal({
templateUrl: 'modal.html',
controller: "ModalController",
resolve : {
data: function () {
return $scope.data
}
}
})
in model controller you can get data like
app.controller('ModalController', function($scope, close, data) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
});
Call broadcast with data to Your modal, and catch event:
var app = angular.module('app', ['angularModalService']);
app.controller('Controller', function($scope, $rootScope, ModalService) {
$scope.url = 'google.com';
var obj= {};
obj.name = "test"
$scope.data = obj;
$scope.show = function() {
ModalService.showModal({
templateUrl: 'modal.html',
controller: "ModalController"
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$rootScope.$broadcast('ModalController:set', {message: "You said " + result});
});
});
};
});
app.controller('ModalController', function($scope, close) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
$scope.$on('ModalController:set', function(event, data) {
for(var i in data) {
$scope[i] = data[i];
}
});
});
"showModal" has a property with name "resolve".It lets you to share (pass) parameters to the controller.For example:
ModalService.showModal({
templateUrl: 'modal.html',
controller: "ModalController",
resolve : {
data: function () { // ro you can pass a value in stead of function
return $scope.data
}
}
})
And in controller you can inject it like services or use it with scope like scope.data

Parameter not Resolving in Angular Modal

I'm creating a simple update modal. To do so, I'm passing a parameter into my angular-bootstrap modal. I've two controllers, ModalCtrl and ModalInstanceCtrl:
adminController.controller('ModalCtrl', ['$scope', '$modal', '$log', 'Profile',
function ($scope, $modal, $log, Profile) {
$scope.open = function (profile) {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
profile: function () {
$log.info(profile);
return profile;
}
}
});
modalInstance.result.then(function (updatedProfile) {
$log.info(updatedProfile);
Profile.post(updatedProfile);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}]);
adminController.controller('ModalInstanceCtrl', function ($scope, $modalInstance, profile) {
$scope.ok = function () {
$modalInstance.close(profile);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
The profile is logged both when opening and accepting the modal - leading me to believe that it's being passed into the instance without issue. However, displaying the modal doesn't display anything from that profile object:
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">Profile View</h3>
</div>
<div class="modal-body">
<div><p>{{profile.profileType}}</p></div>
</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>
What am I doing wrong?
You need to put the profile object on the $scope for it to be accessible in the HTML template:
adminController.controller('ModalInstanceCtrl', function ($scope, $modalInstance, profile) {
$scope.profile = profile;
$scope.ok = function () {
$modalInstance.close(profile);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});

Categories