I'm using AngularJs & Javascript for my very first application. I'm triying to show info from an API as a checkbox. Right now it's working, but, how can i validate if any of the checkbox options are checked with a submit button?
I was searching here in stackoverflow and find a way, but it's working only with the last option. Here's a part of my html:
<form name="imtesting" ng-submit="imtesting.$valid && validate()" ng-show="$ctrl.coupons.length > 0">
<ul>
<li ng-repeat="c in $ctrl.coupons">
<input type="checkbox"
name="couponBox"
ng-checked="c.Select"
ng-click="$ctrl.selectOne(c)"
ng-model="formData.couponBox" required/>{{c.CodeCoupon}}
<br>
</li>
</ul>
<span ng-show="submitted == true && imtesting.couponBox.$error.required">Select at least one cupon!</span></form>
And the button:
<button type="submit" ng-click="submitted = true">Save</button>
Hope you can help me. It's a new world for me this job.
Thanx in advance.
Well, why not create a validation function on your Controller.
Loop over all your coupon objects and check if they have a value.
e.g
$scope.requireCoupon = function() {
var nrCouponsChecked = 0;
$ctrl.coupons.forEach(function(coupon) {
if (coupon.Select) {
nrCouponsChecked++;
}
});
}
// and in your template you would use it like
<span ng-show="submitted == true && requireCoupon()">Select at least one cupon!</span>
That is because you are using the same ng-model for all the checkboxes by doing this:
ng-model="formData.couponBox"
The previous code sets an ng-model (formData.couponBox) for all of the checkboxes.
A valid option would be create an object which will contains the ng-model of every checkbox, like this (Demo with some fake data)
angular
.module('app', [])
.controller("myCtrl", function() {
var wizard = this;
wizard.$ctrl = {
//fake data
coupons: [{
Select: false,
CodeCoupon: "1st"
}, {
Select: false,
CodeCoupon: "2nd"
}],
//create an object for storing the checkbox models
checkBoxModels: {},
checkIfAnyChecked: checkIfAnyChecked
}
return wizard.$ctrl;
function checkIfAnyChecked() {
for (var k in wizard.$ctrl.checkBoxModels) {
if (wizard.$ctrl.checkBoxModels.hasOwnProperty(k) && wizard.$ctrl.checkBoxModels[k]) {
//for instance, if 3rd checkbox is checked, wizard.$ctrl.checkBoxModels will be {3: true} and so on...
return true;
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="app" ng-controller="myCtrl as ctrl">
<ul>
<li ng-repeat="c in ctrl.coupons">
<input type="checkbox" name="couponBox" ng-checked="c.Select" ng-click="ctrl.selectOne(c)" ng-model="ctrl.checkBoxModels[$index]" required/>{{c.CodeCoupon}}
<br>
</li>
</ul>
<span ng-show="submitted == true && !ctrl.checkIfAnyChecked()">Select at least one cupon!</span>
<br />
<button type="submit" ng-click="submitted = true">Save</button>
</div>
You have to create dynamic names for each checkbox input to do validations.
Here is an example since you have not provided the dataset.
var app=angular.module("App",[]);
app.controller("AppCtrl",function($scope){
var selectedFruits = {
Mango: true
};
var calculateSomeSelected = function() {
$scope.someSelected = Object.keys(selectedFruits).some(function (key) {
return selectedFruits[key];
});
};
$scope.formData = {
selectedFruits: selectedFruits
};
$scope.fruits = [{'name':'Apple'}, {'name':'Orange'}, {'name':'Banana'}, {'name':'Mango'}];
$scope.checkboxChanged = calculateSomeSelected;
calculateSomeSelected();
});
<!DOCTYPE html>
<html ng-app="App">
<head>
<meta charset="utf-8" />
<script data-require="angular.js#1.4.9" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="AppCtrl">
<form class="Scroller-Container" name="multipleCheckbox" novalidate="" ng-submit="submitForm()">
<h3>What would you like?</h3>
<div ng-repeat="fruit in fruits">
<input type="checkbox" ng-model="formData.selectedFruits[fruit.name]" ng-change="checkboxChanged()" ng-required="true" name="fruits_{{$index}}" /> {{fruit.name}}
<p style="color: red;" ng-show="multipleCheckbox.$submitted&&multipleCheckbox.fruits_{{$index}}.$error.required">You must choose {{fruits[$index].name}} fruit</p>
</div>
<input type="submit" value="Submit">
</form>
<pre>Fruits model:
{{formData.selectedFruits | json}}</pre>
</div>
</body>
</html>
Related
I am working on angularjs and bootstrap application. I'm trying to validate the simple form, when user click on submit button all the fields in the from should have a value.
Please find the demo : https://plnkr.co/edit/aHtODbTTFZfpIRO3BWhf?p=preview
In the demo above, when user click on submit button with out selecting the checkbox , an error message is shown 'Please Select the Color..' , after the error message is shown select the checkbox and click on submit button still the error message is displayed. Any inputs on this?
html code:
<form name="myForm" ng-controller="ExampleController">
<div>Select Color : </div>
<label name="color" ng-repeat="color in colorNames" class="checkbox-inline">
<input ng-required="selectedColor.length === 0" oninvalid="this.setCustomValidity('Please select the color..')" type="checkbox" name="color" value="{{color}}" ng-checked="selectedColor.indexOf(color) > -1" ng-click="userSelection(color)"> <!--<input type="checkbox" name="color" value="{{color}}" ng-checked="selectedColor.indexOf(color) > -1" ng-click="userSelection(color)"> {{color}}-->
{{color}} <br> </label>
<div class="">
<div style="color: black;">Username : </div>
<input type="text" name="user" value="" required>
<div ng-show="myForm.$submitted || myForm.user.$touched">
<p class="error-mesg" ng-show="myForm.user.$error.required">The Username is required</p>
</div>
</div>
<button type="submit" class="btn btn-primary" ng-click="submitForm(myForm)">Submit</button>
</form>
First
I have declared an array for all of the checkbox value:
$scope.selectedColor = [false,false,false];
Second
I added a method for check box validation check:
$scope.someSelected = function () {
for(var i = 0; i < $scope.selectedColor.length; i++) {
if($scope.selectedColor[i]) return true;
}
return false;
};
Third
I use ng-model and update the HTML code, ng-model is used for two-way data binding, and change to bind value will reflected in view and controller:
<input ng-required="!someSelected()" ng-model = "selectedColor[$index]" type="checkbox" name="color" value="{{color}}">
Forth
The user input box also do not have the ng-model so the change in view not be updated in controller. To solve this ng-model is added.
<input type="text" ng-model = "user" name ="user" value="" required>
Fifth
Updated the submit form validation:
$scope.submitForm = function(){
if ($scope.someSelected() && $scope.user != "" && $scope.user != undefined) {
alert("all fields are entered");
}else{
}
}
Thats all!
Please check the working code snippet:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-checkbox-input-directive-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
</head>
<body ng-app="checkboxExample">
<script>
angular.module('checkboxExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.colorNames = ['RED', 'BLUE', 'BLACK'];
$scope.selectedColor = [false,false,false];
$scope.userSelection = function userSelection(team) {
var idx = $scope.selectedColor.indexOf(team);
if (idx > -1) {
$scope.selectedColor.splice(idx, 1);
}
else {
$scope.selectedColor.push(team);
}
};
$scope.submitForm = function(){
if ($scope.someSelected() && $scope.user != "" && $scope.user != undefined) {
alert("all fields are entered");
}else{
}
}
$scope.someSelected = function () {
for(var i = 0; i < $scope.selectedColor.length; i++) {
if($scope.selectedColor[i]) return true;
}
return false;
};
}]);
</script>
<form name="myForm" ng-controller="ExampleController">
<div>Select Color : </div>
<label name="color" ng-repeat="color in colorNames" class="checkbox-inline">
<input ng-required="!someSelected()" ng-model = "selectedColor[$index]" type="checkbox" name="color" value="{{color}}"> <!--<input type="checkbox" name="color" value="{{color}}" ng-checked="selectedColor.indexOf(color) > -1" ng-click="userSelection(color)"> {{color}}-->
{{color}} <br> </label>
<div class="">
<div style="color: black;">Username : </div>
<input type="text" ng-model = "user" name ="user" value="" required>
<div ng-show="myForm.$submitted || myForm.user.$touched">
<p class="error-mesg" ng-show="myForm.user.$error.required">The Username is required</p>
</div>
</div>
<button type="submit" class="btn btn-primary" ng-click="submitForm(myForm)">Submit</button>
</form>
</body>
</html>
<!--
Copyright 2018 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
Solution is to update your (1) input field for colors, (2) input field for user and (3) submitForm method
<input ng-required="selectedColor.length === 0" onchange="this.setCustomValidity(!validity.valueMissing && '')" oninvalid="this.setCustomValidity(validity.valueMissing ? 'Please select the color..' : '')"type="checkbox" name="color" value="{{color}}" ng-checked="selectedColor.indexOf(color) > -1" ng-click="userSelection(color)">
<input type="text" name="user" value="" ng-model="user" required>
$scope.submitForm = function(form){
if ($scope.selectedColor.length > 0 && $scope.user != "") {
console.log('fields are all entered');
} else{
}
}
(1) You need to set the false condition to handle the checkbox when it is selected.
(2) For your user input field, you need to set ng-model=user to link the $scope.user object to the input.
(3) For the submitForm method, you want to know that the selectedColor array has at least one item, and that user is not empty.
As an ending point, please format your code using proper linting and indentation. Otherwise, it is difficult to read at first glance.
I'm trying to create a list where there are multiple select all buttons to for ng-repeat check boxes.
HTML code
<div class="col-xs-12"ng-repeat="items in testArray">
<div class="col-xs-6">
{{items.brand}}
</div>
<div class="col-xs-6 col-sm-offset-6">
<button ng-click="selectAll()">select All</button>
<div ng-repeat="i in items.form">
<input type="checkbox"/>{{i.formName}}
</div>
</div>
</div>
you can try it.this example you can manipulate it according to your need
https://plnkr.co/edit/qD7CABUF9GLoFCb8vDuO?p=preview
$scope.test=function(event){
if(event.currentTarget.checked==true)
{
var togglestatus=$scope.isAllSelected;
angular.forEach($scope.options,function(object){
object.selected=togglestatus
})
}else{
angular.forEach($scope.options,function(object){
object.selected=false
})
}
}
html:
<body ng-app="test" ng-controller="testctrl">
<label>
<input type="checkbox" ng-model="isAllSelected" ng-click="test($event)">SelectAll</label>
<div ng-repeat="option in options">
<input type="checkbox" ng-model="option.selected">checkbox</div>
</body>
Please check ngChecked directive. You need to add it to your input
<input type="checkbox" ng-checked="i.isChecked" />
and then in selectAll() method set isChecked property on every item to true.
look at code snippet given below , this will give you idea.
var app = angular.module("myApp",[]);
app.controller('demoCtrl',function($scope){
$scope.itemsArray = [{name:"Test 1",forms:[{formName:"xyz 1 "},{formName:"xyz 1 "}]},{name:"Test 2",forms:[{formName:"xyz 2 "},{formName:"xyz 1 "}]},{name:"Test 3 ",forms:[{formName:"xyz 3"},{formName:"xyz 1 "}]}];
$scope.selectAll = function(item){
for(var i =0;i < item.forms.length;i++)
{
item.forms[i].isChecked = true;
}
}
$scope.removeAll = function(item) {
for(var i =0;i < item.forms.length;i++)
{
item.forms[i].isChecked = false;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="demoCtrl">
<div ng-repeat="item in itemsArray">
<span>{{item.name}}</span>
<button ng-click="selectAll(item)"> select All </button>
<button ng-click="removeAll(item)"> Deselect All </button>
<div ng-repeat="i in item.forms">
<input type="checkbox" ng-model="i.isChecked"/>
</div>
</div>
</div>
</div>
You can simply set a variable to true like this
ng-click="selectAll = true"
and then use the ng-checked directive to set the checkbox to checked when the expression inside is true
ng-checked="selectAll"
HTML
<div class="col-xs-12"ng-repeat="items in testArray">
<div class="col-xs-6">
{{items.brand}}
</div>
<div class="col-xs-6 col-sm-offset-6">
<button ng-click="selectAll = true">select All</button>
<div ng-repeat="i in items.form">
<input type="checkbox" ng-checked="selectAll"/>{{i.formName}}
</div>
</div>
</div>
Created a fiddle, showcasing your need for requirement "select all" - http://jsfiddle.net/deeptechtons/TKVH6/
//html
<div>
<ul ng-controller="checkboxController">
<li>Check All
<input type="checkbox" ng-model="selectedAll" ng-click="checkAll()" />
</li>
<li ng-repeat="item in Items">
<label>{{item.Name}}
<input type="checkbox" ng-model="item.Selected" />
</label>
</li>
</ul>
</div>
//js
angular.module("CheckAllModule", [])
.controller("checkboxController", function checkboxController($scope) {
$scope.Items = [{
Name: "Item one"
}, {
Name: "Item two"
}, {
Name: "Item three"
}];
$scope.checkAll = function () {
if ($scope.selectedAll) {
$scope.selectedAll = true;
} else {
$scope.selectedAll = false;
}
angular.forEach($scope.Items, function (item) {
item.Selected = $scope.selectedAll;
});
};
});
Since I am using Semantic UI for checkboxes, the <input> tag is wrapped with a <div class="ui checkbox"> and what happens is when the box is checked, it just adds the class checked.
<div class="field" ng-repeat="animal in animals">
<div class="ui checkbox">
<input class="hidden" tabindex="0" type="checkbox" value="{{animal.id}}" ng-model="animal.selected">
<label>{{animal.name}}</label>
</div>
</div>
How do I get the id or value of the selected checkboxes using AngularJS? Thank you.
You can have a function in your controller
$scope.getAnimal= function(){
angular.forEach($scope.animals, function(animal){
if (animal.selected) do smth here...
})
}
You can use Array.prototype.filter() method to get only the selected objects.
Here's a demonstration:
angular.module('app', [])
.controller('mainCtrl', function($scope) {
$scope.animals = [];
for (var i = 0; i <= 5; i++) {
$scope.animals.push({
"id": Math.floor(Math.random() * 310),
"name": "Name " + Math.floor(Math.random() * 420),
"selected": i % 2 === 0 ? true : false
});
}
$scope.selected = [];
$scope.show = function() {
$scope.selected = $scope.animals.filter(function(value) {
return value.selected;
});
}
});
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<div class="field" ng-repeat="animal in animals track by $index">
<div class="ui checkbox">
<input id="checkbox{{$index}}" class="hidden" tabindex="0" type="checkbox" value="{{animal.id}}" ng-model="animal.selected">
<label for="checkbox{{$index}}" ng-bind="animal.name"></label>
</div>
</div>
<hr>
<button type="button" value="show" ng-click="show()">Show selected tems</button>
<pre ng-bind="selected | json"></pre>
</body>
</html>
I'm trying to implement a Todo list using Angular JS and connecting it with MySQL and PHP. I have a working code where the button used to open a modal passes a php variable to that modal. I have placed that value in a hidden input field (int the modal). Now, I want to get that value so I can use it AngularJS because I will pass it again through AJAX in a separate PHP page. The thing is, it always returns undefined. Where am I going wrong with this?
JQuery code to pass the php variable and value to the modal:
<script>
$(document).ready(function(){
$('#editModal').on('show.bs.modal', function (e) {
var id = $(e.relatedTarget).data('id');
$("#new-taskID").val(id); // e.g. 3
});
});
</script>
'EditModal' (the form inside the Bootstrap Modal)
<form class="cmxform" id="editTask" name="dasd" onsubmit="return false" method="post" action="" role="form">
<div class="col-md-12">
<div ng-app>
<div id="todoapp" ng-controller="TodoCtrl">
<div class="form-group form-animate-text" style="margin-top:15px !important;">
<input type="text" class="form-text" id="new-todo" ng-model="todoText" name="allotted_time_edit" ng-keyup="addTodo()" required>
<span class="bar"></span>
<label>What needs to be done?</label>
<input type="hidden" class="form-text" id="new-taskID" value = "" name="new-taskID" required> //the passed value is placed here
</div>
<section id="main" style="display: block;">
<div ng-show="isTodo()">
<input id="toggle-all" type="checkbox" ng-model="markAll" ng-click="toggleMarkAll()"/>
<label for="toggle-all">Mark all as complete</label>
</div>
<ul id="todo-list" class="unstyled">
<li ng-repeat="todo in todos" ng-dblclick="toggleEditMode()">
<div class="view" ng-keyup="editTodo()">
<input type="checkbox" ng-model="todo.done"/>
<span class="done-{{todo.done}}" >{{todo.text}}</span>
</div>
<input class="edit" type="text" ng-model="todo.text" ng-keyup="editOnEnter(todo)"/>
</li>
</ul>
</section>
<footer style="display: block;">
<div class="todo-count">{{remaining()}} of {{todos.length}} remaining</div>
<a id="clear-completed" ng-click="clear()" ng-show="hasDone()">
Clear <span >{{(todos.length - remaining())}} {{itemText()}}</span>.</a>
</footer>
</div>
</div>
</div>
<center>
<button id="send" type="submit" class="btn btn-primary" name="dasd">Update</button>
<button type="button" class="btn btn-danger"data-dismiss="modal">Cancel</button>
</center>
</form>
AngularJS Code
<script>
function TodoCtrl($scope, $http) {
$scope.todos = [];
$scope.markAll = false;
$scope.addTodo = function(item) {
var name = $scope.todoText;
var id = document.getElementById('new-taskID').val;
alert(id); //return undefined
if(event.keyCode == 13 && name){
$http.post("ajax-search/add_checklist.php?item="+name).success(function(data){ $scope.todos.push({text:$scope.todoText, done:false});
$scope.todoText = '';
});
}
};
$scope.isTodo = function(){
return $scope.todos.length > 0;
}
$scope.toggleEditMode = function(){
$(event.target).closest('li').toggleClass('editing');
};
$scope.editOnEnter = function(todo){
if(event.keyCode == 13 && todo.text){
$scope.toggleEditMode();
}
};
$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};
$scope.hasDone = function() {
return ($scope.todos.length != $scope.remaining());
}
$scope.itemText = function() {
return ($scope.todos.length - $scope.remaining() > 1) ? "items" : "item";
};
$scope.toggleMarkAll = function() {
angular.forEach($scope.todos, function(todo) {
todo.done =$scope.markAll;
});
};
$scope.clear = function() {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
}
</script>
I really need to get the value but it returns undefined. Your help will be much appreciated. Thank you so much!!
I have a form like this
<form id="myForm">
<input type="text" name="userName" value="test" />
<ul>
<li ng-repeat="item in list">
<input type="checkbox" name="chkList" value="id" />
</li>
</ul>
</form>
I am using jquery to submit form and converting the post data like this
var d = 'name=' + $('#myform input[name=userName]).val();
var valArr = [];
$('#myform input[name=chkList]').each(function() {
valArray.push($(this).val());
});
d = '&listOfIds=' + valArray.join(',');
... then submitting post with data: d
I dont want to use jquery but not sure what the angualr equivalent would be here?
actually it's all in details, it could be so:
<input type="checkbox" name="chkList" ng-model="valArray[$index]" value="id" />
and in the controller:
$scope.valArray = [ 1 , 2 , 3 ];
Here is what your are looking for: JSFiddle
HTML
<div ng-app="myApp" ng-strict-di>
<div ng-controller="Ctrl">
<div ng-repeat="item in items">
<input type="checkbox" ng-model="$parent.values[item.id]"/>{{item.name}}
</div>
<button type="button" ng-click="submit()">Submit</button>
</div>
JS:
angular.module("myApp",[]).controller("Ctrl",function($scope){
angular.extend($scope,{
values:{},
items:[
{id:1,name:'name1'},
{id:2,name:'name2'},
{id:3,name:'name3'},
],
submit: function() {
var d = '&listOfIds=' + Object.keys($scope.values).join(",");
alert(d);
}
});
});