How to access a form in a modal from a controller - angularjs

In my controller.js file I have:
angular.module('App').controller('AppCtrl', AppCtrl);
function AddApp(){
var vm = this;
vm.resetForm = resetForm;
function resetForm(){
vm.myForm.$setPristine();
}
}
...
function openModal(message){
var errorMessage = message;
var modalInstance = $modal.open({
templateUrl: 'url',
controller: 'AppCtrl',
controllerAs: 'App',
resolve: {
errorMessage: function () {
return errorMessage;
}
}
});
}
and in my modal I have
<div ng-controller="AppCtrl as App">
<form name=App.myForm>
...
when I use this format it tells me that
vm.myForm is undefined.
This is the closest thing I've found here, but it still did not work for me
Can I access a form in the controller?

You can pass the form by adding it to the resolve:
var modalInstance = $modal.open({
templateUrl: 'url',
controller: 'AppCtrl',
controllerAs: 'App',
resolve: {
errorMessage: function () {
return errorMessage;
},
myForm: function() {
return vm.myForm;
}
}
});
In your modal controller:
angular.module('app').controller('AppCtrl',
['$scope', 'errorMessage', 'myForm',
function ($scope, errorMessage, myForm) {
console.log(myForm);
}]
);

Related

AngularJS combine uib modal to a service

I try to open a modal with the uibModal (https://angular-ui.github.io/bootstrap/#!#%2Fmodal) but I want to have one modal with custom text inside.
i'm trying to open the modal like this :
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: '/crims/thermofluor/experiments/components/modal.html',
size: 'sm',
controller: 'ModalController',
resolve: {
content: function () {
return 'test';
}
}
});
With this controller :
angular
.module('thermofluor')
.controller('ModalController', ModalController)
ModalController.$inject = ['$uibModal', '$uibModalInstance'];
function ModalController($uibModal, $uibModalInstance, content) {
var $ctrl = this;
$ctrl.content = content;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss();
};
}
But it seems not work, angular says that ModalController is not a function (in the modal opening ), so what can I do to get this works ?
Edit : I can do that without a ModalController :
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: 'components/modal.html',
size: 'sm',
controller: function($scope) {
$scope.content = 'bottom';
}
});
But the buttons of my modal doesn't work
Edit
This finally works, here is how I do this :
function openModal(templateName, content, title){
var template = 'components/modal/'+templateName;
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: template,
size: 'sm',
controllerAs: '$ctrl',
controller: function($scope, $uibModalInstance) {
$scope.content = content;
$scope.title = title;
var $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
}
Finally I found a solution, here is what I do :
I create a service ModalService :
angular.module('myModule')
.factory('ModalService', ModalService);
ModalService.$inject = ['$uibModal'];
function ModalService($uibModal) {
return new ModalService();
function ModalService(){
var service = this;
function openModal(templateName, params){
var template = 'components/modal/'+templateName;
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: template,
size: 'sm',
controllerAs: '$ctrl',
controller: function($scope, $uibModalInstance) {
angular.forEach(params, function (e, key){
$scope[key] = e;
});
var $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
}
return {
openModal: openModal
};
}
}
And I use it like this in my controller :
ModalService.openModal("modal.html", {"content": "This experiment doesn't have a tm point", "title": "Tm Point"});
I can pass every variable I need and just set them in my modal html template

AngularJS: Angular UI Bootstrap, pass data from modal to controller

I have correctly setup my angular modal, now I want to pass my modal data back to my controller. I am using the below code.
First my controller calls my factory service that creates the modal popup:
$scope.mymodal = myService.openModal(data);
My service is as:
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
modalInstance.result.then(function () {
return;
}, function () {
});
return modalInstance;
}
See my jsfiddle here for this: http://jsfiddle.net/aman1981/z20yvbfx/17/
I want to pass name & gender that i select on my modal back to my controller, which then populates my page. Let me know what is missing here.
I updated AboutController, ModalController and myService with comments.
Main idea is return data from ModalController with close method. Fiddle
var app = angular.module('myApp', ['ui.router','ui.bootstrap']);
app.controller('IndexController', function($scope, $log) {
});
app.controller("AboutController", ['$location', '$state', '$scope', '$filter','myService', function($location, $state, $scope, $filter, myService) {
var data = "";
$scope.mymodal = myService.openModal(data);
// after modal is close, then this promise is resolve
$scope.mymodal.then(function(resp){
console.log(resp);
})
}]);
app.controller("ModalController", function($location, $state, $scope, $filter, $modalInstance) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$state.go('index');
};
$scope.done = function () {
// return data on close modal instance
$modalInstance.close({genger:$scope.gender,userName:$scope.userName});
};
});
app.factory('ApiFactory', function ($http) {
var factory = {};
return factory;
});
app.factory("myService",[ "$state", "$modal", "ApiFactory",
function ($state, $modal, factory) {
var service = {
openModal: openModal
};
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
// on close, return resp from modal
modalInstance.result.then(function (resp) {
return resp;
}, function () {
});
// return modal instance promise
return modalInstance.result;
}
return service;
}
]);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index', {
url: '^/index',
templateUrl: 'index.html',
controller: "IndexController"
})
.state('about', {
url: '^/about',
templateUrl: 'about.html',
controller: "AboutController"
})
}]);

$stateParams won't pass the values

