Angular ngclick add class to all siblings - angularjs

How to add class to all siblings expect the clicked one. When I click the one I want, I want to apply class blue to all siblings not the one I clicked.
http://jsfiddle.net/bm6kujL1/
<div ng-app="editer" ng-controller="myCtrl" class="container">
<div ng-repeat="item in items">
<div class="wrap" ng-click="show =!show" ng-class="{'blue':show}">
<span>{{item.name}}</span>
<span ng-show="show">{{item.thing}}</span>
</div>
</div>
</div>
//JS
function myCtrl($scope) {
$scope.editedItem = null;
$scope.items = [{
name: "item #1",
thing: "thing 1"
}, {
name: "item #2",
thing: "thing 2"
}, {
name: "item #3",
thing: "thing 3"
}];
$scope.show = false;
}
var editer = angular.module('editer', []);
//CSS
.wrap {
background: yellow;
}
.blue {
background: blue;
}

I made some small changes to your JS fiddle, and it works now. Basically, you only had one attribute called show for all items, but you needed to know for each one if it should be blue or not.
JS:
function myCtrl($scope){
$scope.editedItem = null;
$scope.items = [
{ name :"item #1", thing: "thing 1", selected: false},
{ name :"item #2", thing: "thing 2", selected: false},
{ name :"item #3", thing: "thing 3", selected: false}
];
function resetAllItems() {
for (i in $scope.items) {
$scope.items[i].selected = false;
}
}
$scope.selectItem = function(item) {
resetAllItems();
item.selected = true;
}
}
HTML
<div ng-app="editer" ng-controller="myCtrl" class="container">
<div ng-repeat="item in items">
<div class="wrap" ng-click="selectItem(item)" ng-class="{'blue': item.selected}">
<span>{{item.name}}</span>
<span ng-show="item.selected" >{{item.thing}}</span>
</div>
</div>
</div>

You can use a function instead and use the item show property.
HTML:
<div class="wrap" ng-click="toggleShow(item)" ng-class="{'blue':item.show}">
<span>{{item.name}}</span>
<span ng-show="item.show">{{item.thing}}</span>
</div>
JS:
$scope.items = [{
name: "item #1",
thing: "thing 1",
show: false
}, {
name: "item #2",
thing: "thing 2",
show: false
}, {
name: "item #3",
thing: "thing 3",
show: false
}];
$scope.toggleShow = function(item){
for(var i=0; i<$scope.items.length; ++i){
if($scope.items[i] === item){
$scope.items[i].show = false;
continue;
}
$scope.items[i].show = true;
}
}
fiddle:
http://jsfiddle.net/bm6kujL1/2/

Related

angular radio button set checked

