How to restrict checkbox selection in angularjs - angularjs

I have 10 check boxes in a screen. I want check only 5 check boxes. If I check more than 5 checkboxes, I need to show one alert message, "select only 5 check box".
jsfiddle
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.items = [{
id: 1,
title: 'item1',
selected: true
},{
id: 2,
title: 'item2',
selected: false
},{
id: 3,
title: 'item3',
selected: false
},{
id: 4,
title: 'item4',
selected: false
},{
id: 5,
title: 'item5',
selected: false
},{
id: 6,
title: 'item6',
selected: false
},{
id: 7,
title: 'item7',
selected: false
},{
id: 8,
title: 'item8',
selected: false
},{
id: 9,
title: 'item9',
selected: false
},{
id: 10,
title: 'item10',
selected: false
}
];
}
<div ng-controller="MyCtrl">
<div ng-repeat="item in items">
<input id="{{ item.id }}"
type="checkbox"
ng-model="item.selected"
ng-checked="item.selected" />
<label for="{{ item.id }}" >{{ item.title }}</label>
</div>
</div>
On click of checkbox itself I need to show the alert message. I need to select only 5 checkbok at a time. Not more than 5. Please help me how can i do this.

You can add watcher that will validate checkbox list for selected count:
$scope.$watch(function () {
return $scope.items;
},
function (newValue, oldValue) {
if(newValue !== undefined && oldValue !== undefined){
var selected = newValue.filter(function(_item){
return _item.selected == true;
});
if(selected.length > 4){
//disable other checkboxes
angular.forEach($scope.items, function(item, key) {
if(item.selected === false){
item.disabled = true;
}
});
}
else{ // enable all
angular.forEach($scope.items, function(item, key) {
item.disabled = false;
});
}
}
}, true);
Demo

You could count the selected checkboxes in a foreach onclick and show alert if count >5
$scope.checkSelected = function(item){
var c = 0;
angular.forEach(items, function(item, key) {
if(item.selected){
c++;
}
});
if(c>5){
item.selected = false;
alert('Not more than 5');
}
}

I'd recommend giving them classes then using js to select the class and do a count of how many have selected:true
if($('#myclass option:selected').length() > 4){
alert("WARNING")
}

You can make use of ng-change directive.
<input id="{{ item.id }}"
type="checkbox"
ng-model="item.selected"
ng-change="processChecked(item)" />
$scope.processChecked = function(item) {
var checked = $scope.items.filter(function(i) {
return i.selected;
});
if (checked.length > 5) {
alert("more than 5!");
item.selected = false; // undo last action
}
}

Related

pre-fill select box using angularjs

In this example the pre defined item not selected by default. Please help to achieve this.
<button ng-click="addRow()">Add Row</button>
<ul>
<li ng-repeat="row in rows">
<select kendo-drop-down-list ng-model="row.selected" ng-init="row.selected = row.choosenItem" ng-options="item.name for item in list | filter:notUsed(row)"></select>
<button ng-click="deleteRow(row)">X</button>
</li>
</ul>
var app = angular.module('plunker', []);
In the data ($scope.rows) item selected in row.choosenItem property. Still the selectbox not filled with choosenItem.
app.controller('MainCtrl', function($scope) {
$scope.list = [{
id: 1,
name: "one"
}, {
id: 2,
name: "Two"
}, {
id: 3,
name: "Three"
}, {
id: 4,
name: "Four"
}, {
id: 5,
name: "Five"
}, {
id: 6,
name: "Six"
}];
$scope.rows = [{
choosenItem: {
id: 2,
name: "Two"
},
label: "row 1",
selected: 2
}, {
choosenItem: {
id: 4,
name: "Four"
},
label: "row 2",
selected: 4
}];
function byID(member) {
return member.choosenItem.id;
}
$scope.notUsed = function(row) {
return function(item) {
return item.id === row.choosenItem.id || !_.indexBy($scope.rows, byID)[item.id];
}
};
$scope.addRow = function addRow() {
$scope.rows.push({
choosenItem: {},
label: "row "+($scope.rows.length+1),
selected: 0
})
};
$scope.deleteRow = function deleteRow(row) {
};
$scope.onSelectChange = function onSelectChange(row){
row.choosenItem = _.findWhere($scope.list, {'id': parseInt(row.selected)});
};
});
Example code here
Basically, when using ngOptions the syntax is value as text for item in array - so keeping that in mind, define your value:
ng-init="row.selected = row.choosenItem.id" ng-options="item.id as item.name for item in list"