I am trying to pass an object by a simple $state.go(), but all I get is default values 0 and ""
angular ui router:
placesApp.config(($stateProvider, $urlRouterProvider) => {
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("home", {
url: "/home",
templateUrl: "views/search-result.html",
controller: "HomeCtrl"
})
.state("placeDetail", {
url: "/place-detail",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeId: 0,
placeImg: ""
}
})
});
The link that triggers the function:
<a ui-sref="placeDetail" class="place-name" ng-bind="place.venue.name" ng-click="goToPlaceDetail()"></a>
Place detail function, I should not that this is not HomeCtrl. It is in a directive related to HomeCtrl:
placesApp.directive("placeGrid", () => {
return {
restrict: "E",
replace: true,
controller: ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
var imgObj = $scope.place.venue.photos.groups[0].items[0];
var placeId = $scope.place.venue.id;
var placeImg = imgObj.prefix + "1280x600" + imgObj.suffix;
var placeInfo = {placeId: placeId, placeImg: placeImg};
$scope.goToPlaceDetail = () => {
$state.go("placeDetail", {placeInfo: placeInfo});
};
}],
templateUrl: "views/place-grid.html"
}
});
placeDetail controller:
placesApp.controller("PlaceDetailCtrl", ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
$scope.placeId = $stateParams.placeInfo.placeId;
$scope.placeImg = $stateParams.placeInfo.placeImg;
}]);
Don't create new placeInfo property. just pass the object.
var placeInfo = {placeId: placeId, placeImg: placeImg};
$scope.goToPlaceDetail = () => {
$state.go("placeDetail", placeInfo);
};
And access the property like this
$scope.placeId = $stateParams.placeId;
OR
add a new property to state
.state("placeDetail", {
url: "/place-detail",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeInfo: {
placeId: 0,
placeImg: ""
}
}
})
Sorry Have you tried something like:
In your app.config:
.state("placeDetail", {
url: "/place-detail/:placeId/:placeImg",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeId: 0,
placeImg: ""
}
})
then in your HTML:
<a ui-sref="placeDetail({id:place.venue.id,placeImg:place.venue.name})" class="place-name" ></a>
then in your controller (or where you need to get them from url):
placesApp.controller("PlaceDetailCtrl", ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
function init(){
$scope.placeId = $stateParams.placeId;
$scope.placeImg = $stateParams.placeImg;
}
init();
}]);

templateUrl not rendering when modal opened from iFrame

I have a situation in the application, where I want to load an already available modal, in an iFrame of another application using the same codebase. For this I have used the following code :
new-user-module.js
(function () {
'use strict';
angular
.module('mo.pages.new-user.layouts', ['ui.router', 'ui.bootstrap', 'mo.pages.new-user.services'])
.config(['$stateProvider', newUserRouteConfiguration]);
function newUserRouteConfiguration($stateProvider) {
$stateProvider
.state('new-user', {
url: '/new-user',
onEnter: [
'mo.pages.new-user.services.NewUserPageService', function (newAttachmentPageService) {
newAttachmentPageService.openAttachmentModal();
}
]
});
}})();
new-user-service.js
(function () {
'use strict';
angular
.module('mo.pages.new-user.services')
.service('mo.pages.new-user.services.NewUserPageService', NewUserPageServiceFactory);
NewUserPageServiceFactory.$inject = [
'$stateParams',
'$modal'
];
function NewUserPageServiceFactory($stateParams, $modal) {
var service = {
openUserModal: openUserModal
};
return service;
function openUserModal() {
return function () {
$modal.open({
templateUrl: 'modules/pages/shared/modals/new-user/new-user-modal.html',
controller: 'mo.pages.shared.modals.NewUserModalController as vm',
windowClass: 'new-user-modal',
resolve: {
headerText: function() {
return 'header';
}
},
backdrop: 'static',
size: 'lg'
});
};
}
}})();
The issue, I am facing is that, the modal is loading, when the '/new-user' is getting called in the iFrame, but the templateUrl is not loading.
Check your console, I think you may find an error with your call to newAttachmentPageService.openAttachmentModal();
Since NewUserPageServiceFactory is registered as a service and not really a factory, it should not return anything. You should just be adding the method to the service object, for example:
function NewUserPageServiceFactory($stateParams, $modal) {
this.openUserModal = function() {
return function () {
$modal.open({
templateUrl: 'modules/pages/shared/modals/new-user/new-user-modal.html',
controller: 'mo.pages.shared.modals.NewUserModalController as vm',
windowClass: 'new-user-modal',
resolve: {
headerText: function() {
return 'header';
}
},
backdrop: 'static',
size: 'lg'
});
};
}
}
For a good illustration of the (slight) differences between services and factories see here
Let me know if this works

use a bootstrap modal without making a seperate controller

I am using a bootstrap modal
Controller.js -
$scope.open = function() {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'views/template.html',
controller: 'controller2',
resolve: {
items: function() {
return $scope.values;
}
}
});
modalInstance.result.then(function(values) {
$scope.new_value = values;
}, function() {
});
};
I don't want to create a new controller since the modal should show values which are constantly changing in the current controller. What should I pass in place of controller2 if I modal to be in the same controller?
You could use the scope option instead of the controller:
$scope.open = function() {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'views/template.html',
scope: $scope,
resolve: {
items: function() {
return $scope.values;
}
}
});
modalInstance.result.then(function(values) {
$scope.new_value = values;
}, function() {
});
};

Resources