i had managed to calculate distance between user's current geo-coordinates and object geo-coordiantes, here is the working plunker. How can I sort ng-repeat from the smallest to the highest value ?.
It is easy with the orderBy filter with simple expression, but this expression which prints distance is a bit tricky !thanks.
HTML:
<div data-ng-controller="restaurantlistController" >
<div ng-repeat="restaurant in restaurantList | orderBy: 'distance'" href="#">
<article class="item_frame">
<div class="marker_left_container">
<span class="venu_type_text">{{restaurant.venueType}}</span>
<span class="distance_from_user_rest"> distance: {{distanceTo(restaurant)}}</span>
<span class="distance_from_user_rest2">from current location</span>
</div>
<div class="restaurant_details_container">
<h1 class="restaurant_name_inlist">{{restaurant.Name}}</h1>
<span class="restaurant_detail_inlist2">{{restaurant.subCuisine}} <br />
{{restaurant.subsubCuisine}}</span>
<span class="restaurant_address">{{restaurant.address}}, <br />
</span>
<span class="restaurant_address">{{restaurant.cp}}, {{restaurant.city}} <br />
</span>
<span class="restaurant_others">{{restaurant.phoneNumber}} <br />
</span>
<span class="restaurant_others">{{restaurant.website}} <br />
</span>
<span>-------------------------------------------------</span>
</div>
</div>
</article>
<!--main article frame 1 -->
</div>
In your controller you should update the distanceTo function to the following:
$scope.distanceTo = function(restaurant) {
var distance = GreatCircle.distance( restaurant.long,restaurant.lat, position.longitude, position.latitude)
restaurant.distance = distance;
return distance;
}
Now your filter should work, because it is checking for the restaurant.distance property.
Instead of using orderBy, you could just sort the array:
$scope.restaurantList.sort(function(a,b) { return someDistanceFunction(a,b) } );
How about just giving the distanceTo function as the orderBy predicate:
<div ng-repeat="restaurant in restaurantList | orderBy:distanceTo" href="#">
From orderBy documentation:
Orders a specified array by the expression predicate.
A predicate to be used by the comparator to determine the order of
elements.
Can be one of:
function: Getter function. The result of this function will be sorted
using the <, ===, > operator.
Related
I click the sort button, get all prices, and I need to ensure that elements were sorted correctly by prices. So I need to get price value="377", price value="1288", price value="1688" etc. but I can't get the right elements.
<div class="ssl-price-box">
<price value="377" units="/yr" class="lg-price ng-isolate-scope">
<span class="price">
<span class="currency-icon">$</span>
<span class="integer ng-binding">3.</span>
<span class="cent ng-binding">77</span>
<span class="units">/yr</span>
</span>
</price>
<!-- ngIf: product.prices.max.certIsPromo -->
</div>
<div class="ssl-content">
<div class="ssl-price-box">
<price value="1288" units="/yr" class="lg-price ng-isolate-scope">
<span class="price">
<span class="currency-icon">$</span>
<span class="integer ng-binding">12.</span>
<span class="cent ng-binding">88</span>
<span class="units">/yr</span>
</span>
</price>
i tried search be css, className, xpath, repearet, i thought if they are all the same repeater would work.
My code:
const allSSLList = $$('.ssl-price-box');
const newAllSSLList = allSSLList.sort((a, b)=>a-b));
expect(await allSSLList).toBe(massiveOfElements)
I need to get only prices, e.g. "3.77", "12.88", "16.88" etc. and then verify if they are ASC sorting but I got all prices, even old ones. I need to get only where
<span class="price">
<price value="377" units="/yr" class="lg-price ng-isolate-scope">
Expected [ '$3.77/YR', '$12.88/YR $26.99/YR', '$16.88/YR $31.99/YR', '$19.66/YR $35.88/YR', '$30.88/YR $44.99/YR', '$38.88/YR $95.99/YR', '$59.99/YR', '$68.88/YR $138.99/YR', '$70.88/YR $96.99/YR', '$78.19/YR', '$78.19/YR', '$134.99/YR', '$138.88/YR $215.89/YR' ] to be 'smth'.
Stack:
From the HTML provided, it looks like the CSS selector div.ssl-price-box > price will get you all the price elements you need. From there, you can use .getAttribute() to pull the value attribute from each element as "377", "1288", etc. Then you would want to convert those string values into numbers, copy that array, sort the second array, and then compare to the first list to verify that the two lists are sorted.
I get prices, even that I don't need, how can I filter them?
<div class="ssl-price-box">
<price value="377" units="/yr" class="lg-price ng-isolate-scope"><span class="price"><span class="currency-icon">$</span><span class="integer ng-binding">3.</span><span class="cent ng-binding">77</span><span class="units">/yr</span></span></price>
<!-- ngIf: product.prices.max.certIsPromo -->
</div>
<price value="13888" units="/yr" class="lg-price ng-isolate-scope">
<span class="price">
<span class="currency-icon">$</span>
<span class="integer ng-binding">138.</span>
<span class="cent ng-binding">88</span>
<span class="units">/yr</span>
</span>
</price>
<price ng-if="product.prices.max.certIsPromo" value="21589" units="/yr" old-price="" class="base-price ng-scope ng-isolate-scope">
<span class="price old-price">
<span class="currency-icon">$</span>
<span class="integer ng-binding">215.</span>
<span class="cent ng-binding">89</span>
<span class="units">/yr</span>
<span class="line-through"></span>
</span>
</price>
I have no idea how to do it. I tried
const allSSLList = element.all(by.css('div.ssl-price-box')).all(by.className("span[class='price']"));
and this
const allSSLList = element.all(by.css('div.ssl-price-box > price'));
expect(await allSSLList)).toBe(newPrices)
I got all elements, but I don't need old price in tag class="price old-price" from second css, because I need compare Array with all new prices
Expected [ '377', '1288', '2699', '1688', '3199', '1966', '3588', '3088', '4499', '3888', '9599', '5999', '6888', '13899', '7088', '9699', '7819', '7819', '13499', '13888', '21589' ] to be 'newPrice'.
With the HTML provided, it looks like you can use the XPath
//div[#class='ssl-price-box']/price[not(#old-price)]
^ find a DIV that has the right class
^ find a child PRICE tag
^ that does not contain the attribute "old-price"
to only get the price that aren't old prices. From there, you can use .getAttribute() to pull the value attribute from each element as "377", "1288", etc.
allSSLList will return an array with all the prices, as you are getting inside the expectation. You need to specify which element from the array you want with a .get(index);
But please provide more info because from the html snipped it's not clear exactly what element do you need to retrieve
I have the following in a view file:
<p class="presentation black">Sections:
<span data-ng-if="currentTab == 'tab1'">
<div ng-repeat="question in filtered = (template.questions | unique:'sectionName')"></div>
<p class="presentation black">{{filtered.length}}</p>
</span>
<span data-ng-if="currentTab == 'tab2'">
<div ng-repeat="sheet in filtered = (template.sections[0].sheets | unique:'name')"></div>
<p class="presentation black">{{filtered.length}}</p>
</span>
</p>
When tab1 is selected, the information is displayed correctly. However when on tab2, it appears that <p> element in both spans is being displayed - an empty value in displayed for the <p> element related to tab1. By looking at the DOM tree it also seems that when on tab2, the ng-if condition is not displaying: <!-- end ngIf: currentTab == 'tab2' -->. Can anyone see where the issue may be? Let me know if more code is required.
The "p" shouldn't be in a "span" according to HTML5 specs. Change the "span" to a "div".
HTML
<p class="presentation black">Sections:
<div data-ng-if="currentTab == 'tab1'">
<div ng-repeat="question in filtered = (template.questions | unique:'sectionName')"></div>
<p class="presentation black">{{filtered.length}}</p>
</div>
<div data-ng-if="currentTab == 'tab2'">
<div ng-repeat="sheet in filtered = (template.sections[0].sheets | unique:'name')"></div>
<p class="presentation black">{{filtered.length}}</p>
</div>
</p>
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.
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.