Ng repeat and ng class mistake - angularjs

I have some categories and subcategories.When I select category it apears subcategories.Next I want to select a subcategory of category selected but the class is changing.
I want, when I select a category to be able to select a subcategory of that category.Here is the codepen :
http://codepen.io/anon/pen/GZKBaW.
Thanks for help! :)
<html lang="en" ng-app="StarterApp">
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js">
</script>
</head>
<body ng-controller="AppCtrl">
<ul class="main">
<li ng-repeat="a in categories"
ng-class="{active : toggled==$index,none:toggled!=$index}"
ng-click="set($index)">{{a.name}}
<ul>
<div ng-show="showData">
<li ng-class="{'active':event==$index,'none':event!=$index}" ng-repeat="b in subcategories" ng-click="setSubcategory($index,b)">{{b}}</li>
</ul>
</li>
</ul>
</body>
</html>

Shouldn't access html directly,
Your'e accessing html directly and you shouldn't in your case. i would change your controller to
var app = angular.module('StarterApp', []);
app.controller('AppCtrl', ['$scope', function($scope) {
$scope.categories = [{
'name': 'work',
'subcategories': ['saved', 'study', 'plm']
}, {
'name': 'move',
'subcategories': ['saved', 'study', 'xxx']
}, {
'name': 'flirt',
'subcategories': ['saved', 'travel', 'aaa']
}];
$scope.setSelectedCategory = function(category){
$scope.selectedCategory = category;
}
$scope.setSelectedSubcategory = function(subcategory){
$scope.selectedSubcategory = subcategory;
}
}]);
and your html to,
<ul class="main">
<li ng-repeat="category in categories" ng-click="setSelectedCategory(category)" ng-class="{'active' : category == selectedCategory}">
{{category.name}}
<ul ng-show="category == selectedCategory">
<li ng-class="{'active':selectedSubcategory == subcategory}" ng-repeat="subcategory in category.subcategories" ng-click="setSelectedSubcategory(subcategory)">{{subcategory}}</li>
</ul>
</li>
</ul>
http://codepen.io/anon/pen/XdrPqm

Related

AngularJS: uncheck checkboxes with no ng-model attribute

I want to uncheck all checkboxes when press some button. I need to do this on AngularJS (no jQuery). My checkboxes don't have ng-model attribute. How I can uncheck them?
My HTML structure:
<li ng-repeat="channel in channelsList">
<div class="checkbox">
<label><input type="checkbox" value="" ng-click="isChecked(channel.id)">
<img src="images/checkbox-unchecked.png" alt="" class="unchecked">
<img src="images/checkbox.png" alt="" class="checked"><span>{{channel.name}}</span>
</label>
</div>
</li>
My channelsList is only an array of objects with 2 properties: id and name.
Thanks for helping!
Two ng-ifs
If you really want to avoid ng-model you could achieve the same effect with... notice the checked attribute
<li ng-repeat="channel in channelsList">
<div class="checkbox">
<label>
<input ng-if="isChecked(channel.id);" type="checkbox" checked ng-click="check(channel.id);">
<input ng-if="!isChecked(channel.id);" type="checkbox" ng-click="check(channel.id);">
<img src="images/checkbox-unchecked.png" alt="" class="unchecked">
<img src="images/checkbox.png" alt="" class="checked"><span>{{channel.name}}</span>
</label>
</div>
</li>
Bind checkbox ng-model to a _selected property.
Please note that I use _selected and not selected in case your API would in a near future return a selected property that would collide with this one.
index.html
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="SampleController">
<ul>
<li ng-repeat="channel in channelsList">
<input type="checkbox" ng-model="channel._selected" /> {{channel.name}} (id={{channel.id}})
</li>
</ul>
<button ng-click="uncheckAll()">Uncheck all</button>
</body>
</html>
script.js
angular.module('app', []);
angular.module('app').controller('SampleController', function ($scope) {
$scope.channelsList = [
{id: 'c1', name: 'CNN'},
{id: 'c2', name: 'BBC'},
{id: 'c3', name: 'Discovery Channel'}
];
$scope.uncheckAll = function() {
angular.forEach($scope.channelsList, function (channel) {
channel._selected = false;
});
};
});
Here is the plunker : http://plnkr.co/edit/VPOjKMUVyrMpPfT9jLz3
I don't know exactly what you need but supposing you have an array of ids telling the ids checked like this:
$scope.channelsList = [
{'id' : 1, 'name' : 'foo' },
{'id' : 2, 'name' : 'bar' },
{'id' : 3, 'name' : 'foo' }
];
var checked = [1, 3]
$scope.isChecked = function(id){
return checked.indexOf(id) >= 0;
};
You can put a button like:
<button ng-click="uncheckAll()">click</button>
And use it to clear your array:
$scope.uncheckAll = function(){
checked = [];
}

angularjs pass index through directive

