How to pass controller into modal view - javascript

I've been on this for an unhealthy length of time. Initially, modal.open only darkened the screen without any dialog box coming up. Then I used windowTemplateUrl to override templeteUrl and it showed.
Now nothing from the controller passes through; neither the cancel() function nor data from API seem to work. Any possible solution would be very welcome.
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$uibModal', 'loc8rData'];
function locationDetailCtrl($routeParams, $uibModal, loc8rData) {
var vm = this;
vm.locationid = $routeParams.locationid;
loc8rData.locationById(vm.locationid)
.success(function(data) {
vm.data = {
location: data
}
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
var modalInstance = $uibModal.open({
templateUrl: "/reviewModal/reviewModal.view.html",
backdrop: true,
//windowClass: 'show',
windowTemplateUrl: "/reviewModal/reviewModal.view.html",
controller: 'reviewModalCtrl as vm',
//size: 'sm',
resolve: {
locationData: function() {
return {
locationid: vm.locationid,
locationName: vm.data.location.name
};
}
}
});
};
}
})();
//modal controller
(function() {
angular
.module('loc8rApp')
.controller('reviewModalCtrl', reviewModalCtrl);
reviewModalCtrl.$inject = ['$uibModalInstance', 'locationData'];
function reviewModalCtrl($uibModalInstance, locationData) {
var vm = this;
vm.locationData = locationData
//create vm.modal.cancel() method and use it to call $modalInstance.dismiss method
vm.modal = {
cancel: function() {
$uibModalInstance.dismiss('cancel');
}
};
}
})();
<div class="container modal-content">
<form id="addReview" name="addReview" role="form" class="form-horizontal">
<div class="modal-header">
<button type="button" ng-click="vm.modal.cancel()" class="close"><span aria-hidden="true">x</span><span class="sr-only">Close</span></button>
<h4 id="myModalLabel" class="modal-title">Add your review for {{ vm.locationData.locationName }}</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="name" class="col-xs-2 col-sm-2 control-label">Name</label>
<div class="col-xs-10 col-sm-10">
<input id="name" name="name" required="required" ng-model="vm.formData.name" class="form-control" />
</div>
</div>
<div class="form-group">
<label for="rating" class="col-xs-10 col-sm-2 control-label">Rating</label>
<div class="col-xs-12 col-sm-2">
<select id="rating" name="rating" ng-model="vm.formData.rating">
<option>5</option>
<option>4</option>
<option>3</option>
<option>2</option>
<option>1</option>
</select>
</div>
</div>
<div class="form-group">
<label for="review" class="col-sm-2 control-label">Review</label>
<div class="col-sm-10">
<textarea id="review" name="review" rows="5" required="required" ng-model="vm.formData.reviewText" class="form-control"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button ng-click="cancel()" type="button" class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>

I use like this, in rootController of the app I make this:
$rootScope.openMsgModal = function (modalSettings) {
var defaultSettings = {
title: "Title",
msg: "Message",
icon: "fa-info-circle",
iconColor: "#c83637",
clickAction: "ok",
isCancelVisible: false,
templateUrl: 'views/templates/popups/alertMessage.html',
controller: 'ModalAlertController',
translations: {
confirmButton: "common.button_confirm",
cancelButton: "common.button_cancel"
}
}
angular.extend(defaultSettings, modalSettings);
var modalInstance = $uibModal.open({
templateUrl: defaultSettings.templateUrl,
controller: defaultSettings.controller,
size: 'md',
resolve: {
modalSettings: function () {
return defaultSettings;
}
}
});
return modalInstance;
};
}
...and then, where I need to use modal I have this:
var modalInstance = $uibModal.open( {
animation: true,
templateUrl: 'views/templates/popups/alertMessage.html',
controller: 'ModalAlertController',
resolve: {
modalSettings: function() {
angular.extend(defaultSettings, modalSettings);
return defaultSettings;
}
}
});

Related

AngularJS 1.6.8: Unable to submit form and display success message

