AngularJS Sortable order pricing issue - angularjs

I'm facing an issue when ordering prices formatted as currency.
var myApp = angular.module("myApp", []);
myApp.factory("Purchases", function() {
var Purchases = {};
Purchases.data = [{
date: "10/05/2012",
text: "1 Lorem ipsum dolor sit amet ipsum dolor",
price: "£90",
availability: "1 Available until 10th Dec 2013"
},
{
date: "24/05/2012",
text: "2 Lorem ipsum dolor sit amet ipsum dolor",
price: "£9.5",
availability: "2 Available until 10th Dec 2013"
},
{
date: "20/05/2012",
text: "3 Lorem ipsum dolor sit amet ipsum dolor",
price: "£10",
availability: "3 Available until 10th Dec 2013"
}
];
return Purchases;
});
function PurchasesCtrl($scope, Purchases) {
$scope.purchases = Purchases;
$scope.sort = {
column: '',
descending: false
};
$scope.changeSorting = function(column) {
var sort = $scope.sort;
if (sort.column == column) {
sort.descending = !sort.descending;
} else {
sort.column = column;
sort.descending = false;
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="PurchasesCtrl">
<h2>Purchases:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first" ng-click="changeSorting('date')">Date</th>
<th ng-click="changeSorting('text')">Description</th>
<th ng-click="changeSorting('price')">Amount</th>
<th ng-click="changeSorting('availability')">Status</th>
</tr>
<tr ng-repeat="purchase in purchases.data|orderBy:sort.column:sort.descending">
<td class="first">{{purchase.date}}</td>
<td>{{purchase.text}}</td>
<td>{{purchase.price}}</td>
<td>{{purchase.availability}}</td>
</tr>
</table>
</div>
</div>
The issue order: $9.5 > $10
Is there any way to correct the ordering?

Yes, check this fiddle: http://jsfiddle.net/2u3wn91z/1/ .
You want to compare numbers, not strings, so you need to separate currency (as first letter of price) and then remove currency from price):
Purchases.data = Purchases.data.map(function (purchase) {
purchase.currency = purchase.price.charAt(0);
purchase.price = Number(purchase.price.substr(1));
return purchase;
});
$scope.purchases = Purchases;
When you have price separated from currency, you can display it separately:
<td>{{purchase.currency}}{{purchase.price}}</td>

Related

Change Single Select to Multiple Select Google Map API

I'm trying to change the single select box to multiple select. I changed the select to include multiple, but when I click multiple selections, none of the markers show up on the Google Map. I'm struggling with how to bind the selections to the sites array that contain the locations. How can Implement a multi select box within the code?
Index.html
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<meta http-equiv="X-UA-Compatible"content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1">
<meta charset="utf-8">
<link rel="stylesheet" href="CSS/bootstrap.min.css">
<link rel="stylesheet" href="CSS/style.css">
</head>
<div ng-app="mapsApp" ng-controller="MapCtrl">
<div align ="center" class ="input-w">
<div class ="gulf">States</div>
<fieldset>
<div class = "flexi">
<label>ISE: </label>
<select id ="ISEs" multiple class="dropdown" name="singleSelect" ng-model="data.singleSelect" ng-change="filterMarkers(); centerMap()">
<option value="0">All</option>
<option value="Bob">Bob</option>
<option value="Sally">Sally</option>
</select><br><br>
</div>
</div>
</fieldset>
</div>
<div id="map"></div>
{{marker.title}}
</div>
</div>
<!--
<script src="js/jquery.min.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.25.0/slimselect.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=myKey"onerror = "googleError()"
></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
App.JS
var sites= [
{name:"ABC",address:"123",lat:"29.97046",lng:"-92.09689",SalesPerson:"Bob"},
{name:"DEF",address:"123",lat:"30.97046",lng:"-92.09689",SalesPerson:"Bob"},
{name:"GHI",address:"123",lat:"31.97046",lng:"-92.09689",SalesPerson:"Sally"},
{name:"JKL",address:"123",lat:"32.97046",lng:"-92.09689",SalesPerson:"Sally"},
];
//Angular App Module and Controller
angular.module('mapsApp', [])
.controller('MapCtrl', function ($scope) {
var mapOptions = {
zoom: 7,
center: new google.maps.LatLng(32.340803,-89.4855946),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
var icons = {
Bob: {
icon: {
url: "http://maps.google.com/mapfiles/ms/icons/green-dot.png"
}
},
Sally: {
icon: {
url: "http://maps.google.com/mapfiles/ms/icons/red-dot.png"
}
}
}
var createMarker = function (info) {
var features = [
{
position: new google.maps.LatLng(info.lat,info.lng),
type: info.SalesPerson
}
]
for (var i =0; i < features.length; i++)
var marker = new google.maps.Marker({
map: $scope.map,
position: features[i].position,
icon:icons[features[i].type].icon,
title: info.name,
});
marker.content = '<div class="iw-ISE">' + info.ISE + '</div>'
+ '<div class="iw-labels">' + "Contact: "+ info.Contact + '</div>'
+ '<div class="iw-labels">' + "Store Phone: "+ info.Phone + '</div>'
+'<p>'+ info.address +'</p>'
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent('<h2 class ="title">' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
for (i = 0; i < sites.length; i++) {
createMarker(sites[i]);
}
$scope.openInfoWindow = function (e, selectedMarker) {
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
$scope.clearMarkers = function() {
for (var i = 0; i < $scope.markers.length; i++) {
$scope.markers[i].setMap(null);
}
$scope.markers.length = 0;
}
$scope.filterMarkers = function() {
//1.select filtered cities
var filteredISE;
var ISEName = $scope.data.singleSelect;
if(ISEName == '0') {
filteredISE = sites;
}
else {
filteredISE = sites.filter(function(c){
if(c.SalesPerson == ISEName)
return c;
});
}
//2.update markers on map
$scope.clearMarkers();
for (i = 0; i < filteredISE.length; i++) {
createMarker(filteredISE[i]);
}
}
}
});
I re-wrote my pen with Angular Js, here is the link codepen.io/ueple/full/ExjaXjL , tell me if it's ok for you ?, or is there's something I've missed ! :-)
After reading your scope, I create an example in Js, not Angularjs like, but with some functionalities you're expecting, I hope so. Tell me if it helps you.
My codePen
What i'm using is an Array of Places and Markers that are read with the function
initalizeMaps.
var mapPlaces = {
id1: {town: 'Decines Charpieu', lat: 45.767000, lng: 4.950000, zoom: 14, display: 1},
id2: {town: 'Paris', lat: 48.851208, lng: 2.348436, zoom: 10, display: 2},
id3: {town: 'New York', lat: 40.748294, lng: -73.985858, zoom: 11, display: 1},
id4: {town: 'Rio de Janeiro', lat: -22.974772, lng: -43.185066, zoom: 8, display: 2},
id5: {town: 'City of Athena', lat: 37.980549, lng: 23.725121, zoom: 10, display: 1}
};
and
var mapMarkers = [
{id: 1,title: 'My town', desc: 'A town of 25000 inhabitants', lat: 45.768811, lng: 4.955300, icon: 'reddot', extraTitle: 'My town Extra Infos', extraDesc: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempor ante ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean commodo mi nec nisl cursus mollis. Nam tortor elit, suscipit vitae tellus at, suscipit pretium metus. Aenean id ultrices ligula. In non dui et magna placerat semper ut et tellus. Ut purus nulla, malesuada a ante malesuada, rhoncus vulputate diam.', url: "https://www.decines-charpieu.fr/uploads/Image/41/IMF_DIAPORAMA_ACCUEIL/GAB_REFONTE/6313_606_Ville-Cuturel.jpg"}];
And the function to read those 2 Arrays is
function initializeMap(idMap)
google.maps.event.addDomListener(window, 'load', initializeMap( currentMap ));
Regards

Angular ng-repeat and dynamic properties

I have a php object that I pass to ng through a function. This object has several properties such as : paragraphe1, paragraphe2, paragraphe3 up to 8.
I try to display it with a ng-repeat loop like :
<div ng-repeat="i in [1,2,3,4,5,6,7,8]">
Paragraphe {{i}} >> {{paragraphe+i}}
</div>
It shows :
Paragraphe 1 >> 1
Paragraphe 2 >> 2
...
Paragraphe 8 >> 8
instead of the content of paragraphe1, ....8
Thanks for your help.
FX
Assuming your paragraph definition is:
$scope.paragraph = {
paragraph1: 'lorem ipsum 1',
paragraph2: 'lorem ipsum 2',
paragraph3: 'lorem ipsum 3',
// ...
}
The template should look like:
<div ng-repeat="i in [1,2,3,4,5,6,7,8]">
Paragraphe {{i}} >> {{paragraph['paragraph' + i]}}
</div>
See js fiddle
Instead of passing the values hard coded you can make use of key, value pairs in the ng-repeat
view:
<div ng-app="myApp" ng-controller="demoCtrl">
<div ng-repeat="(key, value) in paragraph">
{{key}} >> {{value}}
</div>
</div>
JS:
// module
var app = angular.module('myApp', []);
// filter
app.filter('dayFilter', function() {
return function(input) {
var filterFunction = function (item) {
return item.days >= 1 && item.days <= 7;
};
return input.filter(filterFunction);
};
});
//controller
app.controller('demoCtrl', function ($scope) {
$scope.paragraph = {
paragraph1: 'lorem ipsum 1',
paragraph2: 'lorem ipsum 2',
paragraph3: 'lorem ipsum 3'
}
});

AngularJS tabs acting weird

I was wondering if some of you could lighten me and try to explain what I miss in this : http://plnkr.co/edit/opxB2Jfi0Xf0Tq1780vz?p=preview
Looks quite simple to me but does not work.
My code:
<section ng-app="myApp">
<div ng-controller="myCtrl">
<ul ng-init="tab=1">
<li ng-repeat="item in data">
<a href ng-click="tab = item.thingy">{{item.name}}</a>
</li>
</ul>
<div ng-repeat="item in data" ng-show="tab === item.thingy">
<img ng-src="{{item.img}}" width="50px"><br>
{{item.year}}</div>
</div>
</section>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope',
function($scope) {
$scope.data = [{
name: "First",
title: "oneTitle",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
year: "2013",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
thingy: 1
}, {
name: "third",
title: "twoTitle",
description: "Quisque pulvinar libero sed eros ornare",
year: "2014",
img: "http://static.hdw.eweb4.com/media/wp_400/1/1/8519.jpg",
thingy: 2
}, {
name: "Second",
title: "threeTitle",
description: "Cras accumsan massa vitae tortor vehicula .",
year: "2015",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/43326.jpg",
thingy: 3
}, {
name: "fourth",
title: "FourTitle",
description: "Suspendisse vitae mattis magna.",
year: "2011",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42413.jpg",
thingy: 4
}];
}
]);
</script>
Thank you in advance!
modifications in script.js:
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', function ($scope) {
$scope.data = [{
name: "First",
title: "oneTitle",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
year: "2013",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
thingy: 1
}, {
name: "third",
title: "twoTitle",
description: "Quisque pulvinar libero sed eros ornare",
year: "2014",
img: "http://static.hdw.eweb4.com/media/wp_400/1/1/8519.jpg",
thingy: 2
}, {
name: "Second",
title: "threeTitle",
description: "Cras accumsan massa vitae tortor vehicula .",
year: "2015",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/43326.jpg",
thingy: 3
}, {
name: "fourth",
title: "FourTitle",
description: "Suspendisse vitae mattis magna.",
year: "2011",
img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42413.jpg",
thingy: 4
}];
$scope.details = $scope.data[0];
$scope.GetDetails = function(obj)
{
$scope.details = obj;
}
}]
);
In HTML:
<section ng-app="myApp">
<div ng-controller="myCtrl">
<ul ng-init="tab=1">
<li ng-repeat="item in data">
<a href ng-click="GetDetails(item);">{{item.name}}</a>
</li>
</ul>
<div>
{{details.thingy}} <br/>
{{details.name}}<br/>
{{details.title}}<br/>
{{details.description}}<br/>
{{details.year}}<br/>
<img ng-src="{{details.img}}" width="50px"><br>
</div>
</div>
</section>
Basically second ng-repeat is not required

AngularJS - hide/show div if date is within last 6 months

I have an ng-repeat that displays a list of dates, and information about purchases on that dates.
HTML:
<div ng-repeat="data in MyData">
<p>
{{ data.purchasedOn.substring(6, data.purchasedOn.length - 2) | date:'dd/MM/yyyy' }}
</p>
<br>
<p>
{{ data.purchaseDescription }}
</p>
</div>
Which displays:
01/02/2013
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
10/04/2014
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
02/08/2014
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
13/06/2014
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
19/02/2013
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
How can i only show the {{ data.purchaseDescription }} when purchasedOn is within the last 6 months from the current month?
Assuming that you want to show purchasedOn but not the description, you could use a function like this one described here to determine a date 6 months prior.
function addMonths(date, months) {
date.setMonth(date.getMonth() + months);
return date;
}
Then define a function to get a boolean show/hide value:
function shouldHide(purchasedOn){
var purchaseDate = Date.parse(purchasedOn);
var sixMonthsAgo = addMonths(new Date(), -6);
var hide = purchaseDate < sixMonthsAgo ? true : false;
return hide;
}
Now you can just use your function in an ng-hide in your <p> element
<p ng-hide={{shouldHide(data.purchasedOn)}}>
{{ data.purchaseDescription }}
</p>
EDIT
If you do just want to hide the entire element, you could make a filter function like this:
$scope.filterOldDates = function(date)
{
if(shouldHide(date)){
return false;
}
return true;
};
You would use it like this:
<div ng-repeat="data in MyData | filterOldDates">

Filter date range using jQuery UI calendars in AngularJS data-bound table

I have a series of HTML tables which pull data from JSON sources. These are tabbed. They work fine and can be seen in the fiddle here:
Fiddle: http://jsfiddle.net/nA28B/1/.
What I need to do now though is use the date range inputs (which are integrated as jQuery UI datepickers) to filter the data in the tables by the date column. I'm new to AngularJS and the integration with the jQuery UI datepickers particularly has taken this way over my head and I'm struggling to find the solution.
I've tried adding an ng-change attribute to the date inputs but can't even get this to fire a simple alert - possibly I've not set up controllers in the correct places (I've tried creating a new controller around the filter inputs to no avail)?
The code for this is pretty lengthy but quite straight forward, as follows:
HTML:
<div ng-app="myApp">
<h2>Tabs:</h2>
<div class="tabs" ng-init="selected=1">
Purchases
Products on sale
Last 30 days sales
</div>
<h2>Filters:</h2>
<div>
<label for="fromDate">From date:</label> <input type="text" name="fromDate" value="from date..." ng-model="dateFrom" datepicker />
</div>
<div>
<label for="toDate">To date:</label> <input type="text" name="toDate" value="to date..." ng-model="dateTo" datepicker />
</div>
<div class="selected" ng-controller="PurchasesCtrl" ng:show="selected == 1">
<h3>Purchases:</h3>
<table cellspacing="0">
<tr class="first">
<th class="first">Date</th>
<th>Description</th>
</tr>
<tr ng-repeat="purchase in purchases.data" ng-class-odd="'odd'" ng-class-even="'even'" ng-class="{'last':$last}">
<td class="first">{{purchase.date}}</td>
<td>{{purchase.text}}</td>
</tr>
</table>
</div>
<div class="selected" ng-controller="SaleProductsCtrl" ng:show="selected == 2">
<h3>Sale products:</h3>
<table cellspacing="0">
<tr class="first">
<th class="first">Date</th>
<th>Description</th>
</tr>
<tr ng-repeat="saleProduct in saleProducts.data" ng-class-odd="'odd'" ng-class-even="'even'" ng-class="{'last':$last}">
<td class="first">{{saleProduct.date}}</td>
<td>{{saleProduct.text}}</td>
</tr>
</table>
</div>
<div class="selected" ng-controller="Sale30DaysCtrl" ng:show="selected == 3">
<h3>Sale 30 days:</h3>
<table cellspacing="0">
<tr class="first">
<th class="first">Date</th>
<th>Description</th>
</tr>
<tr ng-repeat="sale30Day in sale30Days.data" ng-class-odd="'odd'" ng-class-even="'even'" ng-class="{'last':$last}">
<td class="first">{{sale30Day.date}}</td>
<td>{{sale30Day.text}}</td>
</tr>
</table>
</div>
</div>
JS:
var myApp = angular.module("myApp",[]);
myApp.factory("Purchases", function(){
var Purchases = {};
Purchases.data = [
{
date: "10/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "05/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "20/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
}
];
return Purchases;
});
function PurchasesCtrl($scope, Purchases){
$scope.purchases = Purchases;
}
myApp.factory("SaleProducts", function(){
var SaleProducts = {};
SaleProducts.data = [
{
date: "10/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "28/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
}
];
return SaleProducts;
});
function SaleProductsCtrl($scope, SaleProducts){
$scope.saleProducts = SaleProducts;
}
myApp.factory("Sale30Days", function(){
var Sale30Days = {};
Sale30Days.data = [
{
date: "06/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "08/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "21/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
},
{
date: "20/05/2012",
text: "Lorem ipsum dolor sit amet ipsum dolor"
}
];
return Sale30Days;
});
function Sale30DaysCtrl($scope, Sale30Days){
$scope.sale30Days = Sale30Days;
}
myApp.directive('datepicker', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
$(function () {
element.datepicker({
dateFormat: 'dd/mm/yy',
onSelect: function (date) {
ngModelCtrl.$setViewValue(date);
scope.$apply();
}
});
});
}
}
});
Can anyone set me on the right track with this please? I've tried everything I can think of but I've reached my AngularJS limit!
EDIT:
I've simplified the example just to try to get the basic date filtering working, so I can then get the tabs etc hooked up afterwards. Here's a simplified fiddle:
SIMPLIFIED FIDDLE: http://jsfiddle.net/bY3YL/1/
Well, your problem was quite simple, your input was outside of you controller, so even though you would had used ng-change, it would had never been called.
I fixed your code here. I also added the filtering function; it's only for the From Date input field, but I think you might figure the To Date one by yourself.
$scope.onChangeFromDate = function() {
var fromDate = $.datepicker.parseDate('dd/mm/yy', $scope.dateFrom);
angular.forEach($scope.purchases.data, function(purchase){
var purchaseDate = $.datepicker.parseDate('dd/mm/yy', purchase.date);
if(purchaseDate.getTime() < fromDate.getTime()) {
purchase.filtered = true;
}
})
}

Resources