AngularJs Select menu using ng-repeat, first item should display differently - angularjs

Below code is fetching today's date and 7 more days e.g. 2016-02-01, 2016-02-02, 2016-02-03, 2016-02-04 etc.
but for today's date I do not want to display a date to user but word "Today" however, I want values in date format as I want to fill it into database while submitting form.
<select ng-model="item1" style=" width:100%; text-align:center;" ng-change="update()">
<option style="text-indent:30%" ng-repeat="item1 in IdeaMonth" value="{{item1.one | date:'yyyy-MM-dd' }}" >
{{item1.one | date:'dd-MM-yyyy' }}
</option>
</select>

You need your custom filter, where you can use moment or the same angular js date filter to get the necessary value:
function compareDateParts(a, b)
{
var aMSec, bMSec;
a = new Date(a);
b = new Date(b);
a.setHours(0,0,0,0);
b.setHours(0,0,0,0);
aMSec = a.getTime();
bMSec = b.getTime();
return aMSec == bMSec ? 0 : (aMSec > bMSec ? 1 : -1);
}
angular.module('app').filter('customDate', ['$filter', function($filter) {
return function(date, format) {
if(compareDateParts(date, new Date()) == 0) return "TODAY"
return $filter('date')(date, format);
};
}]);
Using {{date | customDate: 'dd-MM-yyyy'}}

Related

Date filter causes ng-repeat+other filters to be extremely slow in IE11

I have an ng-repeat plus some custom filters, and a date range filter, all works wonderful in Chrome, Mozilla, android. But in IE with the Date Range filter everything grinds to a halt. The filters take 10 seconds to register (I have filters tied to checkboxes and free text), with the checkbox animations also lagging until the data loads. If I remove the date range filter then everything is fine in IE.
The list is called from an azure API, the list is currently 8500 records long, but the length can't be avoided, and all runs smooths with the size apart from IE and the date range function.
I've tried something to speed it up in IE such as adding :: single binding to all {{ }} values.
I am also using pagination and have LimitTo set to 20
But these fixes seem to be if ng-repeat and filters are slow in IE8+ in general, but mine is fine with the other filters its only with the date range.
The repeat:
<div class="inner" ng-repeat="app in displayedData = ( applications
| orderBy: sortType:sortReverse
| filter: FAl
| filterStatus: FStatus
| filterStage: FStage
| dateRange: startDate:endDate
) | start: (currentPage - 1) * perPage | limitTo: perPage">
<div class="record" ng-class-odd="'odd odd-Record'" ng-class-even="'even even-Record'" data-toggle="collapse" data-target="#{{ app.Id }}">
<div class="field field-Name">{{ app.Lastname }}</div>
<div class="field field-AccountNumber">{{ app.AccountNumber }}</div>
<div class="field field-AppDate">{{ app.DateApplied | date : "dd/MM/yyyy"}}</div>
</div>
The date range filter:
//Filter: Dates
App.filter('dateRange', function () {
return function (applications, startDate, endDate) {
var filtered = [];
var start_date = startDate.toString();
var end_date = endDate.toString();
angular.forEach(applications, function (value) {
if (Date.parse(value.DateApplied) > Date.parse(start_date) && Date.parse(value.DateApplied) < Date.parse(end_date)) {
filtered.push(value);
}
});
return filtered;
};
});
The values for the date range are sent from pikaday date picker:
<h4>Date Range</h4>
<div>
<label style="font-weight: 500">Start Date</label>
<input style="float: right; width: 128px;" type="text" id="datepickerStartDate" ng-model="startDate">
</div>
<div>
<label style="float: left; font-weight: 500">End Date</label>
<input style="float: right; width: 128px;" type="text" id="datepickerEndDate" ng-model="endDate">
</div>
The other filters are all in the below format just passed different specific field values.
//Filter: Status
App.filter('filterStatus', function () {
return function (applications, Status) {
var items = {
status: Status,
out: []
};
angular.forEach(applications, function (value, key) {
if (this.status[value.Status] === true) {
this.out.push(value);
}
}, items);
return items.out;
};
});
First, this is what you should have in html. Move all filtering to controller function - then you can test it, test perfomance, etc.
<div class="inner" ng-repeat="app in displayedData">
...
Second, prepare your data. If your backend return dates as strings (Cant guess what this is about though), parse them as you get them. Quite evident that parsing dates from string is much slower than comparing two date.
Issue was cased by having an && criteria in the date range function if statement
Trouble shooting through it, I found having having only one thing to check for in the IF stopped all slowness.
I instead created a filter for start and end date separately
App.filter('startDate', function () {
return function (applications, startDate) {
var items = {
startdate: startDate,
out: []
};
angular.forEach(applications, function (value, key) {
if (Date.parse(value.DateApplied) > Date.parse(this.startdate)) {
this.out.push(value);
}
}, items);
return items.out;
};
});
App.filter('endDate', function () {
return function (applications, endDate) {
var items = {
enddate: endDate,
out: []
};
angular.forEach(applications, function (value, key) {
if (Date.parse(value.DateApplied) < Date.parse(this.enddate)) {
this.out.push(value);
}
}, items);
return items.out;
};
});
This has fixed the immense slowness experienced in IE. I am sadly unsure why this was causing an issue.