I have a simple query submission form with name, email and query fields and a component with a controller function having the submit function to submit the form.
I am using ng-submit directive in the <form></form> tag to submit the user input and display a success message on submission.
below is the code for the respective files.
contact.html
<div ngController="contactController as vm">
<div class="heading text-center">
<h1>Contact Us</h1>
</div>
<div>
<form class="needs-validation" id="contactForm" novalidate method="post" name="vm.contactForm" ng-submit="saveform()">
<div class="form-group row">
<label for="validationTooltip01" class="col-sm-2 col-form-label">Name</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipName" placeholder="Name" ng-model="vm.name" required>
<div class="invalid-tooltip">
Please enter your full name.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltipEmail" class="col-sm-2 col-form-label">Email</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="validationTooltipUsernamePrepend">#</span>
</div>
<input type="email" class="form-control" id="validationTooltipEmail" placeholder="Email"
aria-describedby="validationTooltipUsernamePrepend" ng-model="vm.email" required>
<div class="invalid-tooltip">
Please choose a valid email.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltip03" class="col-sm-2 col-form-label">Query</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipQuery" ng-model="vm.query" placeholder="Query" required>
<div class="invalid-tooltip">
Please write your Query.
</div>
</div>
</div>
<div class="btn-group offset-md-5">
<button class="btn btn-primary" type="submit">Submit</button>
<button class="btn btn-default" type="button" id="homebtn" ng-click="navigate ('home')">Home</button>
</div>
</form>
<span data-ng-bind="Message" ng-hide="hideMessage" class="sucessMsg"></span>
</div>
</div>
contact.component.js
angular.module('myApp')
.component('contactComponent', {
restrict: 'E',
$scope:{},
templateUrl:'contact/contact.html',
controller: contactController,
controllerAs: 'vm',
factory:'userService',
$rootscope:{}
});
function contactController($scope, $state,userService,$rootScope) {
var vm = this;
$scope.navigate = function(home){
$state.go(home)
};
$scope.saveform = function(){
$scope.name= vm.name;
$scope.email= vm.email;
$scope.query= vm.email;
$scope.hideMessage = false;
$scope.Message = "Your query has been successfully submitted."
};
$scope.user = userService;
};
//localStorage code
function userService($rootScope) {
var service = {
model: {
name: '',
email: '',
query:''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (sessionStorage.restorestate == "true") {
$rootScope.$broadcast('restorestate'); //let everything know we need to restore state
sessionStorage.restorestate = false;
}
});
//let everthing know that we need to save state now.
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
};
UPDATE: On Submit, When I check the response in network tab in dev tools, I do not see the submitted values. All I see is the markup.
In your template, the name of the method is saveform:
ng-submit="saveform()"
But in your controller, it's save:
$scope.save = function() { ... }
Rename it to saveform:
$scope.saveform = function() { ... }

how to retain values while navigating across pages using component routing angular 1.5

