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
Related
I followed this svelte tutorial and I wonder if I could do this group binding to a JSON array instead of simple array, for example I would like to do a planets selector:
<script>
let planets = [{
name: 'Jupiter',
enable: false
},
{
name: 'Saturn',
enable: false
},
{
name: 'Uran',
enable: false
},
{
name: 'Neptun',
enable: false
},
{
name: 'Pluto',
enable: true
},
];
$: planets, console.log(planets)
</script>
{#each planets as planet}
<label>
<input type=checkbox bind:group={planets} name={planet.name} value={planet}>
{planet.name}
</label>
{/each}
This is a REPL. I wonder if there is a way how to properly bind JSON array (enable array field with inputs value) in svelte each loop. Now it pops out with each item as you click as you can see in REPL's console.log and I would like just to uncheck it.
With bind:checked property displays proper way
<input type=checkbox bind:checked={planet.enable} value={planet}>
But this does not change array.enable value on click. Can I achieve responsibility of planets array here?
I think the problem is that you set the value to planet. When you remove this and only use the checked property, then the array updates with the proper value.
<script>
let planets = [{
name: 'Jupiter',
enable: false,
},
{
name: 'Saturn',
enable: false
},
{
name: 'Uran',
enable: false
},
{
name: 'Neptun',
enable: false
},
{
name: 'Pluto',
enable: true
},
];
$: planets, console.log(planets)
</script>
{#each planets as planet}
<label>
<input type=checkbox bind:checked={planet.enable}>
{planet.name}
</label>
{/each}
You can checkout my REPL.
Here is a screenshot from the update:
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
}
}
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 to use ng-options.
$scope.fieldTable = [
{
filed:"text",
title:"Global"
},
{
field: "relatedentity",
title: "Entity"
},
{
field:"title",
title:"Title"
},
{
field: "content",
title: "Content"
}
]
I want to build a which use the title as displayed and when select something, popout a alert window which display the according field. The initial selection is
{
filed:"text",
title:"Global"
}
Can anyone help?
var app = angular.module('stack', []);
app.controller('MainCtrl', function($scope) {
$scope.fieldTable = [{
field: "text",
title: "Global"
}, {
field: "relatedentity",
title: "Entity"
}, {
field: "title",
title: "Title"
}, {
field: "content",
title: "Content"
}];
$scope.selected = $scope.fieldTable[0];
$scope.hasChanged = function() {
alert($scope.selected.field);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="stack" ng-controller="MainCtrl">
<select ng-options="item.title for item in fieldTable" ng-model="selected" ng-change="hasChanged()">
</select>
</body>
You can use ng-change to do that
<select ng-options="item.title as item.title for item in fieldTable track by item.title" ng-model="selected" ng-change="onChanged()">
then in your onChange() method in the controller you can do whatever you want it to do :) In your case , show an alert with the value
edit:
https://plnkr.co/edit/4csDtFVH5mKd7Xr39WtG?p=preview
$scope.activities =
[
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
<select data-ng-model="engineer.currentActivity" data-ng-options="a.name for a in activities">
</select>
Using the above I am able to create a select box with 3 values, a blank one and then dropdown menu and horizontal bar.
I would like to set Horizontal Bar as my default and cannot see how to do this.
Help would be great
In the controller, just add a line to setup the initial selection:
$scope.activities =
[
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
$scope.engineer = {}; // if needed
$scope.engineer.currentActivity = $scope.activities[1];
In your angular controller:
$scope.activities = [
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
$scope.activity = $scope.activities[1]; //Bind 2nd activity to the model.
In the HTML:
<select ng-model="activity"
ng-options="activity as activity.name for activity in activities">
<option value=""></option>
</select>
See the Fiddle
Use ng-init directive
ng-init="engineer.currentActivity = options[1]"