problems with a filter date in angularJS

i have a problems with my filter date , I would like to filter between 2 date but with a condition if the date from is not valid then I start at 2017-01-01 (for that I think it is good) and if the date 'to' is not valid I start Has the current date
Here is my plunker:
http://plnkr.co/edit/8sK29zG7YoPOdntbFfcK?p=preview
Thank you for your help
Your filter could be something like this :
app.filter("myfilter", function($filter) {
return function(items, from, to) {
const testFrom = Date.parse(from);
const testTo = Date.parse(to);
if (!testFrom){
console.log('Not valid');
from = moment('2017-01-01');
}
//here it does nt work
if (!testTo){
to = moment();
}
const valids = items.reduce((acc,val) => {
const date = moment(val.dateenvoi);
if(date.isSameOrAfter(from) && date.isSameOrBefore(to))
acc.push(val)
return acc;
},[]);
return valids;
};
});
Check this
No need for custom filter for this functionality, you can use angular predefined filter for this like
<input type="text" name="S_Date" ng-model="filter.dateenvoi"/>
and
<tr ng-repeat="x in myData | filter: filter">
working Plunker

using | filter in ng-options in angular js

I'm pretty new to angular.
I want to have a where clause in my ng-options like this :
select * from currencies where currency.code in ( 'usd' , 'cad')
<select ng-model="selectedCurrency" ng-options="currency.Name for currency in Currencies | filter:currency.code = 'usd' track by currency.ID">
<option value="">-- select a currency--</option>
</select>
I could do it for only one code but I want to select it from an array of two or more !
Try with:
ng-options="currency.Name for currency in Currencies track by currency.ID | filter: {code: 'usd'}"
To search multiple values you can use a function:
$scope.filterCurrencyCodes = function(currency) {
return (['usd', 'cad'].indexOf(currency.code) !== -1);
};
ng-options="currency.Name for currency in Currencies track by currency.ID | filter: filterCurrencyCodes"
Try with:
ng-options="currency.Name for currency in Currencies track by currency.ID | filter: filterCurrency"
And then create a method for evaluate the currency code:
$scope.filterCurrency= function(currency){
if(currency.code == 'USD' || currency.code == 'CAD'){
return true;
}
return false;
};

How to split the date based on check-In and check-out date in angularjs?