How to get all checked checkboxes value by ng-model in Angular?

here is the jsfiddle.
HTML:
<div ng-app="app">
<div ng-controller="ctrl">
<div ng-repeat="item in list">
<div mycb group="{{item.group}}" title="{{item.title}}" is-checked="item.isChecked" value="{{item.value}}" update="callMe()"></div>
</div>
<p>{{result}}</p>
</div>
</div>
JS:
angular.module("app",[])
.controller("ctrl", ["$scope", function($scope){
$scope.list = [
{ group: "pet", title: "dog", isChecked: true, value: "dog" },
{ group: "pet", title: "cat", isChecked: true, value: "cat" },
{ group: "pet", title: "bird", isChecked: true, value: "bird" },
{ group: "pet", title: "snake", isChecked: true, value: "snake" },
{ group: "pet", title: "boy", isChecked: true, value: "boy" },
{ group: "pet", title: "cup", isChecked: true, value: "cup" }
];
$scope.callMe = function(){
var collection = [];
for(var i=0;i<$scope.list.length;i++){
var isChecked = $scope.list[i].isChecked;
if(isChecked){
collection.push($scope.list[i].value);
}
}
$scope.result = collection.join(" ");
}
}])
.directive("mycb", function(){
return{
restrict: "A",
scope: {
title: "#",
isChecked: "=",
group: "#",
value: "#",
update: "&"
},
template: "<input type='checkbox' ng-model='isChecked' name='{{group}}' value='value' ng-change='update()'>{{title}}"
};
})
I created a group of checkbox and it will be updated when each of them is clicked.
By default, all checkboxes are checked. When I click the first one, it will be turned to status unchecked. The value of other checked boxes will show up.
For example:
dog,cat,bird,snake,boy,cup
When I click dog, the checkbox of dog will be turned to unchecked and "cat,bird,snake,boy,cup" will show up. Actually, it not happened like that. It shows "dog,cat,bird,snake,boy,cup".
Please check it out and give me a hand. Many thanks!
You can use an arrray to keep track of the boxes that are checked.
$scope.selectedCheckboxes = [];
$scope.callMe=function(item){
var idx = $scope.selectedCheckboxes.indexOf(item);
// is currently selected
if (idx > -1) {
$scope.selectedCheckboxes.splice(idx, 1);
}
// is newly selected
else {
$scope.selectedCheckboxes.push(item);
}
};
And in html pass item.value to callMe function. You wil have all the value that are checked in $scope.selectedCheckboxes
<div ng-repeat="item in list">
<div mycb group="{{item.group}}" title="{{item.title}}" is-checked="item.isChecked" value="{{item.value}}" update="callMe(item.value)"></div>
</div>
HTML
<div ng-repeat="item in list">
<div mycb group="{{item.group}}" title="{{item.title}}" is-checked="item.isChecked" value="{{item.value}}" ng-change="callMe()"></div>
</div>
Use ng-change event. Call Me function called when the user clicked on the checkbox. you can easily track all the checked checkbox in the controller.
Let me know if you need help more. Thanks.

How do I filter results by checkbox?