I need help with this code.
<ul ng-init="round = 'round'">
<li ng-repeat="mesa in mesas" ng-click="selected($index)">
<div id="{{round}}"> </div>
MESA {{mesa}}
</li>
</ul>
$scope.selected = function ($index){
$scope.index.round = 'round1';
}
I need that only the li that is being clicked to change the css name, but instead it change all of the li's that I have listed.
You're initializing the variable round outside of the repeat loop, so the expression {{round}} will always point to that singular, shared variable. If you update it once, it updates for all children of the ng-repeat.
If I understand your question, you're trying to change the CSS class for the div inside the repeat, correct? What you can do in that case is store the selected index on the controller's scope, and check that value against the index inside the loop
<ul>
<li ng-repeat="mesa in mesas" ng-click="select($index)">
<div class="round1" ng-if="selectedIndex === $index"> </div>
<div class="round" ng-if="selectedIndex !== $index"> </div>
MESA {{mesa}}
</li>
</ul>
$scope.select = function ($index){
$scope.selectedIndex = $index;
}
You could also use ng-class instead of ng-if depending on how your CSS is structured, but the idea is the same.
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<style type="text/css">
.round {
background: green;
}
.round1 {
background: blue;
}
</style>
</head>
<body ng-controller="controller">
<ul>
<li ng-repeat="mesa in mesas" ng-click="selected($index)" ng-class="[index[$index].round]">
<div id="{{ index[$index].id }}"> </div>
MESA {{ mesa }}
</li>
</ul>
</html>
<script type="text/javascript">
angular.module('app', [])
.controller('controller', controller);
controller.$inject = ['$scope'];
function controller($scope) {
$scope.mesas = ['1', '2', '3'];
$scope.index = [{
id: '1',
round: 'round'
}, {
id: '2',
round: 'round'
}, {
id: '3',
round: 'round'
}];
$scope.selected = function($index) {
$scope.index[$index].round = $scope.index[$index].round === 'round' ? 'round1' : 'round';
}
}
</script>
I think is what u looking for¿?

My angular script only works when I open my html page as a static file and not when I run it with django

I've got an array inside my <script> tags and am trying to reference it in the html body:
<html ng-app="myApp">
<head>
<link rel="stylesheet" type="text/css" href="https://bootswatch.com/yeti/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('HomeController', function($scope){
this.posts = feedback;
});
app.controller('TabController', function($scope){
this.tab = 1;
this.setTab = function(newValue){
this.tab = newValue;
};
this.isSet = function(tabName){
return this.tab === tabName;
};
});
var feedback = [{
author: 'Joe Shmo',
body: 'I really love this product, no complaints',
votes: 0,
createdOn: 1397490980837,
tags: ['great', 'cool'],
people: ['Santa Clause']
},
{
author: 'Stinky Pete',
body: 'Sucky product all around',
votes: 0,
createdOn: 1397490980837,
tags: ['terrible', 'stinks'],
people: ['Tooth Fairy']
}];
</script>
</head>
<body>
<section ng-controller="TabController as tab">
<ul class="nav nav-pills nav-stacked">
<li ng-class="{ active:tab.isSet(1) }">
<a href ng-click="tab.setTab(1)">Home</a>
</li>
<li ng-class="{ active:tab.isSet(2) }">
<a href ng-click="tab.setTab(2)">Groups</a>
</li>
<li ng-class="{ active:tab.isSet(3) }">
<a href ng-click="tab.setTab(3)">Notifications</a>
</li>
<div ng-show="tab.isSet(1)" ng-controller="HomeController as home">
<h3>Home Base</h3>
<div ng-repeat="post in home.posts">
<h4>{{ post.author }} <em class="pull-right">{{ post.votes }}</em></h4>
<h5>{{ post.createdOn | date }}</h5>
<p>{{ post.body }}</p>
</div>
</div>
<div ng-show="tab.isSet(2)">
<h3>Your Groups</h3>
</div>
<div ng-show="tab.isSet(3)">
<h3>Nothing to see here.</h3>
</div>
</ul>
</section>
</body>
When I have this running in the browser, I don't get any errors, but when I click the "Home" tab, only Home Base appears and, upon inspecting the page, the <h4>, <h5> and <p> tags are all there, but they are empty. Any help would be appreciated!
FOLLOW UP: I'm using Angular1.4.9, Django1.9 with REST framework, could it be some kind of compatibility issue?
As many of the comments have said, the content is displayed when you open it as a static file, but when I have my django server going, the content does not appear.
I was able to get this to work by doing two things:
Using $scope for the "posts" var:
Replace this:
app.controller('HomeController', function($scope){
this.posts = feedback;
});
With This:
app.controller('HomeController', function($scope){
$scope.posts = feedback;
});
Next - Remove "home" from the ng-repeat here:
<div ng-controller="HomeController as home">
<h3>Home Base</h3>
<div ng-repeat="post in posts">
<h4>{{ post.author }}
<em class="pull-right">{{ post.votes }} </em></h4>
<h5>{{ post.createdOn | date }}</h5>
<p>{{ post.body }}</p>
</div>
</div>
looks like you may be using angular version 1.1.4 or below. Your code works if angular is v 1.1.5 or above. This is because Controller as syntax used in your code was introduced post 1.1.5
None working fiddle: http://jsfiddle.net/halirgb/Lvc0u55v/
This gives below error. Check your console.
Error: Argument 'TabController as tab' is not a function, got undefined
Working Fiddle: http://jsfiddle.net/Lzgts/683/
var app = angular.module('myApp', []);
app.controller('HomeController', function($scope){
this.posts = feedback;
});
app.controller('TabController', function($scope){
this.tab = 1;
this.setTab = function(newValue){
this.tab = newValue;
};
this.isSet = function(tabName){
return this.tab === tabName;
};
});
var feedback = [{
author: 'Joe Shmo',
body: 'I really love this product, no complaints',
votes: 0,
createdOn: 1397490980837,
tags: ['great', 'cool'],
people: ['Santa Clause']
},
{
author: 'Stinky Pete',
body: 'Sucky product all around',
votes: 0,
createdOn: 1397490980837,
tags: ['terrible', 'stinks'],
people: ['Tooth Fairy']
}];
Turns out it was an issue with Django and Angular. Both use the {{ }} notation so the interpreter was seeing {{ post.author }} as django and not angular. The way to fix this was to put {% verbatim %} and {% endverbatim %} at the beginning and end of my html file, and it works now!

