I have a project where I'm using the ui.bootstrap, and according to the tutorial I followed I have to set it up similar to this:
'use strict';
angular.module('academiaUnitateApp')
.controller('EntryCtrl', function ($scope, $modal) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalCtrl'
})
};
});
'use strict';
angular.module('academiaUnitateApp')
.controller('ModalCtrl', function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.delete = function () {
$modalInstance.dismiss('cancel');
};
});
<script type="text/ng-template" id="modal.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<p class="alert alert-danger">
WARNING: By deleting the article all it's nested articles will be moved to the article holding this one.
<br/>
Do you still want to delete this article?
</p>
<button class="btn btn-primary" ng-click="delete()">Yes</button>
<button class="btn btn-primary" ng-click="cancel()">No</button>
<span ng-show="error.state" class="alert alert-danger">{{ error.message }}</span>
<span ng-show="done.state" class="alert alert-success">{{done.message}}</span>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
This works find and all, but what if I want to move the $scope.delete function inside the EntryCtrl controller instead of having it in a separate controller?
You can pass in anonymous controller. That would allow you to have all the logic in a single file.
In your case it would look like this:
'use strict';
angular.module('academiaUnitateApp')
.controller('EntryCtrl', function ($scope, $modal) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: [
'$scope', '$modalInstance', function($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.delete = function () {
$modalInstance.dismiss('cancel');
};
}
]
})
};
});
EDIT
You can pass variables by defining resolve function and adding variables in inner controller definition. I have used this to pass values in one-way fashion but never for two-way binding. I think you should be able to pass outer scope as well.
I don't know if it works, so be warned! :)
'use strict';
angular.module('academiaUnitateApp')
.controller('EntryCtrl', function ($scope, $modal) {
$scope.myValue = 'foobar';
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: [
'$scope', '$modalInstance', 'outerScope', function($scope, $modalInstance, outerScope) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.delete = function () {
$modalInstance.dismiss('cancel');
};
}
],
resolve: {
outerScope: function() {
return $scope;
}
}
})
};
});
PS. Haven't tested code above, just put it together from your provided code
For more details see my answer here:
https://stackoverflow.com/a/29461685/3070052
Related
I am very new to js overall so please be patient with me.
I need to make a simple task which is stated in the topic. I have done some research and tried to make using ui.router but since I am not very good with coding something went wrong.
I want that this information from url would be displayed inside the modal dialogue http://prntscr.com/ashi5e
So here is the code:
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
<!doctype html>
<html ng-app="plunker">
<head>
<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>
<script src="js/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>Log</h3>
</div>
<div class="modal-body">
Content
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>
<button class="btn" ng-click="open()">Log</button>
</div>
</body>
</html>
You need to get the data (eg. with a service) and put it into $scope.items. In your modal do the same: get items and bind it to your scope. That's all
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log, $http) {
/* Get data here with a service or smth */
$scope.items = '';
$scope.open = function () {
$http.get("YOUR_URL")
.then(function(response) {
$scope.items = response.data
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
<!doctype html>
<html ng-app="plunker">
<head>
<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>
<script src="js/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>Log</h3>
</div>
<div class="modal-body">
{{items}}
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>
<button class="btn" ng-click="open()">Log</button>
</div>
</body>
</html>
You didn't registered modalDemoCtrl and ModalInstanceCtrl at first you need to register both controller like: myApp.controller('modalDemoCtrl', ModalDemoCtrl); where myApp is angular module like: var myApp = angular.module('plunker', ['ui.bootstrap']);.
you can use a service to get data from an url by using$http and that service inject in your modalInstance controller. in my example create dataService and a function named getData and called this function from modalInstance controller. like: dataService.getData().then(.. and use then function to get response. and store response data in to $scope.infos variable so you can use this $scope.infos in your modal.
var myApp = angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
};
myApp.controller('modalDemoCtrl', ModalDemoCtrl);
myApp.factory('dataService', function($http) {
return {
getData: function() {
return $http.get('http://prnt.sc/ashi5e');
}
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, items, dataService) {
dataService.getData().then(function(response) {
$scope.infos = response.data;
});
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
myApp.controller('ModalInstanceCtrl', ModalInstanceCtrl);
I'm having some issues transferring the modal example from the angular-ui documentation here: https://angular-ui.github.io/bootstrap/#/getting_started
I keep running into this error:
Argument 'ModalInstanceCtrl' is not a function, got undefined
controller:
(function () {
'use strict';
angular
.module('projMgrApp')
.controller('forumController', forumController)
forumController.$inject = ['$scope', '$window', '$uibModal', 'Notices'];
function forumController($scope, $window, $uibModal, Notices) {
$scope.Notices = Notices.query();
$scope.successText = "Temp Success Message";
$scope.MessageTitle = "Temp Msg Title";
$scope.MessageText = "Temp Msg Text";
angular.module('projMgrApp').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, MessageText, messageTitle) {
$scope.MessageText = MessageText;
$scope.MessageTitle = MessageTitle;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
$scope.OnAddNoticeClick = function () {
var EditNoticeModal = $uibModal.open({
templateUrl: 'add-edit-modal.html',
controller: 'ModalInstanceCtrl',
resolve: {
MessageText: function () { return $scope.MessageText },
MessageTitle: function () { return $scope.MessageTitle }
}
});
};
}
})();
the modal is spawned from a ui button that runs the OnAddNoticeClick fn.
I managed to get it to work by switching the style of controller to:
angular.module('projMgrApp')
.controller('ModalInstanceCtrl', ModalInstanceCtrl);
ModalInstanceCtrl.$inject = ['$scope', '$uibModalInstance', 'MessageText', 'MessageTitle'];
function ModalInstanceCtrl($scope, $uibModalInstance, MessageText, MessageTitle) {
$scope.MessageText = MessageText;
$scope.MessageTitle = MessageTitle;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
};
I have a framework that is supposed to be router agnostic, and while I have gotten it to work with ngRoute, I cannot for the life of me to get it to work with UI Router
The main app module Looks like this:
(function () {
"use strict";
angular.module("app", ["ptFramework", "ui.router", "ngStorage", "ui.bootstrap"]);
})();
The framework is built on three modules using custom directives the first module is the framework module
Here is the module:
(function () {
"use strict";
angular.module("ptFramework", [,"ptMenu", "ptDashboard"]);
})();
The module that I am having trouble with is the Menu module Below is the menu module:
(function () {
"use strict";
angular.module("ptMenu", ["ngAnimate"]);
})();
In index.html I have included a custom directive which looks something like this:
HTML:
<pt-menu>
<pt-menu-item label="Dasboard" icon="fa-tachometer" state="dashboard"></pt-menu-item>
<pt-menu-group label="Patients" icon="fa-users">
<pt-menu-item label="Patients" icon="fa-users" state="patient"></pt-menu-item>
<pt-menu-item label="Enter Results" icon="fa-area-chart" state="enterresults"></pt-menu-item>
<pt-menu-item label="View Results" icon="fa-area-chart" state="viewresults"></pt-menu-item>
</pt-menu-group>
<pt-menu-group label="Providers" icon="fa-user-md">
<pt-menu-item label="Providers" icon="fa-user-md" state="provider"></pt-menu-item>
<pt-menu-item label="Injury Dict." icon="fa-book" state="injurydictionary"></pt-menu-item>
<pt-menu-item label="Excercise Dict." icon="fa-book" state="excercisedictionary"></pt-menu-item>
</pt-menu-group>
<pt-menu-group label="Therapist" icon="fa-user-md">
<pt-menu-item label="Therapist" icon="fa-user-md" state="therapist"></pt-menu-item>
<pt-menu-item label="Program Entry" icon="fa-user-md" state="programentry"></pt-menu-item>
<pt-menu-item label="Results" icon="fa-area-chart" state="results"></pt-menu-item>
<pt-menu-item label="Excercises" icon="fa-bicycle" state="excercise"></pt-menu-item>
</pt-menu-group>
</pt-menu>
Here is the directive for Menu item:
(function () {
"use strict";
angular.module('ptMenu').directive('ptMenuItem', function () {
return {
require: '^ptMenu',
scope: {
label: '#',
icon: '#',
state: '#'
},
templateUrl: 'ext-modules/ptMenu/ptMenuItemTemplate.html',
link: function (scope, el, attr, ctrl) {
scope.isActive = function () {
return el === ctrl.getActiveElement();
};
scope.isVertical = function () {
return ctrl.isVertical() || el.parents('.pt-subitem-section').length > 0;
}
el.on('click', function (evt) {
evt.stopPropagation();
evt.preventDefault();
scope.$apply(function () {
ctrl.setActiveElement(el);
ctrl.setState(scope.state);
});
});
}
};
});
})();
As you can see I have state in the directive so that I can use it in my mark up. There is a el.onclick event that calls the parent controllers setState function.
That controller is here:
ptMenuController:
(function () {
"use strict";
angular.module('ptMenu').controller('ptMenuController',
['$scope', '$rootScope',
function ($scope, $rootScope) {
$scope.isVertical = true;
$scope.openMenuScope = null;
$scope.showMenu = true;
$scope.allowHorizontalToggle = true;
this.getActiveElement = function () {
return $scope.activeElement;
};
this.setActiveElement = function (el) {
$scope.activeElement = el;
};
this.isVertical = function () {
return $scope.isVertical;
}
this.setState = function (state) {
$rootScope.$broadcast('pt-menu-item-selected-event',
{ state: state });
};
This broadcasts to the next controller in the chain which is framework controller.
Framework Controller:
(function () {
"use strict";
angular.module("ptFramework").controller("ptFrameworkController",
['$scope', '$window', '$timeout', '$rootScope', '$state',
function ($scope, $window, $timeout, $rootScope, $state) {
$scope.isMenuVisible = true;
$scope.isMenuButtonVisible = true;
$scope.isMenuVertical = true;
$scope.$on('pt-menu-item-selected-event', function (evt, data) {
$scope.stateString = data.state;
$state.go(data.state);
checkWidth();
broadcastMenuState();
});
This message is getting to the front end with the correct state, but it is complaining about my controller, and when I comment out the controller I get no view
Here is the route config file
(function () {
"use strict";
angular.module('app').config([
'$stateProvider', "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state("dashboard", {
url: "/dashboard",
template: "<pta-dashboard></pta-dashboard>"
})
.state("patient", {
url: "/patient",
temlateUrl: "app/patient/patientViewTemplate.html",
controller: "patientController"
})
.state("enterresults", {
url: "/enterresults",
templateUrl: "app/patient/enterResultsTemplate.html",
controller: "patientController"
})
.state("viewresults", {
url: "/viewresults",
templateUrl: "app/patient/viewResultsTemplate.html",
controller: "patientController"
})
.state("provider", {
url: "/provider",
templateUrl: "app/provider/providerVierTemplate.html",
controller: "providerController"
})
.state("injurydictionary", {
url: "/injurydictionary",
templateUrl: "app/provider/injuryDictionaryTemplate,html",
controller: "providerController"
})
.state("excercisedictionary", {
url: "/excercisedictionary",
templateUrl: "app/provider/excerciseDictionaryTemplate.html",
controller: "providerController"
})
.state("therapist", {
url: "/therapist",
templateUrl: "app/therapist/therapistViewTemplate.html",
controller: "therapistController"
})
.state("programentry", {
url: "/programentry",
templateUrl: "app/therapist/programEntryTemplate.html",
controller: "therapistController"
})
.state("results", {
url: "/results",
templateUrl: "app/results/resultsViewTemplate.html",
controller: "resultsController"
})
.state("excercise", {
url: "/excercise",
templateUrl: "app/excercise/excerciseViewTemplate.html",
controller: "excerciseController"
})
.state("programs", {
url: "/programs",
templateUrl: "app/programs/programsViewTemplate.html",
controller: "programsController"
});
$urlRouterProvider.otherwise( "/dashboard");
}
]);
})();
I am stumped on this, as is everybody I have spoken with. I have sucessfully made this work with ngRoute. I should also be getting my directive should be showing up as well. I have my ui-sref in place in the frameworkTemplate.html
<div class="pt-title-bar">
<div class="row">
<div class="pt-logo-area col-sm-6">
<img class="pt-icon" ng-src="{{ iconFile }}" />
<div class="pt-title-area">
<p class="pt-logo-title">{{ title }}</p>
<p class="pt-logo-subtitle">{{ subtitle }}</p>
</div>
<div ng-if="isMenuButtonVisible" ng-click="menuButtonClicked()"
class="pt-collapsed-menu pull-right">
<button type="button" class="btn pt-nav-button">
<i class="fa fa-bars"></i>
</button>
</div>
</div>
<div class="pt-right-side-controls col-sm-6">
<pt-user-profile-small></pt-user-profile-small>
</div>
</div>
Any thoughts or input would be appreciated, I am getting ready to abandon the broadcast all together and go to ui-srefs in the index.html. But that feels like giving up.
Thanks,
John
This is apparently a known issue with UI-Router and custom directives
https://github.com/angular-ui/ui-router/pull/858
I want to pass a whole object to modal, so I can view all of its attributes there. Right now I have items that look like this:
$scope.items = [{ Title: title, Id: id }]
In my html page i am using a 'ng-repeat', something like this:
<tr ng-repeat="item in items | filter:search">
<td> {{item.Title}} </td>
<td> {{item.Id}} </td>
<td> <button ng-controller="ModalDemoCtrl" type="button" ng-click="viewItem(item)" class="btn btn-primary">View Item</button> </td>
and my modal html page:
<div class="modal-header">
<h3>{{Title }}</h3>
</div>
<div class="modal-body">
<p>{{ Id }}</p>
</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>
Only enough to see if we can get our two values.
But I have no idea how my modalController should look like, I can't seem to pass the whole item (with only title, and id so far) to the modal view.
I have followed the example on the angular bootstrap github page when making my controller:
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.viewItem = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
angular.module('ui.bootstrap.demo').controller('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');
};
});
I am aware that this wont work, I can't type my actual controller at this moment, I will update later tonight with it. Any thoughts though on how this can be achieved?
If I understand correctly what you are after you don't need to pass the whole list of items to your modal, you should only pass the item the user has clicked on. This is actually the item that is passed as argument to your viewItem function, so you would have something like this:
$scope.viewItem = function (selectedItem) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
item: function () {
return selectedItem;
}
}
});
}
and then in your modal controller:
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, item) {
$scope.title = item.title;
$scope.id = item.id
});
Or you can just assign the item being passed to your modal controller to the $scope.item variable and use {{item.title}} and {{item.id}} in your HTML instead.
I think you don't need to create another controller, you can use your current. And show modal window with directives ng-show or ng-if. It's not necessary use two controllers for one view. One controller - one view.
If you want create modal window and use it in different parts of your project, you can create directive and use it to create modal windows your application.
When creating the Items function I would pass an object so then you can call it in your modal ctrl like so:
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.viewItem = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return myItems: $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items.myItems;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
I have it working in my app like this. Hope it helps
I want to delete a record after pressing Ok on Modal Dialog in angularjs. It delete the item but not removing form $scope. I user $index in my html file. Can any one help me?? I am struck :(
My html file:
<script type="text/ng-template" id="admin.html">
<div class="modal-header">
<h3 class="modal-title">Are you Sure?</h3>
</div>
<div class="modal-body">
Are you sure??
</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 ng-click="open($index)">Open me!</button>
JS file:
$scope.open = function (user) {
var modalInstance = $modal.open({
templateUrl: 'admin.html',
controller: 'ModalInstanceCtrl',
windowClass: 'app-modal-window',
resolve: {
userIndex: function () {
return user
},
users: function () {
return $scope.users
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
});
};
app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, users, userIndex, services) {
$scope.users = users;
$scope.selected = {
user: $scope.users[userIndex]
};
$scope.ok = function () {
services.deleteCustomer($scope.selected.user.id);
$scope.users.splice(userIndex, 1);
$modalInstance.close($scope.selected.user);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});