st-table convert string to date - angularjs

I have json object array binded to a table. Objects have a date column which is in date format but string. I need to change date format.
I tried;
<tbody>
<tr ng-repeat="row in table_data">
<td>{{row.availabledate | date:'MMMM dd, yyyy'}}</td>
</tr>
</tbody>
But, since it is string it is not formatted. I dont want to convert it in a loop for the sake of performance. Is there a way to convert this string to date and then format it on html part?

One way is to make your own filter, then use the date filter.
This crude/raw filter expects a YYYYMMDD string and creates a date object from it that you can then use angular's date filter on.
app.filter('strToDate', function() {
return function(input) {
var year = input.substring(0,4);
var month = input.substring(4,6);
var day = input.substring(6,8);
// Do filter work here
return new Date(year,month,day);
}
});
and then
<td>{{row.availabledate | strToDate | date:'MMMM dd, yyyy'}}</td>
Here's a Plunker link with working example: https://plnkr.co/edit/hn5StpktiMLq2gWHAszu?p=preview
You could also just make your filter return the formatted date.

Another way, doing all the work inside the filter:
app.filter('strToDate', function($filter) {
//1. date value
//2. the format input by user
return function(input, format) {
//Create the date object
var year = input.substring(0,4);
var month = input.substring(4,6);
var day = input.substring(6,8);
var newDate = new Date(year,month,day);
// return the format selected
return $filter('date')(newDate , format)
}
});
You can use the filter like this:
<td>{{row.availabledate | strToDate :'MMMM dd, yyyy'}}</td>

Related

Angular date filter with date-string

I have a datestring in the following format: YYYY-MM-DD HH:mm:SS
I want to use the Angular date filter in the binding to change it to a YYYY-MM-DD HH:mm format.
I am trying {{data.date | date : "YYYY-MM-DD HH:mm"}}, but it doens't seem to work. Any ideas on what to change to get it to recognize my date format?
Try this
In Js file
angular.module('yourmodule').filter('datetime', function($filter)
{
return function(input)
{
if(input == null){ return ""; }
var _date = $filter('date')(new Date(input),
'MMM dd yyyy - HH:mm:ss');
return _date.toUpperCase();
};
});
In HTML
<span>{{ d.time | datetime }}</span>

How to sort results after I filtered them with angular

I have a table and each row has a column with an amount of money. That amount can be in different currency. For now I have two different currencies, for example euros and dollars.
In order to sort that table by amount of money (low-to-high or reverse) I should first convert the amount in dollars for example and then sort the table.
So, I have an order function that works well reference : https://docs.angularjs.org/api/ng/filter/orderBy
I created a filter 'currency' that converts the amount from euros to dollars (i have this as default). The currency converter works good.
But, when I click the button for ordering, I see the results with the converted currency but the table is ordered with the numeric value of the first results.
ng-click="changeCurrencyToDollars(); order('bonus_amount');"
For example the initial data is :
10 US Dollar
9 Euros
and it is converted to :
US Dollar
11.14 US Dollar
Any ideas why the sorting is not working on the converted currency (filtered results) ?
Thanks
Controller:
$scope.convertedCurrency = false; //initial table data with mixed currencies
$scope.changeCurrencyToDollars = function (){
$scope.convertedCurrency = $scope.convertedCurrency ? false: true;
};
$scope.order = function(predicate){
$scope.predicate = predicate;
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
$scope.operators = orderBy($scope.operators, predicate, $scope.reverse);
};
app.filter('currency', [function() {
var defaultCurrency = 'Dollars';
return function(input, currencySymbol){
var out = "";
currencySymbol = currencySymbol || defaultCurrency;
switch (currencySymbol){
case 'Dollars':
out = input;
break;
case 'EUR':
out = 1.11 * input; // convert to dollars
currencySymbol = defaultCurrency;
break;
default:
out = input;
}
return out.toFixed(0) + ' ' + currencySymbol;
}
}]);
View:
Inside the ng-repeat:
<span class="highlight-word" ng-if="!convertedCurrency">{{operators.bonus_amount}} {{operators.bonus_currency}}</span>
<span class="highlight-word" ng-if="convertedCurrency">{{operators.bonus_amount | currency: operators.bonus_currency}}</span>
How I solved it:
I inserted a new property to every object with the converted value. That way every object had a "dollars" property. And for sorting I used the same $scope.order, since it was working but with the new property of the object. Not the best angular solution, but at least the "weight" was in the controller and not in the view.
you have not given your object but ,let's say that is it like this:
$scope.operator = [{
bonus_amount:'100',
bonus_currency:'Dollars'},
{
bonus_amount:'10',
bonus_currency:'Dollars'},
{
bonus_amount:'150',
bonus_currency:'Dollars'}];
Now let's add the currency filter(you put your custom filter to make the conversion) and the orderby filter, and show the data:
In your ng-repeat you add the 'orderBy' filter and then, when you show the data you add the 'currency' filter:
<li ng-repeat="operators in operator | orderBy:'+bonus_amount'">{{operators.bonus_amount | currency }}</li>
Hope helps, good luck.