I'm trying to filter results by star rating, these filters are checkboxes. I can't get this to work. I keep getting the error:
Error: input is undefined
This is my code so far:
$scope.ratings = [
{ name:'One Star', value:1, selected: true},
{ name:'Two Stars', value:2, selected: true},
{ name:'Three Stars', value:3, selected: true},
{ name:'Four Stars', value:4, selected: true},
{ name:'Five Stars', value:5, selected: true}
]
.filter('ratingsFilter', function(){
return function(vehicleResults, ratings){
console.log(ratings)
}
})
<label ng-repeat="rating in ratings">
<input name="rating" type="checkbox" value="{{rating.value}}" ng-model="rating"> star rating {{rating.value}}
</label>
When displaying the filtered results:
<div ng-repeat="vehicle in (filteredResults = (vehicleResults | filter: priceFilter | ratingsFilter:rating )) | startFrom:(currentPage - 1)*10 | limitTo:10 " class="results-container">
Can anyone give me some pointers on how to filter these results?
Thank you in advance.
I've created plunk but it's playing tricks on me so here you have codepen
http://codepen.io/maurycyg/pen/RNrxQj
JS
var app = angular.module('ratings', []);
app.controller('MainCtrl', function($scope) {
$scope.ratings = [{
name: 'One Star',
value: 1,
selected: true
}, {
name: 'Two Stars',
value: 2,
selected: true
}, {
name: 'Three Stars',
value: 3,
selected: true
}, {
name: 'Four Stars',
value: 4,
selected: true
}, {
name: 'Five Stars',
value: 5,
selected: true
}]
$scope.vehicles = [{
name: 'One',
rating: 1
}, {
name: 'Two',
rating: 2
}, {
name: 'Three',
rating: 3
}, {
name: 'Four',
rating: 4
}, {
name: 'Five',
rating: 5
}, ]
}).filter('ratingsFilter', function() {
return function(vehicles, ratings) {
filteredResults = []
angular.forEach(vehicles, function(vehicle) {
angular.forEach(ratings, function(rating) {
if (vehicle.rating === rating.value && rating.selected === true) {
filteredResults.push(vehicle)
}
})
})
return filteredResults;
}
})
I think your problem lies at the ratings repeater and not on your filter.
When you are using ng-model directive it takes care of the value binding, you cannot have both interpolated value attribute and ng-model on an input element.
I believe what you whant to achieve is best done if you remove the ng-model completely and instead use the ng-checked directive like so:
var app = angular.module('main', []);
app
.filter('ratingsFilter', function() {
return function(items, includedRatings) {
return items.filter(function (value, index, array) {
return includedRatings.indexOf(value.rating) > -1;
});
};
})
.controller('MainCtrl', function($scope) {
$scope.selectedRatings = [1, 2, 3, 4, 5];
$scope.toggleRating = function (val) {
var array = $scope.selectedRatings;
var isChecked = array.indexOf(val);
if (isChecked > -1) {
for (var i = array.length; i--;) {
if (array[i] === val) {
array.splice(i, 1);
}
}
}
else {
array.push(val);
}
};
$scope.ratings = [
{ name:'One Star', value:1, selected: true},
{ name:'Two Stars', value:2, selected: true},
{ name:'Three Stars', value:3, selected: true},
{ name:'Four Stars', value:4, selected: true},
{ name:'Five Stars', value:5, selected: true}
];
$scope.priceFilter = {};
$scope.vehicleResults = [
{ name:'Porche', rating: 3, price:80000},
{ name:'Ferrari', rating: 1, price:150000},
{ name:'Volvo', rating: 2, price:54000},
{ name:'Batmobile', rating: 5, price:10},
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="main" ng-controller="MainCtrl">
<label ng-repeat="rating in ratings">
<input name="rating" type="checkbox"
value="{{rating.value}}"
ng-click="$parent.toggleRating(rating.value)"
ng-checked="$parent.selectedRatings.indexOf(rating.value) > -1" />
star rating {{rating.value}}
</label>
<br />
<label>
Price:
<input ng-model="priceFilter['price']" />
</label>
<label>
selected Rating:
{{ selectedRatings }}
</label>
<ul >
<li ng-repeat="vehicle in vehicleResults | filter : priceFilter | ratingsFilter: selectedRatings">
{{vehicle.name}} - {{vehicle.price | currency}} ({{vehicle.rating}} stars)
</li>
</ul>
</div>

Validate that all of the checkboxes are checked in ionic

I have a form with list of checkboxes, as shown here:
$scope.deviceList = [
{ text: "Dev 0", checked: false },
{ text: "Dev 1", checked: false },
{ text: "Dev 2", checked: false },
{ text: "Dev 3", checked: false },
{ text: "Dev 4", checked: false }
];
<form>
<ion-checkbox class="checkbox-balanced"
ng-repeat="item in deviceList"
ng-model="item.checked"
ng-required="true">
{{ item.text }}
</ion-checkbox>
</form>
Of course that I have more elements. but just for this case I show the relavent code.
Now, I would like to have a validation that the form cannot be sent until all checkboxes are checked.
Any suggestions of an elegant solution for that?
Thanks in advance
Maybe a function with something like the following would do the trick:
$scope.validate = function(){
var numChecked = $filter($scope.deviceList, function(device) {
return device.checked
}).length;
return $scope.deviceList.length == numChecked;
}
And don't forget to inject $filter service in your controller or it won't work

Angular custom filter into javascript only

I have some checkboxes and a list. I have made a custom filter to filter the results of that list according to the checkbox that is selected.
The problem is that I plan to have quite a lot of these checkboxes filtering the results so I would like to move all aspects of the filtering into the javascript. I have seen that this is possible by adding it into the controller but I have not been able to. Could someone point me in the right direction?
Here is the fiddle: http://jsfiddle.net/webgremlin/qpyngzu8/
html
<div ng-app="someApp">
<div ng-controller="checkboxCtrl">
<label ng-repeat="tree in trees">
{{ tree.name }}
<input type="checkbox" ng-model="tree.selected"/>
</label>
</div>
<hr />
<div ng-controller="listCtrl">
<ul>
<li ng-repeat="item in listItems | filterByCategory : trees">
{{ item.name }}
</li>
</ul>
</div>
</div>
js
var someApp = angular.module('someApp', []);
someApp.factory('checkboxFactory', function() {
var checkboxFactory = [
{ name: 'item 1', item: 1 },
{ name: 'item 2', item: 2 },
{ name: 'item 3', item: 3 }
];
return checkboxFactory;
});
someApp.factory('listFactory', function() {
var listFactory = [
{ name: 'list item 01', item: 1 },
{ name: 'list item 02', item: 2 },
{ name: 'list item 03', item: 3 },
{ name: 'list item 04', item: 1 },
{ name: 'list item 05', item: 2 },
{ name: 'list item 06', item: 3 },
{ name: 'list item 07', item: 1 },
{ name: 'list item 08', item: 2 },
{ name: 'list item 09', item: 3 },
{ name: 'list item 10', item: 1 }
];
return listFactory;
});
someApp.filter('filterByCategory', function() {
return function(input, trees) {
console.log(input, trees);
var ret =[];
for (var i in input){
var match = false;
for (var j in trees){
if (trees[j].selected && trees[j].item == input[i].item){
ret.push(input[i]);
}
}
}
if (ret.length > 0){
return ret;
} else {
return input;
}
};
})
someApp.controller('checkboxCtrl', ['$scope','checkboxFactory',
function($scope, checkboxFactory) {
$scope.trees = checkboxFactory;
}]);
someApp.controller('listCtrl', ['$scope','checkboxFactory','listFactory',
function($scope, checkboxFactory,listFactory) {
$scope.trees = checkboxFactory;
$scope.listItems = listFactory;
console.log($scope.listItems);
}]);
You can do that. Just use the $filter provider to look up your filterByCategory filter in your controller and apply it that way:
Fiddle here:
http://jsfiddle.net/smaye81/gp4qg257/2/

Resources