I have a hotel system need to split the date( duration of stay), The start date( Check-In) and EndDate(check-out) are selected by user in datepicker. like this:
<div class="datebox">
<input type="text" show-button-bar='false' class="form-control biginput" datepicker-popup ng-model="lodging.checkIn" is-open="checkin" datepicker-options="dateOptions" ng-required="true" close-text="Close"/>
<span class="dateicon" style='right:5px;' ng-click="openCheckIn($event)"></span>
</div>
<div class="datebox">
<input type="text" show-button-bar='false'
class="form-control biginput" datepicker-popup
ng-model="Lodging.checkOut" is-open="checkout" min-date='lodging.checkIn'
datepicker-options="dateOptions" ng-required="true"
close-text="Close" />
<span class="dateicon" style='right:5px;' ng-click="openCheckOut($event)"></span>
</div>
Users will choose check-in and check-out days from above two datepicker. I need to split out the information for each stays, such that if I choose check-in : 11/01/2015 check-out: 11/05/2015, I need to create a table to show each stay's expense from date 11/01/2015 to 11/05/2015. It will be like following table:
Date Amount
11/01/2015 109
11/02/2015 120
11/03/2015 101
11/04/2015 99
How to split out the duration date (like the first columnn of the table)and put them in the ng-repeat for my table?
First, prepare your table with ng-repeat
<table ng-init="loadStays()" ng-if="stays">
<thead>
<tr>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="stay in stays | between:lodging.checkIn:lodging.checkOut">
<td>{{ stay.date | date : 'mm-dd-yyyy' }}</td>
<td>{{ stay.amount }}</td>
</tr>
</tbody>
</table>
Then, create a filter for display only items between date from and date to (if I understand your question correctly)
// For parse a date in format: 'mm-dd-yyyy'
// If you have to parse the date from your item (maybe datetime ?)
// Use the built-in date filter
// like date = $filter('date')(item.date, 'mm-dd-yyyy')
parseDate = function(input) {
var parts = input.split('-');
return new Date(parts[1]-1, parts[2], parts[0]);
};
// Create the filter assuming app is your module.
app.filter('between', function() {
return function(items, from, to) {
filtered = [];
var dateFrom = parseDate(from);
var dateTo = parseDate(to);
if (from == '' && to == '')
return items;
filtered = items.filter(function(item) {
if (from !== '' && to == '') {
return item.date >= dateFrom;
} else if (from == '' && to !== '') {
return item.date <= dateFrom;
} else if (from !== '' && to !== '') {
return item.date >= dateFrom && item.date <= dateTo
}
});
return filtered;
};
});
With this code, stays are dynamically filtered and user see only items with a date attribute between your lodging.checkIn and logding.checkOut dates taken from datepicker ng-models.
And in case of you don't know how retrieve stays from your server, use something like :
// Retrieve stays from yourdomain/stays
$scope.loadStays = function() {
$http.get('stays').then(function(response) {
$scope.stays = response.data;
}, function(response) {
console.log(response);
});
};

Ignore Time Zone Angularjs

Is there a better way to ignore an timezone in Angularjs:
"2014-01-18 14:30:00" Instead Of "2014-01-18 15:30:00"
function Scoper($scope) {
$scope.datum = "2014-01-18T14:30:00Z";
}
<div ng:app ng:controller="Scoper">
DateTime <br />
Angular: {{datum | date:'yyyy-MM-dd HH:mm:ss'}} <br />
</div>
http://jsfiddle.net/samibel/2rMXJ/
I was experimenting the same problem for a while. There is a timezone possible parameter to the date filter which I think should be the preferred solution, instead of making your own filter and append it. So, this is what worked for me:
{{ someAcceptedDateFormat | date : 'shortTime' : 'UTC' }}
I found this answer: Why does angular date filter adding 2 to hour?
Here is an example:
Just pipe another filter:
app.filter('utc', function(){
return function(val){
var date = new Date(val);
return new Date(date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds());
};
});
In your template:
<span>{{ date | utc | date:'yyyy-MM-dd HH:mm:ss' }}</span>
I Have the solution:
app.filter('timezone', function(){
return function (val, offset) {
if (val != null && val.length > 16) {
return val.substring(0, 16)
}
return val;
};
});
template:
<span>{{ date | timezone | date:'yyyy-MM-dd HH:mm:ss' }}</span>
http://jsfiddle.net/samibel/n4CuQ/

Resources