How to filter date in ngTable?

I am trying to filter date in ngTable based on the given format d MMM yyyy HH:mm:ss. I followed this answer and created a custom filter, but it does not take the given format instead d MMM, yyyy.
How can I have filter on ngTable to filter dates in a given format? Here is my plunker
ngTable
<td data-title="'Start Date'" class="text-center" header-class="text-left" filter="{ 'start_date': 'text' }" sortable="'type'">{{item.start_date| date: 'd MMM yyyy HH:mm:ss'}}</td>
<td data-title="'End Date'" class="text-center" header-class="text-left" filter="{ 'end_date': 'text' }" sortable="'type'">{{item.end_date| date: 'd MMM yyyy HH:mm:ss'}}</td>
Custom filter
filter('customUserDateFilter', function($filter) {
return function(values, dateString) {
var filtered = [];
if (typeof values != 'undefined' && typeof dateString != 'undefined') {
angular.forEach(values, function(value) {
var source = ($filter('date')(value.start_date)).toLowerCase();
var temp = dateString.toLowerCase();
//if ($filter('date')(value.start_date).indexOf(dateString) >= 0) {
//if (temp.indexOf(" ") >=0)
//debugger;
if (source.indexOf(temp) >= 0) {
filtered.push(value);
}
});
}
return filtered;
}
})
You have to be careful when you are changing the format of the date. This is because the filter formats the date which has to be the same format as shown in the table to ensure correct functionality:
var source = ($filter('date')(value.start_date)).toLowerCase();
must be changed to this:
var source = ($filter('date')(value.start_date, 'd MMM yyyy HH:mm:ss')).toLowerCase();
Here is the working plunkr.

angular ui bootstrap datepicker filter with repeater

i am new to angularjs and i am getting problem at the repeat filter with bootstrap date-picker ng-model (dt | date:'yyyy-MM-dd') with date (create_at).
<li ng-repeat="item in items | filter:{create_at:{'dt| date:"yyyy-MM-dd"'}, subject:query}" class="thumbnail">
...
</li>
Thanks!
you need to create a custom filter for that, the date filter is a formatter, it will not filter your results so what you need to do is something like: (this is for date range but you can convert it to a single date):
app.filter("dateRange", function() {
return function(items, from, to) {
var df = parseDate(from);
var dt = parseDate(to);
var result = [];
for (var i=0; i<items.length; i++){
var tf = new Date(items[i].date1 * 1000),
tt = new Date(items[i].date2 * 1000);
if (tf > df && tt < dt) {
result.push(items[i]);
}
}
return result;
};
in view:
<lin g-repeat="order in orders | dateRange:dateFrom:dateTo">
...
</li>
so you see here, we get a date string, convert it to a date and then filter by the date range. you can modify it as you please... you can also turn dates to ISO or whatever

Angular date range filter

I was wondering if anyone could help me. I'm currently trying to get a date filter to work in Angular. I could be going about this completely the wrong way but just thought I would ask.
I currently have an ng-repeat looping through an array of objects. My objects have the following fields: title, sentBy and recevied. Received is in UTC format and my filter basically takes two inputs also in utc format for start and end date. The filter then checked if the received is greater than or equal to to start date or less than or equal to the end date. My issue is that the input to the filter is the input of the whole object. Im not sure how to access the received field of the object within the filter to do the comparrison. I tried input.received but it didnt seem to work. heres a sample of my code.
.filter('dateRange', function(){
return function(input, startDate, endDate) {
if(input.received >= startDate && input <= endDate){
return input;
}
};
})
As I say I could be going about this completely wrong but any help would be greatly appreciated.
edit:
my html code is as simple as below:
<div ng-repeat="message in messages | dateRange: startDate : endDate " >
Try below code. You need to compare the time.
.filter('dateRange', function(){
return function(input, startDate, endDate) {
angular.forEach(input, function(obj){
if(obj.received.getTime() >= startDate.getTime() && obj.received.getTime() <= endDate.getTime()) {
return obj;
}
});
};
});
<div ng-bind="messages | dateRange: startDate : endDate " ></div>
or
<div> {{messages | dateRange: startDate : endDate }}</div>
In your code the filter is working on messages array, that means the first argument (input) is the array, and the return type has to be an array too. Have a look here.
Your code should be something like that:
<div ng-repeat="message in messages | dateRange: startDate : endDate" >
Your filter is:
.filter('dateRange', function() {
return function(input, startDate, endDate) {
var retArray = [];
angular.forEach(input, function(obj){
var receivedDate = obj.received;
if(receivedDate >= startDate && receivedDate <= endDate) {
retArray.push(obj);
}
});
return retArray;
};
});
Here is a plunker.

Resources