Hi I am developing web application in angularjs. I have one form. I am binding values to multi select dropdown.
<li ng-repeat="p in locations">
<input type="checkbox" ng-checked="master" ng-model="isTrue" ng-change="getIndex(p.Location,isTrue )" ng-name="location" required/>
<span>{{p.Location}}</span>
</li>
I am binding array to locations.
My array look likes
0: id: 1 Location:"ABC"
1: id: 2 Location:"DEF"
2: id: 3 Location:"IJK"
Now my requirement is to make checked some values. Suppose if i have var locations="ABC,DEF" then i want to make only those values checked. May i know if this can be done. Any help would be appreciated. Thank you.
Basically, if our input is a string with the locations that should be selected (i.e) var locations = 'ABC,DEF'; we can split this string by the , character and get an array with the locations to match:
var app = angular.module('myApp', []);
app.controller("locationsController", ["$scope",
function ($scope) {
// vars
var locations = 'ABC,DEF';
// functions
function init () {
var locals = locations.split(',');
angular.forEach($scope.locations, function (item) {
if (locations.indexOf(item.Location) > -1) {
item.checked = true;
}
});
}
// $scope
$scope.locations = [
{ id: 1, Location: "ABC" },
{ id: 1, Location: "DEF" },
{ id: 1, Location: "IJK" }
];
// init
init();
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="locationsController">
<li ng-repeat="p in locations">
<input ng-checked="p.checked" type="checkbox" ng-model="p.checked" required/>
<span>{{ p.Location }}</span>
</li>
</div>
</div>
Try this. Define for each checkbox separate model.
var app = angular.module('myApp', []);
app.controller("Controller", ["$scope",
function($scope) {
$scope.locations = [{
"id": 1,
Location: "ABC"
}, {
"id": 1,
Location: "DEF"
}, {
"id": 1,
Location: "IJK"
}]
var checked = ['ABC','DEF'];
function init() {
angular.forEach($scope.locations,function(location){
if(checked.indexOf(location.Location) != -1){
location.checked = true;
}
})
}
init();
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="Controller">
<li ng-repeat="p in locations">
<input type="checkbox" ng-model="p.checked" name="location" required/>
<span>{{p.Location}}</span>
</li>
</div>
</div>
It should work:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope,$filter) {
$scope.selectedValue = 'ABC,IJK';
$scope.selectedValue = $scope.selectedValue.split(',');
$scope.options = [{
id: 0,
name: 'ABC'
}, {
id: 1,
name: 'DEF'
}, {
id: 2,
name: 'IJK'
}];
$scope.selected = [];
angular.forEach($scope.selectedValue,function(val,key){
var r = $filter('filter')( $scope.options, {name: val})[0].id;
if(r != undefined){
$scope.selected[r]=true;
}else{
$scope.selected[r]=false;
}
});
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<li ng-repeat="p in options">
<input type="checkbox" ng-model="selected[p.id]" ng-change="getIndex(p.Location,isTrue )" />
<span>{{p.name}}</span>
</li>
Selected : {{selected}}
</div>
Try this, Since you need different ngModel for each check box, you need to put them inside the location object itself.
HTML:
<li ng-repeat="p in locations">
<input type="checkbox" ng-checked="master" ng-model="p.isTrue" ng-change="getIndex(p.Location, p.isTrue)" ng-name="location" required/>
<span>{{p.Location}}</span>
</li>
In Javascript:
$scope.locations = [
{id: 1 Location:"ABC"},
{id: 2 Location:"DEF"},
{id: 3 Location:"GHI"}
];
var selectedLocations="ABC,DEF";
selectedLocations = locations.split(",");
angular.forEach($scope.locations, function(loc){
loc.isTrue = selectedLocations.indexOf(loc.Location) > -1;
});
Try this:
<li ng-repeat="p in locations">
<input type="checkbox" ng-checked="p.Location == 'ABC' || p.Location == 'DEF'? true : false" ng-model="p.master" ng-change="getIndex(p.Location,isTrue )" ng-name="location" required/>
<span>{{p.Location}}</span>
</li>
Add one more field checked:"true" with your locations like this
var app = angular.module('myApp', []);
app.controller("Controller", ["$scope",
function($scope) {
$scope.locations = [{id:1,Location:"ABC",checked:"false"},{id:1,Location:"DEF",checked:"true"},{id:1,Location:"IJK",checked:"true"}]
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="Controller">
<li ng-repeat="p in locations">
<input ng-checked="{{p.checked}}" type="checkbox" ng-model="p.id" name="location" required/>
<span>{{p.Location}}</span>
</li>
</div>
</div>
Add another variable to your array. and set the value true/false in it
0: id: 1 Location:"ABC" flag : true
1: id: 2 Location:"DEF" flag : false
<li ng-repeat="p in locations">
<input type="checkbox" ng-checked="p.flag" ng-model="isTrue" ng-
change="getIndex(p.Location,isTrue )" ng-name="location" required/>
<span>{{p.Location}}</span>
</li>
Use that flag to check unchek ur checkbox/
Related
I have list of states and I have added search filter on name of states.
I have array like this:
stateList : [{name: 'abc', area:500},{name: '!def', area:500}]
I have <li> with ng-repeat="state in stateList | filter:{name:searchText}"
Search text box with ng-model="searchText"
Search is working in normal scenario but when I search !(exclamation mark). It is not giving any result. It should give state with name '!def'
The problem is that ! token is recognized by AngularJS as "negative predicate". Nevertheless you can create your custom myFilter like this:
angular.module('app', []).controller('ctrl', function($scope) {
$scope.stateList = [{
name: 'abc',
area: 500
}, {
name: '!def',
area: 500
}]
}).filter('myFilter', function() {
return function(input, filter) {
if (!filter.name)
return input;
return input.filter(function(x) {
return x.name.indexOf(filter.name) != -1;
});
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl'>
<input type='text' ng-model='searchText' />
<ul>
<li ng-repeat='state in stateList | myFilter : {name:searchText}'>{{state | json}}</li>
</ul>
</div>
Try this way
<input type="text" ng-model="state.name"/>
ng-repeat="state in stateList | filter:state"
Is it possible to show only a list of checked items in a checkbox list?
What I want to do is select a few items on a checked list and when I press "Show only checked items", I want to toggle between showing only the checked items in the checkbox list and showing the entire list with the checked items.
I searched angular's site but wasn't able to find a solution to it.
Fiddle: http://jsfiddle.net/fjoLy5sq/422/
<div ng-controller="DemoCtrl">
<label ng-repeat="role in roles">
<input type="checkbox" checklist-model="user.roles" checklist-value="role.id"> {{role.text}}
</label>
<br>
<button ng-click="checkAll()">check all</button>
<button ng-click="uncheckAll()">uncheck all</button>
<button ng-click="checkFirst()">check first</button>
<button ng-click="checkFirst()">Show only Checked</button>
<br><br>
user.roles {{ user.roles | json }}
</div>
Javascript:
angular.module("DemoApp", ["checklist-model"])
.controller('DemoCtrl', function($scope) {
$scope.roles = [
{id: 1, text: 'guest'},
{id: 2, text: 'user'},
{id: 3, text: 'customer'},
{id: 4, text: 'admin'}
];
$scope.user = {
roles: [2, 4]
};
$scope.checkAll = function() {
$scope.user.roles = $scope.roles.map(function(item) { return item.id; });
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push(1);
};
});
Add a new variable in controller:
$scope.showAll = true;
In a view inverse the value of showAll when Show only Checked button is clicked:
<button ng-click="showAll = !showAll">Show only Checked</button>
To show only checked items, use Array.includes method, and check that current role is in user.roles:
<label ng-repeat="role in roles" ng-if="user.roles.includes(role.id)">
<input type="checkbox" checklist-model="user.roles" checklist-value="role.id"> {{role.text}}
</label>
Working demo
I've been writing a code that uses ng-if to display a div with a message if an array is empty([]). The ng-if isn't displaying the div even though I have console.log the array and it shows up empty.
I am still new to angularjs so I am not sure if I am using the ng-if directive correctly. Here is my code, anything helps, thank you!
js:
(function () {
'use strict';
var data = [];
var shoppingList = [
{
name: "Donuts",
quantity: "10"
},
{
name: "Cookies",
quantity: "10"
},
{
name: "Drinks",
quantity: "10"
},
{
name: "Shrimp",
quantity: "10"
},
{
name: "Ice Cream tub",
quantity: "100"
}
];
console.log(data);
angular.module('shoppingListCheckOffApp', [])
.controller('toBuyListController', toBuyListController)
.controller('boughtListController', boughtListController)
.service('shoppingListService', shoppingListService);
toBuyListController.$inject = ['shoppingListService'];
function toBuyListController(shoppingListService) {
var buy = this;
buy.shoppingList = shoppingList;
buy.shoppingListBought = function (itemIndex) {
shoppingListService.dataTransfer(buy.shoppingList[itemIndex].name, buy.shoppingList[itemIndex].quantity);
shoppingListService.remove(itemIndex);
};
}
boughtListController.inject = ['shoppingListService'];
function boughtListController(shoppingListService) {
var bought = this;
bought.data = shoppingListService.getData();
console.log(bought.data);
}
function shoppingListService() {
var service = this;
service.dataTransfer = function (itemName, quantity) {
var item = {
name: itemName,
quantity: quantity
};
data.push(item);
}
service.remove = function (itemIndex) {
shoppingList.splice(itemIndex, 1);
};
service.getData = function () {
return data;
};
};
})();
html:
<!doctype html>
<html ng-app="shoppingListCheckOffApp">
<head>
<title>Shopping List Check Off</title>
<meta charset="utf-8">
<script src="angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div>
<h1>Shopping List Check Off</h1>
<div>
<!-- To Buy List -->
<div ng-controller="toBuyListController as buy">
<h2>To Buy:</h2>
<ul>
<li ng-repeat="item in buy.shoppingList">Buy {{item.quantity}} {{item.name}}(s)<button
ng-click="buy.shoppingListBought($index);" ng-click="myVar = true"><span></span>
Bought</button></li>
</ul>
<div ng-if="buy.shoppingList === []">Everything is bought!</div>
</div>
<!-- Already Bought List -->
<div ng-controller="boughtListController as bought">
<h2>Already Bought:</h2>
<ul>
<li ng-repeat="item in bought.data">Bought {{item.quantity}} {{item.name}}(s)</li>
</ul>
<div ng-if="bought.data === []">Nothing bought yet.</div>
</div>
</div>
</div>
</body>
</html>
You should use ng-if (for arrays) in this way:
<div ng-if="!bought.data.length">Nothing bought yet.</div>
This will show the message when the list is empty.
If you do this:
buy.shoppingList === []
You are comparing you buy.shoppingList array with a new empty array, then it will return false.
My application has to dynamically list file items using a Radio button, Checkbox and AngularJS custom filter (code given below).
I have tried few options, but could not get the working code.
I have created the fiddle link and find the same below:
https://jsfiddle.net/38m1510d/6/
Could you please help me to complete the below code to list the file items dynamically ?
Thank you.
<div ng-app="myApp" ng-controller="myCtrl">
<label>
<input type="radio" ng-model="inputCreatedBy" value="byX"
ng-click="myFilter(?, ?)"> by X
<input type="radio" ng-model="inputCreatedBy" value="byAll"
ng-click="myFilter(?, ?)"> by All
</label> <br/><br/>
<label>
<input type='checkbox' ng-model='Type1Files' ng-change='myFilter(?, ?)'>Type1 files
<input type='checkbox' ng-model='Type2Files' ng-change='myFilter(?, ?)'>Type2 files
</label>
<br/><br/>
<label ng-repeat="file in displayFiles | filter: myFilter(createdBy, fileType)">
{{ file.name }}
</label>
</div>
</body>
<script>
var app = angular.module("myApp",[]);
app.controller('myCtrl', function ($scope) {
$scope.files = [
{ name: 'file1', type:'Type1', createdBy: 'X' },
{ name: 'file2', type:'Type2', createdBy: 'X' },
{ name: 'file3', type:'Type2', createdBy: 'Y' },
{ name: 'file4', type:'Type1', createdBy: 'Y' }
];
$scope.displayFiles = [];
$scope.myFilter = function() {
return new function(createdBy, fileType) {
var displayFilesTemp = [];
for(i=0;i<$scope.files.length;i++) {
if($scope.files[i].type ==fileType && $scope.files[i].createdBy == createdBy && !checkArrayContainsObject(displayFilesTemp, displayFiles[i])) {
displayFilesTemp.push(displayFiles[i]);
}
}
return displayFilesTemp;
};
};
});
function checkArrayContainsObject(a, obj) {
for (var i = 0; i < a.length; i++) {
if (JSON.stringify(a[i]) == JSON.stringify(obj)) {
return true;
}
}
return false;
}
</script>
Here's a working fiddle - http://jsfiddle.net/1gfaocLb/
Radio is a unique value, so it's easy to filter by.
Selected types are array of values so it's needs a little more attention.
myApp.filter('typesFilter', function() {
return function(files, types) {
return files.filter(function(file) {
if(types.indexOf(file.type) > -1){
return true;
}else{
return false;
}
});
};
});
According the shared code / fiddle, I've simplified the code for a possible solution. The file filtering logic is not foreseen since it was not clear what needed to be done exact.
<body ng-app="myapp">
<div ng-controller="myctrl">
<label>
<input type="radio" ng-model="inputCreatedBy" value="byX"
ng-click="filterFiles()"> by X
<input type="radio" ng-model="inputCreatedBy" value="byAll"
ng-click="filterFiles()"> by All
</label> <br/><br/>
<label>
<input type='checkbox' ng-model='Type1Files' ng-change='filterFiles()'>Type1 files
<input type='checkbox' ng-model='Type2Files' ng-change='filterFiles()'>Type2 files
</label>
<br/><br/>
<label ng-repeat="file in filteredFiles">
{{ file.name }} <br/>
</label>
</div>
</body>
var app = angular.module("myapp",[])
app.controller('myctrl', function ($scope) {
$scope.files = [
{ name: 'file1', type:'Type1', createdBy: 'X' },
{ name: 'file2', type:'Type2', createdBy: 'X' },
{ name: 'file3', type:'Type2', createdBy: 'Y' },
{ name: 'file4', type:'Type1', createdBy: 'Y' }
];
$scope.filterFiles = function(){
// init dict
var files = [];
// loop & check files
angular.forEach($scope.files, function(value, key) {
// do file check and push to files.push when matching with criteria
files.push(value);
});
// set scope files
$scope.filteredFiles = files;
}
// init filter on ctrl load
$scope.filterFiles();
});
First, you don't have to use any directive as ng-if/ng-click to achieve what you want. Just changing how the values are binding into the radio button and checkbox can do the trick. Also you just need to do a custom filter to handle the checkbox selections, since radio button is unique. Take a look on my solution:
angular.module("myApp", [])
.controller('myCtrl', function($scope) {
$scope.files = [
{
"name":"file1",
"type":"Type1",
"createdBy":"X"
},
{
"name":"file2",
"type":"Type2",
"createdBy":"X"
},
{
"name":"file3",
"type":"Type2",
"createdBy":"Y"
},
{
"name":"file4",
"type":"Type1",
"createdBy":"Y"
}
];
})
.filter('typesFilter', function() {
return function(files, types) {
if (!types || (!types['Type1'] && !types['Type2'])) {
return files;
}
return files.filter(function(file) {
return types['Type1'] && file.type == 'Type1' || types['Type2'] && file.type == 'Type2';
});
};
});
<html ng-app="myApp">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="myCtrl">
<form action="" name="form">
Created by:
<input type="radio" id="radio1" ng-model="criteria.createdBy" value="X">
<label for="radio1">by X</label>
<input type="radio" id="radio2" ng-model="criteria.createdBy" value="">
<label for="radio2">by All</label>
<br/>
<br/>
Type:
<input type="checkbox" id="check1" ng-model="criteria.type['Type1']">
<label for="check1">Type1 files</label>
<input type="checkbox" id="check2" ng-model="criteria.type['Type2']">
<label for="check2">Type2 files</label>
</form>
<pre ng-bind="criteria | json"></pre>
<div ng-repeat="file in files | filter: { createdBy: criteria.createdBy } | typesFilter: criteria.type" ng-bind="file.name"></div>
</body>
</html>
monkeyStuff does what i want, it updates the span content if i write in the input field.
But why doesn't it work with the voteStuff?
See it in Action: Fiddle
<body>
<div id="monkeyStuff">
<input type="text" data-bind="value:monkey" />
<span data-bind="text:monkey"></span>
</div>
<hr>
<div id="voteStuff">
<div data-bind="text: test"></div>
<ul data-bind="foreach: voters">
<li>
<input type="text" data-bind="value:name" />
<span data-bind="text:name"></span>
</li>
</ul>
</div>
<script>
var vm = {
monkey: ko.observable()
};
vm.monkey("Quak");
ko.applyBindings(vm, document.getElementById('monkeyStuff'));
var model = {
test: 'Test address text',
voters: ko.observableArray([
{ name: 'First Voter' },
{ name: 'Second Voter' }
])
};
ko.applyBindings(model, document.getElementById('voteStuff') );
</script>
</body>
EDIT: OK it works like this:
voters: ko.observableArray([
{ name: ko.observable('First Voter') },
{ name: ko.observable('Second Voter') }
])
But is there a way to do it automatic for each property in the voters array?
You need to make the name property of the elements in your voters ko.observableArray also observable, which would thus allow you to alter these properties with the bindings you have implemented:
voters: ko.observableArray([
{ name: ko.observable('First Voter') },
{ name: ko.observable('Second Voter') }
])
Working example: http://jsfiddle.net/he2zoa3d/2/