Recently I have implemented angular 1.5 component routing. But I am not able to retain values while navigating across pages.
How can I retain values while navigating across page. have a look at this PLUNKER . This is very basic example of two page navigation.
When I enter/select value on Page 1 and I move to Next Page. When I come to Previous Page all values reset, It's not retaining values. How can we achieve retaining values while navigating across pages?? This example having only two page navigation, In real application I will be having 5-10 page navigation.
If one can retain toggle selection. That would be great.
Here is my code:
JavaScript
(function(angular) {
'use strict';
var module = angular.module('app', ['ngComponentRouter']);
module.config(function($locationProvider) {
$locationProvider.html5Mode(true);
});
module.value('$routerRootComponent', 'myFirstApp');
module.component('myFirstApp', {
templateUrl: "mainview.html",
$routeConfig: [{
path: '/',
redirectTo: ['/First']
}, {
path: '/first',
name: 'First',
component: 'firstComponent'
}, {
path: '/second',
name: 'Second',
component: 'secondComponent'
}]
})
module.component('firstComponent', {
templateUrl: "1.html",
controllerAs: "vm",
controller: function($rootScope) {
$rootScope.title = "Title from Page 1";
var vm = this;
vm.clusters = {};
vm.$onInit = $onInit;
vm.selectNumericValue = selectNumericValue;
vm.selectAlphaValue = selectAlphaValue;
// default selection
function $onInit() {
vm.clusters.numericValue = '111';
vm.clusters.alphaValue = 'AAA';
}
// setting numeric value
function selectNumericValue(numValue) {
vm.clusters.numericValue = numValue;
if (vm.clusters.numericValue === '111') {
vm.clusters.numericValue = '111';
} else {
vm.clusters.numericValue = '222';
}
}
function selectAlphaValue(alphaValue) {
vm.clusters.alphaValue = alphaValue;
if (vm.clusters.alphaValue === 'AAA') {
vm.clusters.alphaValue = 'AAA';
} else if (vm.clusters.alphaValue === 'BBB') {
vm.clusters.alphaValue = 'BBB';
} else {
vm.clusters.alphaValue = 'CCC';
}
}
}
});
module.component('secondComponent', {
templateUrl: "2.html",
controller: function($rootScope) {
$rootScope.title = "Title from Page 2";
},
});
})(window.angular);
HTML
<div class="well form-horizontal">
<div class="form-group" style="height: 50px;">
<label class="control-label col-md-4 col-sm-4 col-xs-4">NUMERIC VALUE</label>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="btn-group">
<button id="clusters-fc" type="button" class="btn btn-toggle" value="111" ng-class="{active: vm.clusters.numericValue === '111'}" ng-click="vm.selectNumericValue('111')">
111
</button>
<button id="clusters-ip" type="button" class="btn btn-toggle" value="222" ng-class="{active: vm.clusters.numericValue === '222'}" ng-click="vm.selectNumericValue('222')">
222
</button>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4 col-sm-4 col-xs-4">ALPHABETICAL VALUE</label>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="btn-group">
<button type="button" class="btn btn-toggle" ng-class="{active: vm.clusters.alphaValue === 'AAA'}" ng-click="vm.selectAlphaValue('AAA')">
AAA
</button>
<button type="button" class="btn btn-toggle" ng-class="{active: vm.clusters.alphaValue === 'BBB'}" ng-click="vm.selectAlphaValue('BBB')">
BBB
</button>
<button id="def-ip-tenGb" type="button" class="btn btn-toggle" ng-class="{active: vm.clusters.alphaValue === 'CCC'}" ng-click="vm.selectAlphaValue('CCC')">
CCC
</button>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4 col-sm-4 col-xs-4">Entered VALUE</label>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="btn-group">
<input type="textbox" class="form-control">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4 col-sm-4 col-xs-4">Selected VALUE</label>
<div class="col-md-6 col-sm-6 col-xs-6">
<div class="btn-group">
<select class="form-control" ng-model="vm.clusters.productionArrayType">
<option>111</option>
<option>222</option>
<option>333</option>
<option>444</option>
</select>
</div>
</div>
</div>
</div>
<a class="btn btn-success" ng-link="['Second']">Next Page</a>
attaching image of running sample:
You can use shared service for this:
module.service('sharedService', function() {
});
module.component('firstComponent', {
templateUrl: "1.html",
controllerAs: "vm",
controller: function($rootScope, sharedService) {
$rootScope.title = "Title from Page 1";
var vm = this;
vm.clusters = {};
vm.$onInit = $onInit;
vm.sharedService = sharedService;
vm.sharedService.selectNumericValue = selectNumericValue;
vm.sharedService.selectAlphaValue = selectAlphaValue;
...
});
<input type="textbox" ng-model="vm.sharedService.alphaValue" class="form-control">
UPDATE PLUNKER

Controller on Modal not working on AngularJS

I have a main users page with users, if you select a user, a modal is opened and should show the user information.
The problem is that the $scope doesn't seem to be working, as it doesn't show the user data on the modal. But if I show that user data anywhere on the main users page, it works fine.
I have this controller:
function userController($scope, $modal, $http, $rootScope) {
var usrCtrl = this;
$scope.users = null;
$scope.openUserForm = function () {
var modalInstance = $modal.open({
templateUrl: 'views/modal_user_form.html',
controller: userController,
windowClass: "animated flipInY"
});
};
var session = JSON.parse(localStorage.session);
$http({
method: 'GET',
url: $rootScope.apiURL+'getAllClientUsers/'+session,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(response){
if(response.ErrorMessage === null && response.Result !== null){
$scope.users = response.Result;
}
});
//**This is the code that opens the modal
$scope.editViewUser = function(user){
for (var key in $scope.users) {
if($scope.users[key].SecUserId === user){
$scope.selectedUser = $scope.users[key];
}
}
$scope.openUserForm();
};
};
And this modal:
<div ng-controller="userController">
<div class="inmodal">
<div class="modal-header">
<h4 class="modal-title">Create or Edit User</h4>
<small class="font-bold">Use this modal to create or edit a user</small>
</div>
<div class="modal-body">
<form method="get" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label">Nombre</label>
<div class="col-sm-10"><input ng-model="selectedUser.FirstName" type="text" class="form-control"></div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Apellido</label>
<div class="col-sm-10"><input ng-model="selectedUser.LastName" type="text" class="form-control"></div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Usuario</label>
<div class="col-sm-10"><input ng-model="selectedUser.UserName" type="text" class="form-control"></div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Email</label>
<div class="col-sm-10"><input ng-model="selectedUser.Email" type="email" class="form-control"></div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Activo</label>
<div class="col-sm-10">
<div><label> <input ng-model="selectedUser.FirstName" type="checkbox" value=""></label></div>
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Email Verificado</label>
<div class="col-sm-10">
<div><label> <input ng-model="selectedUser.FirstName" type="checkbox" value=""></label></div>
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">Privilegios</label>
<div class="col-sm-10">
<select class="form-control m-b" name="account">
<option ng-repeat="priv in selectedUser.EffectivePrivileges">{{ priv }}</option>
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" ng-click="cancel()">Close</button>
<button type="button" class="btn btn-primary" ng-click="ok()">Save changes</button>
</div>
</div>
</div>
I tried injecting the controller and also using the ng-controller, and scope property for modal.
What am I missing?
The problem is that modal template is compiled in the scope which doesn't inherit from your $scope. To make a connection between them you can tell modal to create a new child scope of your scope:
$scope.openUserForm = function () {
var modalInstance = $modal.open({
scope: $scope, // <----- add this instruction
templateUrl: 'views/modal_user_form.html',
controller: userController,
windowClass: "animated flipInY"
});
};
Generally, the modal would have its own controller rather than point to the controller that its called from. You would inject the model (selectedUser) into the modal controller, work on it, then pass it back to parent. Also, you can give user option to cancel in which case no changes are made to parent controller model.
Modal controller:
app.controller('UserModalController', [
'$scope',
'$modalInstance',
'selectedUser',
function ($scope, $modalInstance, selectedUser) {
$scope.selectedUser = selectedUser;
$scope.cancel= function () {
// user cancelled, return to parent controller
$modalInstance.dismiss('cancel');
};
$scope.save = function () {
// close modal, return model to parent controller
$modalInstance.close($scope.selectedUser);
};
]);
Changes to main controller:
var modalInstance = $modal.open({
templateUrl: 'views/modal_user_form.html',
controller: 'UserModalController',
windowClass: "animated flipInY",
resolve: {
selectedUser: function() {
return $scope.selectedUser;
}
}
});
modalInstance.result.then(function(updatedUser) {
// deal with updated user
}, function() {
// modal cancelled
});

What's wrong with angular $modal?

i want to return some rezult from radioboxes from modal window. I used Angular bootstrap for this. So my code doesn t return me radiobox value after closing the modal window.
Template code:
<div class="modal-header">
<h3 class="modal-title">Вы уверены, что хотите удалить категорию?</h3>
</div>
<div class="modal-body">
Выбирете способ удаления
<div class="form-group">
<label>
<input type="radio" ng-model="deleteType" value="this">
Удалить категорию включая её подкатегории
</label><br />
<label>
<input type="radio" ng-model="deleteType" value="select">
Удалить категорию и выбрать новую для подкатегорий
</label><br />
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger" ng-click="ok()">Delete</button>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
</div>
My controller:
$scope.delCat = function (index,el,current) {
var modalInstance = $modal.open({
templateUrl: 'view/category/dialog.html',
controller: 'modalDialogController',
size: 'sm',
resolve: {
deleteType: function () {
return $scope.deleteType;
}
}
});
var deleteOne = function(){
current.splice(index,1);
}
var deleteMore = function(){
alert('asdfasd');
}
modalInstance.result.then(function (deleteType) {
switch (deleteType) {
case 'this':
deleteOne();
break;
case 'select':
break;
}
});
};
mainApp.controller('modalDialogController', function ($scope, $modalInstance, deleteType) {
$scope.deleteType = 'this';
$scope.ok = function () {
$modalInstance.close($scope.deleteType);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Function $scope.ok() doesn t return value of $scope.deleteType after its closing.
Have a look at this plunkr. I've reproduced the modal with your code.
The value of the radio button, stored in deleteType, is correctly passed into the success callback of the result promise

how to pass data from modal to function

I have a modal form that has several inputs text form control. How do I pass the data to post to the database so that ng-grid gets updated?
do I call my ajax create function within the $scope.open controller section? or resolve?
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
}]);
the create function
$scope.createMedicalServices = function(){
var providerMedicalServiceAttributes = {};
providerMedicalServiceAttributes.cash_price = $scope.cash_price
providerMedicalServiceAttributes.average_price = $scope.average_price
providerMedicalServiceAttributes.service = $scope.service
var medicalServicesAttributes = {};
medicalServicesAttributes.description = $scope.description
medicalServicesAttributes.service = $scope.service
var newMedicalService = ProviderMedicalService.create(providerMedicalServiceAttributes);
$scope.provider_medical_services.push(newMedicalService);
ProviderMedicalService.update(providerMedicalServiceAttributes, '/providers/services');
};
create function from factory (factory does delete, querying and create)
ProviderMedicalService.prototype.create = function(attr){
return this.service.save(attr);
}
the html for the modal form
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="header-modal">
<h3>Add Service</h3>
</div>
<div class="modal-body">
<form name="myForm" novalidate ng-submit="submit()">
<div class="row well-text-padding">
<div class="col-md-3 modal-form-tag">CPT Code</div>
<div class="col-md-6">
<input type="text" class="form-control form-control-modal" ng-model="CPT_code" placeholder="CPT Code">
</div>
</div>
<label class="checkbox modal-check-box">
<input type="checkbox" ng-model="No_CPT_code">Service does not have a associated CPT Code
</label>
<div class="row well-text-padding">
<div class="col-md-3 modal-form-tag">Description</div>
<div class="col-md-6">
<textarea class="form-control form-control-modal" rows="3" ng-model="Description" placeholder="Add a Description"></textarea>
</div>
</div>
<div class="row well-text-padding">
<div class="col-md-3 modal-form-tag">Average Cost</div>
<div class="col-md-6">
<input type="text" class="form-control form-control-modal" ng-model="Average_cost" placeholder="$">
</div>
</div>
<div class="row well-text-padding">
<div class="col-md-3 modal-form-tag">Offered Price</div>
<div class="col-md-6">
<input type="text" class="form-control form-control-modal" ng-model="Offered_price" placeholder="$">
</div>
</div>
<div class="btn-row2 modal-button-row">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<button class="btn btn-primary" type="submit">Add Service</button>
</div>
</script>
You can make the POST request to server when clicked Add Service, or you can pass your data from modal to your main controller through $scope.$close().
Example as below:
In modal controller
var data = {
CPT_code: $scope.CPT_code,
No_CPT_code: $scope.No_CPT_code,
Description: $scope.Description,
Average_cost: $scope.Average_cost,
Offered_price: $scope.Offered_price
};
$scope.$close(data); // pass the data through modal close event
Then in your main controller by using the promise to get the data
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
}).result.then(function (response) {
var data = response; // here is your data from your modal
});
};
Hope this helps.

Categories