What's wrong with angular $modal? - javascript

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

Related

How to pass controller into modal view

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;
}
}
});

Check All checkbox function inside a modal

If user clicks 'add data' a modal opens, I have individual checkboxes for data1,data2,data3,data4. I also have a check all checkbox. If user clicks this, it should be able to select all above 4, if clicks again, it should deselect all. Also, once selected, the value of 'Select All' should change to 'Deselect All'
Code:
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<label><input type="checkbox" ng-model="checkboxModel.value1"> Data1</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value2"> Data2</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value3"> Data3</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value4"> Data4</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value5">Select All</label><br/>
</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>
<button type="button" class="btn btn-default" ng-click="open()">Add data</button>
</div>
Can someone let me know how to achieve this. I saw a lot of posts online but each had ng-repeat for the first 4 checkboxes. Mine is without using ng-repeat. Can someone please advise.
I have the following plunker: http://plnkr.co/edit/nSCGJzj1zG5SGO2N76L3?p=preview
I noticed that you were not binding to the items array. I fixed that by using the following markup:
<div ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.Selected">{{item.name}}</label>
<br/>
</div>
<label>
<input type="checkbox" ng-model="selectedAll" ng-click="checkAll()">Select All</label>
<br/>
After that, I had to change the structure of the items property to become an object for later binding:
$scope.items = [{
name: 'item 1'
}, {
name: 'item 2'
}, {
name: 'item 3'
}, ];
To be able to update all the other checkboxes, I resorted to the following code:
$scope.checkAll = function() {
if ($scope.selectedAll) {
$scope.selectedAll = true;
} else {
$scope.selectedAll = false;
}
angular.forEach($scope.items, function(item) {
item.Selected = $scope.selectedAll;
});
}
Please, refer to this plunker example for the full working solution.
UPDATE
Use the example here:
https://docs.angularjs.org/api/ng/directive/ngChecked#!
basically the trick is to add to all "slave" check boxes
ng-checked="checkboxModel.value5"
Well, first the explanation:
To select/deselect all the checkboxes, you can simply loop over the elements and setting all the checkbox to true/false.
To select/deselect this checkbox programatically, you can use Array.prototype.every() method, which returns if all checkboxes are selected or not, if all elements are selected that option will be/keep also selected, otherwise, it will be/keep deselected.
To get all the selected items when you close the modal you could use the Array.prototype.filter() method to return only the selected checkboxes.
Here's a snippet working:
(function() {
"use strict";
angular
.module('ui.bootstrap.demo', [
'ngAnimate',
'ui.bootstrap'
])
.controller('ModalDemoCtrl', ModalDemoCtrl)
.controller('ModalInstanceCtrl', ModalInstanceCtrl);
function ModalDemoCtrl($scope, $uibModal, $log) {
$scope.animationsEnabled = true;
$scope.open = function(size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
modalInstance.result.then(function(selectedItems) {
$scope.selected = selectedItems;
}, function() {
$log.info('Modal dismissed at: ', new Date());
});
}
$scope.toggleAnimation = function() {
$scope.animationsEnabled = !$scope.animationsEnabled;
}
}
// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
function ModalInstanceCtrl($scope, $uibModalInstance, items) {
$scope.items = [];
function loadData() {
var arr = [];
for (var i = 1; i <= 5; i++) {
arr.push({
"name": "Item " + i
});
}
return arr;
}
$scope.items = loadData();
$scope.check = function() {
$scope.selectedAll = $scope.items.every(function(value) {
return value.Selected;
});
}
$scope.selectAll = function() {
$scope.items.forEach(function(item) {
item.Selected = $scope.selectedAll;
});
}
function getChecked() {
return $scope.items.filter(function(value) {
return value.Selected;
});
}
$scope.ok = function() {
$uibModalInstance.close(getChecked());
}
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
}
}
})();
.main_div {
border: 1px solid red;
width: 30%;
margin: 50px;
padding: 2px;
}
<!DOCTYPE HTML>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.0.0/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<div class="checkbox" ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.Selected" ng-change="check()"> {{item.name}}
</label>
<br/>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="selectedAll" ng-click="selectAll()"> Select All
</label>
</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>
<button type="button" class="btn btn-default" ng-click="open()">Add data!</button>
</body>
</html>
If you want to see it in plunker, click here.
I hope it helps!!

Disable required attribute on one radio button

