apply css on menu item click - javascript

I have a little test application here...
http://jsfiddle.net/poppypoop/LMCC2/
I was wondering how I would accomplish the same functionality with angular js. Ultimately adding the 'active' class to the selected menu item while applying the name to the header below. In the fiddle I've done it with jquery, but now I'm wondering how this would be accomplished through angularjs
var app = angular.module("app", []);
function ctrl($scope, Data)
{
}
Would it be best to do it in a directive or controller?

You don't want to be setting the class and modifying the HTML within angular at all. Instead, the angular model should represent the data of your application and use databinding to change view-related properties such as classes, etc.
In your case, the scope could have a list of menu items and a property that holds the currently active item. And when a menu item is clicked on, the active item changes. All the changes in the view are handled by angular databinding...
$scope.items = ['Home', 'Tickets', 'Direct Deposit', 'activity',
'Pay Rate Inquiry', 'Templates'];
$scope.activeItem = 'Home';
$scope.setActive = function (activeItem) {
$scope.activeItem = activeItem;
};
View
<div class="menu-container">
<ul id="menu-ul" class="nav">
<li ng-repeat="item in items">
<a ng-class="{ active: item === selectedItem }" href="#"
ng-click="setActive(item)">{{ item }}</a>
</li>
</ul>
</div>
<div class="nav-selection">
<span>{{ activeItem }}</span>
</div>
JsFiddle: http://jsfiddle.net/xx7KF/

In angular you can use ng-class for adding a class with a boolean condition:
AngularJS - ng-class
You can bind the class to a boolean var in your scope, and when you click on the button, update it with the value you need.

Related

bind click event to the element in ng-repeat angular

I have menu and use ng-repeat for loop to the my category and in this loop i have a link tag and I want to when clicked on this link do something in js file.
But I can't access to the tag a in javascript and add click event to this element.
Here is my ng-repeat code:
<li class="has-children" ng-repeat="category in categories |filter:{ level: 1 } : true" ng-if="$index < 5">
<a class="parent-link">{{category.categoryName}}</a>
<ul class="is-hidden">
<li class="go-back"><a>{{category.categoryName}}</a></li>
<li ng-repeat="submenu in categories |filter:{ parentID: category.categoryID } : true"><a>{{submenu.categoryName}}</a></li>
</ul>
</li>
Here is my js file (this code doesn't fire):
$(".parent-link").on("click", function(e) {
console.log("clicked");
e.prenvetDefault()
});
Use ng-click. It can be used as attribute of element. Example usage:
HTML:
<div ng-click="changeWord()">
{{word}}
</div>
Controller:
$scope.changeWord = function () {
$scope.word = 'I am changed';
}
See http://jsfiddle.net/ax6k3z1e/
Possible reason could be that you Javascript is getting executed before the DOM is ready. You should use ng-click as It's good to build through Angular way when you are using AngularJS in you application.
ng-Repeat have the tendency to bind your iterating object as well. Below is the example for the same.
<div ng-repeat='ele in elements'>
<p ng-click='ShowAlert(ele)'>{{ele.name}}</p>
</div>
Specify below mentioned code in your linked controller.
$scope.ShowAlert=function(element){
alert(element.Name);
}

How to use $index in ng-repeat angular js

I have posted my question
How to create check box from multidimensional array using angular js
But I have not gotten any response. I have debug my code when I am going to add second ng-repeat I am getting
Error: ngRepeat:dupes Duplicate Key in Repeater
When I am adding repeat by $index I am getting single character as key and value too
Please help me I am new in angular js :(
This is my fiddle of code http://jsfiddle.net/ashishoft/03L3faq5/2/
Here is example:
ng-repeat="i in items track by $index"
Pretty simple really. You can even use it in combination with custom directives etc. Its basically an index of where you are in the loop.
There are some flaws with using it though. If your creating an ng-repeat list, and then passing the $index into some click function or something, then you can have issues if your also using filtering on that same list. The $index can fall out of sync with the filters and leave you wondering why its giving you wrong data.
for example:
<li ng-repeat="page in links | someFilter:filter">
<a ng-click="someFunction($index)">{{ someData }}</a>
</li>
vs the better way of:
<li ng-repeat="itemX in someData | someFilter:filter">
<a ng-click="someFunction(itemX)">{{ itemX.name }}</a>
</li>
So although I use the $index in my example below, its often best just to pass the whole object in when doing more complex functions per row.
HTML:
<div ng-app="myApp" ng-controller="MainCtrl">
<ul>
<li ng-repeat="page in links">
<a ng-class="{ testClass: $index == pageNumber }" ng-click="setPageNumber($index)">{{ page }}</a>
</li>
</ul>
</div>
Javascript:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.links = [
'Link One',
'Link Two',
'Link Three'
];
$scope.pageNumber = 0;
$scope.setPageNumber = function(index) {
$scope.pageNumber = index;
}
});
CSS:
.testClass {
background: black;
color: white;
}
This is a sample of how it could be written, although using $index is just fine. Might I suggest using something else like the element id or title, here is an article that talks about ng-repeat.
<div class="favorite-children" ng-repeat="photo in ctrl.favorties track by $index">
<div class="card"></div>
</div>
//or
<div class="favorite-children" ng-repeat="photo in ctrl.favorties track by photo.title">
<div class="card"></div>
</div>
Update
Try this FIDDLE for a preview of a comprehensive JSON, with your same code previewed on how you can use it. Hope it helps.

