I'm trying to prevent ng-click action if css class is empty or not equal until class="visited" that allows ng-click action
Here is my code
<ul class="nav nav-wizard">
<li>
Step 1
</li>
<li>
Step 2
</li>
<li>
Step 3
</li>
<li>
Step 4
</li>
<li>
Step 5
</li>
</ul>
These shouldn't be executed by click until css class is showed like this.
<li class="visited">
Step 1
</li>
This is able to do click if it meets class="visited" condition.
<a ng-click="doSomething($event.currentTarget.getAttribute('class'))">Hello, click me</a>
// In controller:
$scope.doSomething = function(classes) {
if(classes && classes.indexOf("visited") > -1){
//do click properly
}else{
//do nothing
}
};
https://jsfiddle.net/rpuczu4a/
This is probably something you don't want to do as AngularJS philosophy is to focus on model manipulation and let AngularJS do the rendering (based on hints from the declarative UI). Manipulating DOM elements and attributes from a controller is a big no-no in AngularJS world.
You can make it work like so using the pointer-events css attribute (The jQuery is just demonstration Javascript):
$('a[ng-click]').click(function(event) { event.preventDefault(); this.innerHTML = "YAY"; });
a[ng-click] {
pointer-events:none;
}
a[ng-click].visited {
pointer-events:all;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Test(DISALLOW CLICK) <br />
Test (ALLOW CLICK)
Related
I want to add isActive class to an item menu when user click on this item, and remove isActive class from all others items.
I am trying to compare the id, this is the angularJS code:
$rootScope.isActive = function(idVal, event){
return idVal === event.target.id;
}
This is a part from Menu Html code:
<ul class="sidebar-nav">
<li>
<a ui-sref="" id='101' ng-class="{active: isActive($event, 101)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Rules
</a>
<ul class='dropdown sidebar-nav-dropdown' >
<li>
Transaction Mapping
</li>
<li>
File Setup
</li>
<li>
Code Setup
</li>
</ul>
</li>
<li>
<a href="#" id='102' ng-class="{active: isActive($event, 102)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Administrative Rules
</a>
<ul class='dropdown sidebar-nav-dropdown'>
<li>
<a ui-sref="admin.mapping-rules">Transaction Mapping</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">File Setup</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">Code Setup</a>
</li>
</ul>
</li>
</ul>
Thanks,
First of all, you shouldn't use the root scope. You should use the scope of the controller associated to that view.
Second, your code doesn't make much sense. $event can be used as a parameter of a function called... to react to an event:
ng-click="doSomething($event)"
But with ng-class, there is no $event.
All you need to have in your scope is the ID (or name, or whatever identifies a menu item) of the selected menu item:
$scope.selectedMenuItem = null;
When an item is clicked, you need to change the selected menu item:
ng-click="selectMenuItem(101)"
$scope.selectMenuItem(item) {
$scope.selectedMenuItem = item;
}
Then to associated a css class with the selected menu item, you simply need
ng-class="{active: selectedMenuItem === 101}"
That said, if all your links navigate to a given router state, you don't even need that selectedMenuItem. All you need is to add the active class if the current router state is the one the that the link allows navigating to (assuming $state is on your scope):
ng-class="{active: $state.includes('admin.mapping-rules')}
I have tried to find some solution on google about this but couldn't get an exact answer.
I am trying to change tabs inside a view using below code:
<ul class="nav nav-tabs">
<li class="{active: selectedTab === 'details'}"><a href ng-click="selectTab('details')">Details</a></li>
<li class="{active: selectedTab === 'size'}"><a href ng-click="selectTab('size')">Size</a></li>
<li class="{active: selectedTab === 'shipping'}"><a href ng-click="selectTab('shipping')">Shipping</a></li>
</ul>
But whenever I am clicking on "Size" tab, the view redirects to some page. I mean URL changes
from http://localhost:8080/abcd/index.html#/ TO http://localhost:8080/Final_Albatross/index.html#/size
Without view implementation, the click refers to id "size" and tab changes.
Definitely angular is treating this click as a new view call. Please help me out!!
My JS file:
mainAngular.controller('ProductDetailController', function($scope, $routeParams) {
$scope.prod_Id = $routeParams.prodId;
$scope.selectTab = function(tabName) {
alert(tabName);
$scope.selectedTab = tabName;
alert($scope.selectedTab);
}
});
Although I have achieved it using "target="_self" but I want to do it in angular way.
Using anchor links in Angular require target="_self".
https://docs.angularjs.org/guide/$location
<ul>
<li>Link</li>
<li>Anchor</li>
</ul>
Forget about the jQuery, DOM way to handle that kind of problems. Use the angular way.
In AngularJS, the single point of truth is the model. The view (i.e. the HTML) is only a representation of that model, that changes automatically when the model changes.
So, you want a selected tab. Add that to the model:
$scope.selectedTab = 'details';
You want to be able to change which tab is selected. That is as simple as
$scope.selectTab = function(tabName) {
$scope.selectedTab = tabName;
}
And you want the view to be reflect the model values:
<ul class="nav nav-tabs">
<li class="{active: selectedTab === 'details'}"><a href ng-click="selectTab('details'}">Details</a></li>
<li class="{active: selectedTab === 'size'}"><a href ng-click="selectTab('size'}">Size</a></li>
</ul>
I am very new to Angular and I have this piece of code:
<nav ng-controller="navController">
<ul>
<li ng-class="{'active': location('/') || location('/homepage')}">
view puppies
</li>
</ul>
</nav>
With the corresponding controller:
obApp.controller('navController', function($scope, $location) {
$scope.location = function(loc){
if(loc == $location.path()){
return true;
}else{
return false;
}
}
})
Now everything works fine. When I'm on the homepage the list element gets the class active added to it, HOWEVER there is also the angular ng-class directive code shown in the source, like so (this is the HTML source output of the browser):
<li ng-class="{'active': location('/') || location('/homepage')}" class="active">
view puppies
</li>
Should the list element not look like: <li class="active">view puppies</li> ? Logic would dictate that it should look like it is now, because ng-controller="x" shows in the source as it is as well. However that's a hook if you will. The other one's an expression. It looks funky and I'm not sure if it's ok or not. Please, if you answer, detail your answer.
There is nothing wrong with your code, ng-class directive doesn't remove the attribute ng-class from the element when the expression evaluates to true, since you could have more than one expression/class in your ng-class attribute value.
Additionally if the directive did remove the attribute (ng-class) angular would have no way of knowing that you have applied that directive to the element. For example, your element had ng-if on it, it would be removed from the DOM and appended conditionally.
Example
ng-class="{'active': location('/') || location('homepage'), 'disabled': location('private'))}"
Such usage of ng-class is non-effective because $scope.location method will be called at least twice (for location('/') and location('homepage')) each digest loop. There could be a lot of digest loops due to balancing mechanism.
Better approach is to calculate if element is active on location change.
Controller:
$scope.$on('$locationChangeSuccess', function(){
$scope.isHomePage = location('/') || location('/homepage');
});
Markup:
<nav ng-controller="navController">
<ul>
<li ng-class="{'active': isHomePage}">
view puppies
</li>
</ul>
</nav>
i'm new in AngularJS, but did some jQuery before. i've got a problem to understand how to get the clicked element / it's parent to make some changes like change the text, an icon or a class in the item where i made the click.
the simple HTML:
<ul ng-controller="basketCtrl">
<li ng-repeat="item in item">
<button ng-click="addToBasket(Itemid,this,whatever)">
<i class="myBasketicon">
<span>Buy now</span>
</button>
</li>
</ul>
what i want to do:
$scope.addTobasket = function (id, elem, whatever){
// to some JSON-Server-stuff - that works perfect
// now my problems, :
//change this -> myBasketIcon -> myOKicon
//change this -> span text Buy now-> Thanks for buying
// give the this -> li an class => 'changed'
}
I really tried a lot, f.e with ng-model in the tags, arrays... search the web half the day... but didn't find anything that matches my problem.
Maybe it's just the way of thinking not the angular way... so please help :O)
Kind regard from Hamburg, Germany
Timo
You should be able to do this by changing a property (angular way), no need to access the element in the ng-click handler,and using ng-class and angular binding on that property.
<ul ng-controller="basketCtrl">
<li ng-repeat="item in items" ng-class="{'changed': item.added}">
<button ng-click="addToBasket(item)">
<i ng-class="{'myBasketicon':!item.added,'myOKicon':item.added }">
<span>{{item.added ? "Thanks for buying" : "Buy now"}}</span>
</button>
</li>
</ul>
and in your handler just do:
$scope.addTobasket = function (item){
item.added = true;
}
Most cases, whole purpose of using angular is to avoid DOM manipulation and let angular manage it, you just deal with the models/viewmodels and bindings.
You should add methods for the icon class and text that change their results based on the state of the object, or use custom a custom directive. You definitely don't want to be doing any DOM manipulation (changing text/classes etc) the way you would have done with jQuery.
For the method-based approach, something like this for your markup:
<li ng-repeat="item in item">
<button ng-click="addToBasket(item)">
<i ng-class="getClass(item)">
<span>{{getMessage(item)}}</span>
</button>
</li>
and on your controller:
.controller('ShoppingListCtrl', function($scope) {
$scope.getClass = function(item) {
return item.inBasket ? 'myOkIcon' : 'myBasketIcon';
};
$scope.getMessage = function(item) {
return item.inBasket ? 'Thanks for buying' : 'Buy now';
};
})
This could also be done with a custom directive which is a super powerful way to do things (and definitely worth figuring out) but may be overkill for just starting out. If you find you are adding a lot if methods for doing these sorts of things go with directives.
Given a list such as
var list = ['one','two','three'];
In angular, I want to iterate through the list only rendering certain items. Something like:
<ul ng-controller="main">
<li ng-repeat="item in list" ng-switch on="item">
<span ng-switch-when="one">{{item}}</span>
</li>
</ul>
And have the output look like this:
<ul>
<li><span>one</span></li>
</ul>
Instead, I get:
<ul>
<li><span>one</span></li>
<li></li>
<li></li>
</ul>
I have tried ng-hide but is woefully inefficient since I have a large number of items and only want to display one or two and ng-hide renders all of them and then hides the inactive ones with css. This is a problem because I am doing this in a JQuery Mobile app which tries to decorate all list items, including the hidden ones, killing performance.
JSFiddle at http://jsfiddle.net/ghendricks/MXu3a/
You are correct that ng-hide should not be used here, it is a job for filters.
You can provide a custom function to filter the list: http://jsfiddle.net/ERMVj/
$scope.selectOne = function (input) { return input == "two" || input == "one"; };
<li ng-repeat="l in list | filter:selectOne">
<span>{{l}}</span>
</li>