i have multiple radio button groups
i need to set one of each group (maybe none) as selected
datasource
html Code
<div class='row' ng-show="mk.selectedTypeAttributesID.length != 0">
<div class='col-xs-6 col-sm-6 col-md-6 col-lg-6' ng-repeat="att in selectedTypeAttributesID">
<div class="switch-field">
<div class="switch-title">{{att.name}}</div>
<div>
<input ng-repeat-start="val in att.Values" class="bttn-input" type="radio" id="switch_{{val.val}}" name="switch_{{att.id}}" value="{{val.val}}" ng-click="mk.AttChange(att.id,val.val)" />
<label ng-repeat-end class="bttn-input" for="switch_{{val.val}}">{{val.val}}</label>
</div>
</div>
</div>
</div>
i need to use the value of 'Selected' On the datasource to set the checkbox
source Update
You need to use ng-model to select the radio button..
Where ng-model holds the selected value as shown below.
$scope.options = [{Selected: false, val: "red"}, {Selected: true, val:"Black"}, {Selected: false, val:"Pink"}];
$scope.selected = undefined;
var findResult = $scope.options.find(function(x){ return x.Selected == true });
if(findResult){
$scope.selected = findResult.val;
}
Here's a JSFiddle
Edit: Since the sources of the checkboxes are dynamic then build a dynamic selection tree for modal to bind to..
Here's an example:
$scope.options = [{ 0 : [{Selected: false, val: "red"}, {Selected: true, val:"Black"}, {Selected: false, val:"Pink"}]}, { 1 : [{ Selected: false, val: "2" }, { Selected: true, val: "1" }]}];
$scope.choices = [];
for(var i = 0; i < Object.keys($scope.options).length; i++){
var keys = Object.keys($scope.options);
$scope.choices.push({ Id: keys[i], Value: $scope.options[i][keys[i]].find(function(x){ return x.Selected == true }).val });
}
JSFiddle
Are you looking for a solution like so?
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.selectedTypeAttributesID = [{
id: 1,
Values: [{
val: "red",
selected: ""
}, {
val: "green",
selected: ""
}, {
val: "blue",
selected: ""
}]
},
{
id: 2,
Values: [{
val: "1",
selected: ""
}, {
val: "2",
selected: ""
}, {
val: "3",
selected: ""
}]
}
];
$scope.setVal = function(att, index, val) {
for (var k of att.Values) {
k.selected = "";
}
att.Values[index].selected = val;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller='MyController' ng-app="myApp">
<div class='row'>
<div class='col-xs-6 col-sm-6 col-md-6 col-lg-6' ng-repeat="att in selectedTypeAttributesID">
<div class="switch-field">
<div class="switch-title">{{att.name}}</div>
<div>
<input ng-repeat-start="val in att.Values" class="bttn-input" type="radio" id="switch_{{val.val}}" name="switch_{{att.id}}" ng-value="val.val" ng-click="setVal(att, $index, val.val)" />
<label ng-repeat-end class="bttn-input" for="switch_{{val.val}}">{{val.val}}</label>
</div>
</div>
</div>
</div>
<pre>{{selectedTypeAttributesID | json}}</pre>
</div>

angular js filter inside ng-change

my data template looks like this,
scope.items=[{"name:"John","score":1},{"name":"Rick","score":5},{"name":"Peter","score":2}]
I have a select box with values 0,1,2,3,4,5 and would like to filter items object based on score value selected in dropdown
scope.scores= [
{
"name":"condition 0",
"value":"0"
},
{
"name":"condition 1",
"value":"1"
},
{
"name":"condition 2",
"value":"condition 2"
},
{
"name":"condition 3",
"value":"3"
},
{
"name":"condition 4",
"value":"4"
},
{
"name":"condition 5",
"value":"5"
}
]
HTML
<select id="scoreS" ng-model="score" ng-change="updateScore()">
<option
ng-repeat="score in scores"
value="{{score.value}}">{{score.name}}</option>
</select>
So when i select condition 0 from my dropdown box I need to filter items to show only those objects matching score(key) 0 and when I select 1 from the drop down , match only items having score(key) 1 and so on. how do you do this inside updateScore() function ?
Try like this. it's better use ng-options instead of ng-repeat in drop-down
var app = angular.module('anApp', []);
app.controller('aCtrl', function($scope) {
$scope.items=[
{"name":"John","score":1}
,{"name":"Rick","score":5}
,{"name":"Peter","score":2}
]
$scope.scores= [
{
"name":"condition 0",
"value":"0"
},
{
"name":"condition 1",
"value":"1"
},
{
"name":"condition 2",
"value":"2"
},
{
"name":"condition 3",
"value":"3"
},
{
"name":"condition 4",
"value":"4"
},
{
"name":"condition 5",
"value":"5"
}
]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="anApp" ng-controller="aCtrl as vm">
<select id="scoreS" ng-model="score" ng-options="score.value as score.name for score in scores ">
</select>
<div ng-repeat="item in items| filter:{score:score}">
<span>{{item.name}}</span>
</div>
</div>
use filter option to filter the data according to drop down
<div ng-repeat="item in items | filter :score">
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.scores= [
{
"name":"condition 0",
"value":"0"
},
{
"name":"condition 1",
"value":"1"
},
{
"name":"condition 2",
"value":"2"
},
{
"name":"condition 3",
"value":"3"
},
{
"name":"condition 4",
"value":"4"
},
{
"name":"condition 5",
"value":"5"
}
]
$scope.items=[{"name":"John","score":1},{"name":"Rick","score":5},{"name":"Peter","score":2}]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select id="scoreS" ng-model="score" ng-change="updateScore()">
<option ng-repeat="score in scores" value="{{score.value}}">{{score.name}}</option>
</select>
<div ng-repeat="item in items | filter :score">
{{item.name}}= {{item.score}}
</div>
</div>

AngularJS filter items by array of properties (checkbox)

I would like to filter the results by multiple properties.
My code:
(function () {
'use strict';
angular.
module('myApp', []).
filter('byFeatures', byFeatures).
controller('MyCtrl', MyCtrl);
function byFeatures() {
return function (items, conditions) {
if (Object.getOwnPropertyNames(conditions).length === 0) {
return items;
}
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
angular.forEach(item.features, function (feature) {
if (conditions[feature.name] !== undefined && conditions[feature.name][feature.value] !== undefined) {
if (conditions[feature.name][feature.value]) {
//filtered.push(item);
filtered[item.id] = item;
}
}
});
}
//console.log(filtered);
return filtered;
};
};
function MyCtrl($scope, $filter) {
$scope.allProducts = [{
id: 0,
name: "Product A",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 1,
name: "Product B",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "32"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 2,
name: "Product C",
features: [{
name: "Brand",
value: "Nokia"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 3,
name: "Product A",
features: [{
name: "Brand",
value: "Samsung"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
];
$scope.filters = [{
name: "Brand",
values: [
"Apple",
"Nokia",
"Samsung",
]
},
{
name: "Memory",
values: [
"16",
"32",
]
},
];
$scope.currentFilter = {};
$scope.$watch('currentFilter', function (newValue, oldValue, scope) {
//console.log(newValue);
$scope.products = $filter('byFeatures')($scope.allProducts, newValue);
}, true);
};
}());
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<title></title>
</head>
<body ng-app="myApp" class="ng-scope">
<div ng-controller="MyCtrl" style="width: 100%;">
<div style="width: 50%; float: left;">
<h2>Available Phones</h2>
<div ng-repeat="product in products">
<h3>
{{ product.name }}
</h3>
<ul>
<li ng-repeat="feature in product.features">
{{feature.name}} : {{feature.value}}
</li>
</ul>
</div>
</div>
<div style="width: 50%; float: left;">
<h2>Filters</h2>
<pre>{{currentFilter|json}}</pre>
<div ng-repeat="filter in filters">
<span>{{filter.name}}</span>
<ul>
<li ng-repeat="value in filter.values">
<input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br>
</li>
</ul>
</div>
</div>
</div>
</body></html>
If i filter by brand "Apple" are displayed 2 phones with brand "apple" (16 and 32 memory) - its ok. But if i add second filter by memory "16" - will must display only 1 phone apple with memory "16".
How to do it? . Link to JSFiddle
The problem is that you are doing the opposite from what you want: You are checking that the product contains a valid property for one of the items (Brand or Memory). What we need to do is check if the product has a valid property for all the items (Brand and Memory).
It would be enough to change the loop inside the function byFeatures in order to find every relevant condition (When its value is true!) and make sure that our product has one of the selected properties for each, Brand and Memory. Here you can see the right snippet:
(function () {
'use strict';
angular.
module('myApp', []).
filter('byFeatures', byFeatures).
controller('MyCtrl', MyCtrl);
function byFeatures() {
return function (items, conditions) {
if (Object.getOwnPropertyNames(conditions).length === 0) {
return items;
}
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i],
hasProperties = true;
angular.forEach(conditions, function (value, key) {
for (var i = 0; i < item.features.length; i++) {
if (item.features[i].name === key && (!value.hasOwnProperty(item.features[i].value) || !value[item.features[i].value])) {
for (var j in value) {
if (value[j]) {
hasProperties = false;
}
}
}
}
});
if (hasProperties) {
filtered.push(item);
}
}
//console.log(filtered);
return filtered;
};
};
function MyCtrl($scope, $filter) {
$scope.allProducts = [{
id: 0,
name: "Product A",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 1,
name: "Product B",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "32"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 2,
name: "Product C",
features: [{
name: "Brand",
value: "Nokia"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 3,
name: "Product A",
features: [{
name: "Brand",
value: "Samsung"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
];
$scope.filters = [{
name: "Brand",
values: [
"Apple",
"Nokia",
"Samsung",
]
},
{
name: "Memory",
values: [
"16",
"32",
]
},
];
$scope.currentFilter = {}; //$scope.filters;
$scope.$watch('currentFilter', function (newValue, oldValue, scope) {
$scope.products = $filter('byFeatures')($scope.allProducts, newValue);
}, true);
};
}());
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="js/script.js"></script>
<title></title>
</head>
<body ng-app="myApp" class="ng-scope">
<div ng-controller="MyCtrl" style="width: 100%;">
<div style="width: 50%; float: left;">
<h2>Available Phones</h2>
<div ng-repeat="product in products">
<h3>
{{ product.name }}
</h3>
<ul>
<li ng-repeat="feature in product.features">
{{feature.name}} : {{feature.value}}
</li>
</ul>
</div>
</div>
<div style="width: 50%; float: left;">
<h2>Filters</h2>
<pre>{{currentFilter|json}}</pre>
<div ng-repeat="filter in filters">
<span>{{filter.name}}</span>
<ul>
<li ng-repeat="value in filter.values">
<input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
I also changed the way you were adding the new product to the filtered array. Otherwise, if the ID of the only item is 2, the array would keep the first 2 positions as 'undefined' and this would cause troubles through the ngRepeat iterations

AngularJS : `Load more` button in each group of ng-repeat with many groups titles

I want to add load more button to the bottom of each group like the image here, and after clicking the button it shows rest of parts of the relevant group
where a,g are groups titles those have group property
In the snippet bellow, the code return only one load more button, and with no consideration of the group property.
var myApp = angular.module('myApp',[]);
myApp.controller('main', ['$scope', function($scope) {
$scope.test = "test";
$scope.filteredModules = [
{
"name":"a",
"group":"a"
},
{
"name":"b",
},
{
"name":"c",
},
{
"name":"c",
},
{
"name":"e",
},
{
"name":"f",
},
{
"name":"g",
"group":"g"
}
,{
"name":"h",
},
{
"name":"i",
},
{
"name":"j",
},
{
"name":"k",
}
,
{
"name":"l",
}
];
$scope.limit = 4;
$scope.loadMore = function() {
var increamented = $scope.limit + 4;
$scope.limit = increamented > $scope.filteredModules.length ? $scope.filteredModules.length : increamented;
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="main">
<div ng-repeat="node in filteredModules | limitTo:limit track by $index">
<div ng-if="!node.group">{{node.name}}</div>
<div ng-if="node.group" style="background-color:red">{{node.name}} </div>
</div>
<button ng-click="loadMore()">Load more</button>
</div>
</div>
Please try this snippet
var myApp = angular.module('myApp',[]);
myApp.controller('main', ['$scope', function($scope) {
$scope.filteredModules = {
"groups":
[
{
"title": "Alfreds Futterkiste",
"childs": ["child-1", "child-2", "child-3", "child-4", "child-5", "child-6","child-7", "child-8", "child-9"],
"limit": "3"
},
{
"title": "Ana Trujillo Emparedados y helados",
"childs": ["child-1", "child-2", "child-3", "child-4", "child-5", "child-6"],
"limit": "4"
},
{
"title": "Antonio Moreno Taquería",
"childs": ["child-1", "child-2", "child-3", "child-4", "child-5", "child-6"],
"limit": "3"
}
]
};
$scope.loadMore = function(index) {
$scope.filteredModules.groups[index].limit = parseInt($scope.filteredModules.groups[index].limit) + 3;
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="main">
<div ng-repeat="node in filteredModules.groups track by $index">
<div ng-if="node.title" style="background-color:red">{{node.title}}
</div>
<div ng-repeat="child in node.childs | limitTo: node.limit">
{{child}}
</div>
<br/>
<button ng-click="loadMore($index)" ng-hide="node.limit >= node.childs.length">Load more</button>
<br/><br/>
</div>
</div>
</div>

How do I cancel drag between different lists when using angular-ui's sortable module

I am using angular-ui's sortable-ui module and am trying to raise a cancel so that the dragged items returns to it original location in the source list. Unfortunately I cannot get this working. Here is an example:
http://jsfiddle.net/Ej99f/1/
var myapp = angular.module('myapp', ['ui.sortable']);
myapp.controller('controller', function ($scope) {
$scope.list = ["1", "2", "3", "4", "5", "6"];
$scope.list2 = ["7", "8", "9"];
$scope.sortableOptions = {
update: function(e, ui) {
if (Number(ui.item.text()) === 6) {
ui.item.parent().sortable('cancel');
}
},
receive: function(e, ui) {
ui.sender.sortable('cancel');
ui.item.parent().sortable('cancel');
},
connectWith: ".group",
axis: 'y'
};
});
angular.bootstrap(document, ['myapp']);
Any help would be gratefully appreciated.
well, when it comes to angular, all roads lead to the data "the single source of truth". So update your model back to it's original state, before the move, and you're all set :)
example below has two lists, the first one being restricted for
its sorting (the update method)
and for sending an item (receive method on list 2)
the second list you can sort, and send items to list 1
(using foundation4 for css)
<div ng-app="test">
<div ng-controller="sortableTest">
<div class="small-4 columns panel">
<ul data-drop="true"
ui-sortable="sortable.options.list1" ng-model="sortable.model.list1">
<li ng-repeat="fruit in sortable.model.list1"
data-id="{{ fruit.id }}">{{ fruit.label }}</li>
</ul>
</div>
<div class="small-4 columns panel">
<ul data-drop="true"
ui-sortable="sortable.options.list2" ng-model="sortable.model.list2">
<li ng-repeat="element in sortable.model.list2"
data-id="{{ element.id }}">{{ element.label }}</li>
</ul>
</div>
<div class="clear"></div>
<br />
<span ng-repeat="fruit in sortable.model.list1">{{ fruit.label }} </span><br />
<span ng-repeat="element in sortable.model.list2">{{ element.label }} </span><br />
<span ng-repeat="fruit in sortable.oldData.list1">{{ fruit.label }} </span><br />
<span ng-repeat="element in sortable.oldData.list2">{{ element.label }} </span><br />
</div>
</div>
js:
var test = angular.module('test', ['ui.sortable']);
test.controller('sortableTest', function($scope, $timeout) {
$scope.sortable = {
model: {
list1: [{id: 1, label: 'apple'},{id: 2, label: 'orange'},{id: 3, label: 'pear'},{id: 4, label: 'banana'}],
list2: [{id: 5, label: 'earth'},{id: 6, label: 'wind'},{id: 7, label: 'fire'},{id: 8, label: 'water'}]
},
oldData: {
list1: [],
list2: []
},
options: {
list1: {
update: function(event, ui) {
console.debug('up-list1');
$scope.sortable.oldData.list1 = $scope.sortable.model.list1.slice(0);
$scope.sortable.oldData.list2 = $scope.sortable.model.list2.slice(0);
// DO NOT USE THIS! it messes up the data.
// ui.item.parent().sortable('cancel'); // <--- BUGGY!
// uncomment and check the span repeats..
$timeout(function(){
$scope.sortable.model.list1 = $scope.sortable.oldData.list1;
$scope.sortable.model.list2 = $scope.sortable.oldData.list2;
});
},
connectWith: 'ul'
},
list2: {
update: function(event, ui) {
console.debug('up-list2');
},
connectWith: 'ul',
receive: function(event, ui) {
console.debug('re-list2');
$timeout(function(){
$scope.sortable.model.list1 = $scope.sortable.oldData.list1;
$scope.sortable.model.list2 = $scope.sortable.oldData.list2;
});
}
}
}
};
});
you can of course use a service or something to store the old value. One can use ui.sender to differentiate the senders, if you have more that two..

Resources