I have 3 radio buttons in a bootstrap modal and I want only 2 of them to be required in order to submit the form. I created a requiredCheck() function that's using a jQuery implementation so I'd rather not use this. What is the best way to disable the required attribute for one radio button, when using AngularJS?
HTML
<form name="jawn">
<div class="modal-header">
<h3 class="modal-title">Jawn</h3>
</div><!-- /modal-header -->
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<label for="optionsRadios">
<input type="radio" ng-model="$parent.data.status" name="optionsRadios" ng-value="item.id" required/ ng-click="requiredCheck()"> {{item.name}}
</label>
</li>
</ul>
<h4>Comment</h4>
<textarea ng-class="{error: thing.comment.$dirty && thing.comment.$invalid}" type="text" rows="3" cols="64" ng-model="data.comment" ng-minlength="4" ng-required></textarea>
<span class="error" ng-show="thing.comment.$error.required">required</span>
</div><!-- /modal-body-->
<div class="modal-footer">
<button type="submit" class="btn btn-warning" ng-click="ok()" ng-disabled="thing.$invalid">Part Jawn</button>
<button type="button" ng-click="cancel()" class="btn btn-default">Cancel</button>
</div>
</form>
JavaScript
angular.module('app')
.controller('ModalController', function($scope, $modalInstance, $timeout) {
'use strict';
$scope.item = 0;
$scope.items = [
"Zero": 0,
"Uno": 1,
"Dos": 2
];
$scope.requiredCheck = function () {
var $btnWarning = $('.btn-warning');
var $textarea = $('textarea');
$timeout(function() {
if($scope.data.status === item.Dos) {
$btnWarning.removeAttr('disabled');
$textarea.removeAttr('required');
} else if ($scope.data.status === 3) {
$btnWarning.prop('disabled',true);
$textarea.prop('required', true);
} else if ($scope.data.status === 3) {
$btnWarning.prop('disabled',true);
$textarea.prop('required', true);
}
},100);
};
$scope.ok = function () {
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$modalInstance.close();
};
});
You should use angualrjs approach. As you have already specified ngRequired set true/false from controller.
From DOCs
ngRequired: Sets required attribute if set to true
HTML
<textarea ng-model="data.comment" ng-required="textRequired"></textarea>
Script
$scope.requiredCheck = function () {
if(condition){
$scope.textRequired = false;
}else{
$scope.textRequired = true;
}
};
Note: I have simplified the answer

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.

How to submit a form using angular ui bootstrap's modal and csrf

I would like to submit a form using Angular UI Bootstrap's modal. I'm instantiating the modal like:
AdminUsers.factory('ProjectsService', ['$resource', function($resource) {
return $resource('/api/users?sort=createdAt desc');
}]).controller('AdminUsersCtrl', ['ProjectsService', '$scope', '$http', '$modal', '$log', function(ProjectsService, $scope, $http, $modal, $log, $modalInstance) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: '../templates/userModal.html',
controller: function($scope, $modalInstance) {
$scope.user = {};
$scope.ok = function () { $modalInstance.close($scope.user); };
$scope.cancel = function () { $modalInstance.dismiss('cancel'); };
},
resolve: {
items: function () {
return $scope.user;
}
}
});
modalInstance.result.then(function (user) {
$scope.user = user;
$http.post('/api/users/new', $scope.user).success(function() {
$scope.users.unshift($scope.user);
});
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
PS: Please note the controller above does have other methods that is not being displayed above.
The code in my userModal.html is:
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">×</button>
<h6>New customer</h6>
</div>
<div class="modal-body">
<form class="form-horizontal fill-up separate-sections">
<div>
<label>Name</label>
<input type="text" ng-model="user.name" placeholder="Name" />
</div>
<div>
<label>Email</label>
<input type="email" ng-model="user.email" placeholder="Email" />
</div>
<div>
<label>Admin</label>
<select class="form-control" ng-model="user.admin"
ng-options="option as option for option in [true, false]"
ng-init="user.admin=false"></select>
<input type="hidden" name="user.admin" value="{{user.admin}}" />
</div>
<div>
<label>Password</label>
<input type="password" ng-model="user.password" placeholder="Password" />
</div>
<div>
<label>Password confirmation</label>
<input type="password" ng-model="user.confirmation" placeholder="Password confirmation" />
</div>
<div class="divider"><span></span></div>
<div class="divider"><span></span></div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-blue btn-lg" ng-click="ok()">Save</button>
<button class="btn btn-default btn-lg" ng-click="cancel()">Cancel</button>
<input type="hidden" name="_csrf" value=_csrf />
</div>
The problem lies with the hidden input. I need to submit the csrf with form to the server but I don't know how. If this was a jade template I could simply:
input(type="hidden", name="_csrf", value=_csrf)
and Sails/Express would deal with the rest. But because this is a html template used by Angular only, I don't know how to access the _csrf key. I've tried looking into window.document.cookie however it returned undefined.
Can anyone shed some light on this?
Many thanks

Categories