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
Related
So, I am creating a web app, where one page I have a user list and on the second page, I have the users details page. On the second page, I have a confirm button where I want to remove that user when the "Confirm" button is clicked with a 200 Status code. However, I am getting a DELETE : 405 (Method Not Allowed). So, here is my code down below. Please tell me or help me fix this problem. Thank you in advance.
Here is my code.
<div ng-controller="MyCtrl">
<div ng-repeat="person in userInfo.lawyers | filter : {id: lawyerId}">
<a class="back" href="#/lawyer">Back</a>
<button type="button" class="edit" ng-show="inactive" ng-click="inactive = !inactive">
Edit
</button>
<button type="submit" class="submit" ng-show="!inactive" ng-click="inactive = !inactive">Save</button>
<button class="btn btn-primary" ng-click="doDelete(id)">Confirm</button>
<div class="people-view">
<h2 class="name">{{person.firstName}}</h2>
<h2 class="name">{{person.lastName}}</h2>
<span class="title">{{person.email}}</span>
<span class="date">{{person.website}} </span>
</div>
<div class="list-view">
<form>
<fieldset ng-disabled="inactive">
<legend>Basic Info</legend>
<b>First Name:</b>
<input type="text" ng-model="person.firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="person.lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="person.email">
</fieldset>
</form>
</div>
</div>
</div>
Services
app.factory('people', function ($http) {
var service = {};
service.getUserInfo = function () {
return $http.get('https://api-dev.mysite.io/admin/v1/unconfirmed_lawyers');
};
service.confirmUser = function (lawyerId) {
return $http.put('https://api-dev.mysite.io/admin/v1/lawyers/{lawyerId}/confirm');
};
return service;
});
LawyerController
app.controller('LawyerController', ['$scope', 'people', '$routeParams',
function ($scope, people, $routeParams) {
$scope.lawyerId = $routeParams.id;
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
});
}]);
HomeController
var isConfirmed = false;
app.controller('HomeController', function($scope, people, $http) {
if (!isConfirmed) {
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
}, function (error) {
console.log(error)
});
}
});
App.js
$scope.doDelete = function(lawyer) {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
$scope.userInfo.lawyers.splice(index, 1);
location.href = '#/lawyer';
};
If you changed your HTML, so you passed the person instead.
<button class="btn btn-primary" ng-click="doDelete(person)">Confirm</button>
You can use this to find the index within the lawyers, then remove it.
$scope.doDelete = function(lawyer) {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
$scope.userInfo.lawyers.splice(index, 1)
};
The issue is your are using $http.delete which performs an HTTP Delete request. This doesn't sound like something you intended.
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!!
I have an event.controller.js and event.view.html
In the controller I have event and guests,
event is the form of multiple models and guests is 1 model with an array that I can pass more values too.
I have localStorage for events to save the form but guests array doesn't get passed into the form because they are seperated even though they're part of the same controller.
function EventController($location, UserService, EventService, $rootScope, $http, FlashService) {
var vm = this;
vm.guests = [];
vm.addGuest = function () {
vm.guests.push(vm.newGuest);
}
vm.removeGuest = function (guest) {
var index = vm.guests.indexOf(guest);
vm.guests.splice(index, 1);
}
vm.event = event;
function event() {
vm.dataLoading = true;
EventService.Create(vm.events)
.then(function (response) {
if (response.success) {
FlashService.Success('Event created successful', true);
$location.path('/events');
} else {
FlashService.Error(response.message);
vm.dataLoading = false;
}
});
}
my event.view.html looks like
<form name="form" ng-submit="vm.event()" role="form">
<!--All my event input fields-->
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary">Create</button>
Cancel
</div>
</form>
<form name="form" ng-submit="vm.guest()" role="form">
<div class="form-actions">
<button type="submit" ng-disabled="guestform.$invalid || vm.dataLoading" ng-click="vm.addGuest()" class="btn btn-primary">Add Guest</button>
</div>
<div ng-repeat="guest in vm.guests track by $index" class="col-sm-6">
{{guest}} - <a class="btn" ng-click="vm.removeGuest(guest)">Delete</a>
</div>
</form>
different forms submit to the same eventcontroller but are different model namespaces, how would I get a vm.events.guest array that is equal to the vm.guests after I add to it from the vm.addGuest() method?
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
Can't access form variable from my controller, when i try to access it by $scope.locationForm i've got 'undefined', but when i call console.log($scope) i can see in console there have loactionForm.
My HTML code
<div ng-controller="LocationsController as ctrl">
<form class="form-inline" name="locationForm">
<div class="form-group">
<!-- <div class="input-group"> -->
<label for="location-name">Название населенного пункта</label>
<input required
name="name"
ng-model="ctrl.location.name" type="text" class="form-control" id="location-name" placeholder="Название населенного пункта">
<label for="location-name">Район</label>
<select required
name="region_id"
ng-model="ctrl.location.region_id"
ng-options="region.id as region.name for region in ctrl.regions" class="form-control" placeholder="Название района"></select>
<input ng-click="ctrl.save()"
ng-disabled="locationForm.$invalid" type="submit" class="btn btn-default" value="Cохранить">
<a class="btn btn-default" ng-click="ctrl.reset()" ng-show="locationForm.$dirty">Сброс</a>
<!-- </div> -->
</div>
</form>
My Controller code:
function LocationsController($scope, Location, Region, $q) {
var lc = this,
l_index;
lc.form ={};
lc.regions = lc.locations = [];
lc.regions = Region.query();
lc.regions.$promise.then(function(data) {
lc.locations = Location.query();
});
lc.getRegion = function (id) {
return lc.regions.filter(function(obj) {
return obj.id == id;
})[0].name;
};
console.log($scope);
// console.log($scope.locationForm);
lc.reset = function () {
lc.location = new Location;
}
lc.reset();
};
The problem is when the LocationsController is initialized the form element is not yet compiled. So one possible hack is to use a timeout like
function LocationsController($scope, Location, Region, $q, $timeout) {
//then later
$timeout(function(){lc.reset();})
}