Is there a way to pass data from `ng-repeat` to other element conditionally?

I am looping over an array, by the conditional I am finding a value. But how to pass that conditional value to another element?
Example :
<h1>{{title}}</h1> //how to get here?
<ul class="naviPrCatgInfo">
<li ng-repeat='subProject in viewProject.SubProjectIds' ng-class="{'selected' : subProject.Id === subProjectId;}" > //how to pass?
<a ng-class="subProject.Name | trimSpace" ng-href="" ng-click='changeSubProCat(subProject)'>
{{subProject.Name}} {{subProject.Id}}
</a>
</li>
</ul>
Don't declare the new variable inside ng-repeat, because that will get added inside the child scope created by the ng-repeat.
You need to keep subProjectId outside the ng-repeat scope so that could be available inside the controller, you need to use $parent anotation to place that variable inside the controller scope rather than the ng-repeat.
So you can easily filter viewProject.SubProjectIds on the basis of subProjectId and show the title element there.
Markup
<h1>{{(viewProject.SubProjectIds| filter: {Id: subProjectId}: true)[0].Name}}</h1>
<ul class="naviPrCatgInfo">
<li ng-repeat='subProject in viewProject.SubProjectIds' ng-click="$parent.subProjectId = subProject.Id"
ng-class="{'selected' : subProject.Id === subProjectId}">
<a ng-class="subProject.Name | trimSpace" ng-href="" ng-click='changeSubProCat(subProject)'>
{{subProject.Name}} {{subProject.Id}}
</a>
</li>
</ul>

How do I select "this" in angular?

I have 5 buttons using the same ng-click function. Basically each of the buttons operate similarly to a tabbed navigation, where you click one of the buttons and it takes you to that tab's pane. Each of these buttons can be repeatable and are housed in a template. The tab panes are also all in a template but aren't all active until a user clicks one of the buttons and creates a page. So basically there are multiple click functions nested within click functions that do different things depending on what user has activated.
In jQuery, I could just use "this" and select the object that was clicked and do all my manipulations to that object easily; however, it doesn't appear there's a way to do that using just angular. Currently, when you click one of these buttons it does the same thing to all of them. I figure I could create 5 separate functions, but I don't want to do that for scalability reasons.
So to summaraize:
Is there a way to select "this" in Angular?
I'd like a solution that is just using Angular and no jQuery
Is there an efficient way of dealing with click functions within click functions?
<nav class="block--menu">
<section class="content--menu" ng-controller="ActiveCtrl">
<div class="menu" >
<button class="menu__item" ng-click="showConfirm()"></button>
<button class="menu__item" ng-click="showConfirm()"></button>
<button class="menu__item" ng-click="showConfirm()"></button>
<button class="menu__item" ng-click="showConfirm()"></button>
<button class="menu__item" ng-click="showConfirm()"></button>
</div>
</section>
You can access jQuery event object using $event in angular events check the documentation for details but if you are sending that to your controller it most likely means you are not doing it in angular way.
the usage is
<button class="menu__item" ng-click="showConfirm($event)"></button>
and in the controller
$scope.showConfirm = function($event){
//$event.target should be your link
};
You should stop thinking in a jQuery way and don't try to manipulate the DOM directly. In your controller you should only manipulate the data, which is then reflected in the view. When you think Angular-way, your code usually looks as follows:
HTML
<section ng-controller="ActiveCtrl as ctrl">
<div class="menu" >
<button ng-repeat="button in ctrl.buttons track by $index"
ng-click="ctrl.showConfirm(button)"
ng-class="{'menu__item_active':button.active, 'menu__item':true}"
>{{button.name}}</button>
</div>
</section>
JavaScript
angular.module('app',[]).
controller('ActiveCtrl', ['$window', function($window) {
this.buttons = [{
name: 'First'
}, {
name: 'Second'
}, {
name: 'Third'
}];
this.showConfirm = function(button) {
button.active = !button.active;
$window.alert(button.name);
}
}]);
Plunker
http://plnkr.co/edit/Dg10cXqFxEKgEt7jWQ7Z?p=preview

Angular UI Bootstrap Accordion Adding a Class to header

I have the following accordion which is working fine
<accordion-group is-open="open.first">
<accordion-heading>
My Title
</accordion-heading>
</accordion-group>
The "Accordion-heading" directive translates into something like
<h4 class="panel-title">
<a class="accordion-toggle"
accordion-transclude="heading" ng-click="toggleOpen()" href="">
My Title
</h4>
What I want is when someone clicks on this accordion option/title is to add to toggle a class on the h4 attribute. In jquery I would do it like this
$('.panel-heading .panel-title').on('click', function () {
$(this).toggleClass('actives');
});
I think I have to do it as a directive, but not quite sure how ?
Assuming you are using ng-repeat on your <accordion-group> directive, you can do something like this:
<accordion-group ng-repeat="group in groups" ng-init="group.isOpen = false" ng-class="{'open': group.isOpen}" is-open="group.isOpen">
This initializes a new $scope variable in ng-init called isOpen that is attached to the individual group you are repeating over (group.isOpen). In my example above, I've made it false so that all accordion groups are closed on load, and then assigning that variable to is-open. When you click or "open" one of the accordion groups, the directive will automatically change group.isOpen to true. This will then allow the ng-class expression to evaluate true as well and add the class "open" to the panel-heading in the DOM.

Categories