Access in a function to the scope of the clicked object in angular

I have to access a function to the scope of the clicked object in angular. I have to write to the console the id of the object, but without passing the object to the called function by the click event.
Could some one help me with my problem?
Below is the code what I have achieved so far.
<ul data-ng-app="myApp" data-ng-controller="myController">
<li data-ng-repeat="x in names" data-ng-bind="x.title" data-ng-click="fnct(x)"></li>
</ul>
<script>
angular.module('myApp', []).controller('myController', function($scope) {
$scope.names = [{id: 2345, title: 'title1'}, {id: 9876, title: 'title2'}];
$scope.fnct = function(obj) {
console.log(obj.id);
}
});
</script>
You can use this keyword which will refer to current child scope so you don't have to pass x into function explicitly:
<ul data-ng-app="myApp" data-ng-controller="myController">
<li data-ng-repeat="x in names" data-ng-bind="x.title" data-ng-click="fnct()"></li>
</ul>
Here is complete example:
angular.module('myApp', []).controller('myController', function($scope) {
$scope.names = [{id: 2345, title: 'title1'}, {id: 9876, title: 'title2'}];
$scope.fnct = function() {
console.log(this.x.id);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<ul data-ng-app="myApp" data-ng-controller="myController">
<li data-ng-repeat="x in names" data-ng-bind="x.title" data-ng-click="fnct()"></li>
</ul>
Try
<ul data-ng-app="myApp" data-ng-controller="myController">
<li data-ng-repeat="x in names" data-ng-bind="x.title" data-ng click="fnct(x.id)"></li>
</ul>
<script>
angular.module('myApp', []).controller('myController', function($scope) {
$scope.names = [{id: 2345, title: 'title1'}, {id: 9876, title: 'title2'}];
$scope.fnct = function(id) {
console.log(id);
}
});
</script>

Angular.js - ng-repeat not working

Angular.js is pretty new to me. I have learned before the $scope method for the controller and now trying the "this" method. For some reason I can not get my ng-repeat to work. here's my code:
HTML:
<ul class="nav nav-pills">
<li><a ng-click="myCtrl.tab=1" href>one</a></li>
<li><a ng-click="myCtrl.tab=2" href>two</a></li>
<li><a ng-click="myCtrl.tab=3" href>three</a></li>
</ul>
<div ng-controller="imageContr as imageCtrl">
<div ng-show="myCtrl.tab === 1" class="tab">
<h3>ONE title</h3>
<p>hello</p>
<li ng-repeat="item in gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
</div>
<div ng-show="myCtrl.tab === 2" class="tab">
<h3>TWO title</h3>
<p>how are</p>
</div>
<div ng-show="myCtrl.tab === 3" class="tab">
<h3>THREE title</h3>
<p>you?</p>
</div>
</div>
</section>
</body>
</html>
APP.JS:
(function() {
var app = angular.module('myApp', []);
app.controller('myController', function() {
this.tab = 1;
});
app.controller('imageContr', function() {
this.gallery = images;
var images = {
photo: 'image1.jpg'
};
});
})();
Declare images before you assign it, and make it an array
var images = [{ photo: 'image1.jpg' }];
this.gallery = images;
Then in your view:
<li ng-repeat="item in imageCtrl.gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
You are storing the gallery on this of the controller (which is basically the $scope), hence you need to access it in the template via imageContr as well:
<li ng-repeat="item in imageCtrl.gallery">
<img alt="imagealt" ng-src="{{item.photo}}">
</li>
You could also consider making gallery an array, so can easily iterate over it. Or you need to use the "iterate over object properties"-syntax:
<div ng-repeat="(key, value) in myObj"> ... </div>

Resources