How to get position of iterated element angularjs? - angularjs

I have iterated dropdown and I would like to know what is the position of each of these dropdowns when I click on it.
<div class="row" ng-repeat="animal in vm.animals">
{{animal}}
<btn-group uib-dropdown>
<button class="btn btn-secondary btn-sm uib-dropdown-toggle
ng-click="vm.checkPosition($event)">{{vm.test}}
</button>
<div class="dropdown-menu" uib-dropdown-menu>
<a class="dropdown-item" ng-repeat="dog in vm.dogs">
{{dog}}
</a>
</btn>
function checkPosition($event) {
// I tried use here $event.target.el.getBoundingClientRect().top, but this
// position isnt element which I clicked, but propably first element with
// this class
}

As the docs describe, you have access to certain variables inside of your ng-repeat.
For example $first is true only for the first element, $last only for the last one.
What you are looking for is $index

If you mean the index of the array you can use $index as Scorpioo590 mentioned. which in angularjs will give you the item's index in the array that is used in the ng-repeat you can use it like this:
ng-click="vm.checkPosition($event, $index)"
function checkPosition($event, index) {
console.log(index);
}

Related

Getting undefined value for $index in angularjs

I have a button code block in jsp below which will pass $index of a selected checkbox to a javascript function in controller js which is defined on $scope. But when i try to print the $index on console i am getting undefined value for $index.
Code in Jsp
<button type="button" class="btn btn-warning"
ng-disabled='validCheckbox'
**ng-click="addTemplate($index)">**
<i class="glyphicon glyphicon-plus"></i> Add Middle
</button>
Code in Js.
$scope.addTemplate = function(index){
console.log("index"+index);
You can use $index only in ng-repeat in angular.js. Here is an example of how to use $index.
Let say you have StringArray=['a','b','c'];
<div ng-repeat="c in StringArray">
<label>{{$index}}</label>
</div>
The result is :0, 1, 2

how to create greater than and less than filter in angularjs ng-repeat

I am trying to use range slider in angularjs to filter the grid. I want a greater than and less than filter in my ng-repeat. But I am not getting how to do this. I am using the following code for now. But this is not working for me. This code is not giving me desired output
Here is my html for grid
<div class="col-md-3 product-left-grid" ng-repeat="data in Products| filter:priceSlider.max |filter:priceSlider.min">
<div class="product-grid"></div>
<div class="product-grid-text">
<a href="javascript:void(0)">
<img alt="" src="{{data.Picture1}}">
</a>
<div class="products-grid-info">
<div class="price">
<a class="btn btn-sm btn-width btn-default btn-font-weight"
href="javascript:void(0)"
ng-click="viewDetails($index)">Quick View</a>
<a href="javascript:void(0)"
class="btn btn-sm btn-width btn-default btn-font-weight"
ng-click="addToCart (data.ProductID,data.Picture1,data.ProductName,data.UnitPrice,data.Discount,data.ShippingCharges,data.wieght)">Add to cart</a>
<div class="tovar_description clearfix">
<a class="tovar_title" href="#"><b>{{data.ProductName}} </b> | {{data.UnitPrice | currency:mycurrency}}</a>
</div>
</div>
<div class="clearfix"> </div>
</div>
</div>
</div>
this is my price range slider
<rzslider rz-slider-floor="priceSlider.floor"
rz-slider-ceil="priceSlider.ceil"
rz-slider-model="priceSlider.min"
rz-slider-high="priceSlider.max"
rz-slider-on-change="onSliderChange()"></rzslider>
Now I am using filter but I have doubt that I am going wrong somewhere. Please experts help to solve this problem. Price range filter I need like every eCommerce website have.
Thanks
You have to make a custom filter :
//create an angular filter named "price"
app.filter('price', function () {
//our function will need three arguments
return function(items, greaterThan, lowerThan) {
//then we filter the array with dedicated ES5 method
items = items.filter(function(item){
//if item price is included between the two boundaries we return true
return item.price > greaterThan && item.price < lowerThan;
});
//then we return the filtered items array
return items;
};
});
You can see how Array.filter() works here
Our function will need 3 arguments to work, the items list which is passed by default and the lower and higher boundaries that we will pass as arguments in our ng-repeat filter.
Then you can use the filter as follow :
<div ng-repeat="data in Products | price:priceSlider.min:priceSlider.max | orderBy:'price'">...</div>
As I said above, items array is passed by default, then, to specify other parameters you have to separate them with a colon : right after the filter name.
You can read about custom filters in the official documentation here.
Finally you can then specified as many other filters as you want by separating them with a pipe |.
In our example I'm ordering them by price after the array has been filtered.
Here is a working JSFiddle.

Angular ng-class affect multiple elements

I have a code that I generate using Python's Mako templates:
<ul class="list-group">
% for t in list:
<li class="list-group-item">
<div
ng-class="hover ? 'btn btn-xs btn-default' : ''"
ng-mouseenter="hover = true"
ng-mouseleave="hover = false"> ${list.data} </div>
</li>
% endfor
</ul>
All I want is that the row I'm hovering of - will be converted to a button.
Problem is that I see a list of rows ,but when the mouse hover on one of the elements - all elements are affected instead of the specific <li> element I was hovering of , like all the text inside all the rows are converted to buttons.... any idea what am I missing ?
Your hover variable is being assigned in the global scope. Using ng-repeat fixes this because each template instance gets its own scope.
To fix this without ng-repeat you can namespace the hover property within the list object, like in this Plunker.

Count group elements using angular-filter

Is it possible using angular-filter "groupBy" (https://github.com/a8m/angular-filter#groupby) to count the elements in each group to use in a "badge" span (of course without using a a function doing the "manual count")
<div class="list-group" ng-repeat="(key, value) in directoryResult | groupBy: 'TableId'">
<a href="#" class="list-group-item active">
<span class="glyphicon glyphicon-transport"></span> {{convertTableid(key)}} <span class="badge">{{directoryResult.length}}</span>
</a>
<div class="list-group" ng-repeat="item in value">
<a href="#" class="list-group-item">
<span class="glyphicon glyphicon-transport"></span> {{item.Text}}
</a>
</div>
</div>
If you do something like:
ng-repeat="(key, value) in directoryResult | groupBy: 'TableId' as result"
then result will be the filtered variable. You can check the length of that for the number of groups.
Update:
Here is a plunker with a groupBy filter.
http://plnkr.co/edit/8jB4wSRtKfVmEsTGZtfV?p=preview
I took an existing filter I found (since angular doesn't have a built in one) and added a length property. The results show up properly.
Update 2:
Another plunker:
http://plnkr.co/edit/iwUkIMjvevja7KyfTrFC?p=preview
Since angular-filter doesn't provide a length property, you have to count it yourself with Object.keys
<div>Number of groups: {{numGroups(result) }} </div>
JS:
$scope.numGroups = function(input){
return Object.keys(input).length;
}
Update 3:
the result contains an object literal: each property is named "key" and its value is a subgroup of the list. So the running solution is:
<div>Number of groups: {{numGroups(result[key]) }} </div>
Update 4
Finally we may get rid completly of the numGroups function, using directly:
<div>Number of groups: {{result[key].length}} </div>
So your first idea was the good one, I had just to adapt it as my groupBy resturn an object literal containing all the goruped lists.

angularjs how set right scope for function?

have this ng-repeat
<li class="tmmenu-admin-tabs-builder-panel-portlet" ng-repeat="question in questions">
<div>
<span class="tmmenu-admin-tabs-builder-panel-portlet-toggler" ng-click="tatbppTogler()">{{{tatbppt}}}</span>
<span class="tmmenu-admin-tabs-builder-panel-portlet-number">{{question.id}}</span>
{{question.text}}
</div>
<div class="tmmenu-admin-tabs-builder-panel-portlet-options" ng-show="showTatbppo">
...
</div>
</li>
I want, for click in "tmmenu-admin-tabs-builder-panel-portlet-toggler" change visibility "tmmenu-admin-tabs-builder-panel-portlet-options" and change text in "tmmenu-admin-tabs-builder-panel-portlet-toggler".
And i write this code for get result:
$scope.tatbppTogler = function(){
$scope.showTatbppo = !$scope.showTatbppo;
if($scope.showTatbppo){
$scope.tatbppt = "-";
}else{
$scope.tatbppt = "+";
}
}
It's works, but changed dom in all "Li", how changed only current (where user click) "li"?
You can do it like this:
<li class=portlet" ng-repeat="question in questions">
<div>
<span class="toggler" ng-click="showTatbppo=!showTatbppo">{{showTatbppo ? "+" : "-" }}</span>
<span class="number">{{question.id}}</span>
{{question.text}}
</div>
<div class="options" ng-show="showTatbppo">
...
</div>
</li>
Working fiddle, with this concept:
http://jsfiddle.net/x1nguaxj/
btw. You have very-very-very long css class names :)
1 way
you can pass this in ng-click="tatbppTogler(this)" and then in function manipulate with this
2 way
you can create custom directive and apply it to your li element and then on this directive bind click to element and listen , and on click function will be triggered your listener and you will have access on this element
You can create an attribute id for each question and then change based on the id of the question you clicked
I would suggest you'd take a look at $index. From the angularjs docs:
iterator offset of the repeated element (0..length-1)
Using this, you can clearly determine the certain div that was clicked on.

Resources