moment js gets current time but not the created time - angularjs

I'm trying to retrieve the created_at time
but instead it renders the current time. which is not what i want.
I'm using laravel 5.5 in conjunction with moment.js
<p> <% post.created_at | phpDate : "human" %></p>
main.js
app.filter('phpDate', function() {
// A filter declaration should return an anonymous function.
// The first argument is the input passed to the filter
// Any additional arguments are paramaters passed AFTER the filter name
return function(input, format) {
// Create an instance of Moment. Use both the
// date value and timezone information PHP sent
var date = moment.tz(input.date, input.timezone);
if (format == "human") {
// Special case for formatting. If user asks for "human" format
// return a value like "13 minutes ago" or "2 weeks ago" etc.
return moment().subtract(1, 'days').calendar();
} else {
// Covert the moment to a string using the passed format
// If nothing is passed, uses default JavaScript date format
return moment().format('lll');
}
};
});

with the help of a highly respectable user on this site we were able to fix it, just needed add input within moment parathesis.
app.filter('phpDate', function() {
return function(input, format) {
if (format == "human") {
// add input then it works
return moment(input).subtract(1, 'days').calendar();
} else {
return moment().format('lll');
}
};
});

Related

Restrict post dates into Full Calendar

I´m developing Full Calendar like this, but instead of creating events I just get it from the database.
So now I developing Backend to receive days of the week of an event like this:
As you can see I receive booleans within days of the week
Now I want to restrict if one of this days come false, calendar doesn´t allow me to do that
JS Function:
function isGreaterThanToday(date) {
return date < hoy ? false : true;
}
function updateAssignedEvent(event, delta, revertFunc) {
if (!isGreaterThanToday(event.start)) {
mostrarError("Cant post an event today or before today.");
revertFunc();
return;
}
event.start = $.fullCalendar.moment(moment($.fullCalendar.moment(event.start.format())._i));
event.end = event.end ? $.fullCalendar.moment(moment($.fullCalendar.moment(event.end.format())._i)) : event.start;
event.color = getTareaCalendarioColor(event.tipoResponsable,
event.estatusTarea,
event.start,
event.end.diff(event.start, 'hours') <= 24 ? event.start : event.end);
updateEvent(event).then(function(data) {
if (!data.success) {
revertFunc();
return;
}
event.end = event.end !== event.start ? event.end.add(1, 'day') : event.end;
$calendar.fullCalendar('updateEvent', event);
}, function(error) {
revertFunc();
});
}
As you can see I have a function calledfunction isGreaterThanToday(date), I use it to restrict post an event today or before today. I want to do something like this, but I don´t have an idea of how can I call these booleans and compare for example Sunday of the calendar with Sunday of boolean receive. Can anyone help me there? Regards
For example into my function I add:
if (event.accion.agendarDomingo != true) {
mostrarError("Sunday is not allowed");
revertFunc();
return;
}
But how can I compare with my event.start and event.end DAY?
To get day of week using moment.js use 'e' as a format. result will be 0..6 Monday to Sunday.
event.start.format('e');
To check if the time is passed use isAfter function:
If nothing is passed to moment#isAfter, it will default to the current time.
moment(event.start).isAfter();
Now these two validation constraints combined would look like this:
function isDateValid(date) {
return date.format('e') !== "6" && moment(date).isAfter();
}

Is it possible to have angular use a different timezone than the browser?

Users of our application have to choose the timezone they want to work in. This is because they might exclusively work for customers of some other timezone.
The dates of the aplication are then stored in UTC.
Javascript takes the timezone offset of the browser when displaying utc dates as local dates, which is not what I want.
For displaying dates I have a filter in place. It takes the offset that was applied because of the browser and removes it. Then the offset as defined by the user is applied. This works for displaying values.
A sample might be: The user sits in UTC+03:00 but his setting in the application is for UTC-4:00.
In the database there is a UTC value of 6am. The desired displayvalue is 6-4 = 2am. This is achieved by removing the offset applied because of his browser (-3) and then applying the offset of his settings.
function standardDateFilterInterceptor(date, format, timezone) {
if (timezone === "agent") {
if (date !== null && date !== undefined) {
var momentDate = moment(date.toString(), ["YYYY-MM-DD HH:mm:ss"]);
if (momentDate.isValid()) {
date = momentDate.toDate();
let offset = date.getTimezoneOffset();
if (offset !== null && offset !== undefined) {
offset = offset * 60000 * (-1);
const dateWithOffset = new Date(date.getTime() + offset);
date = dateWithOffset;
}
}
}
if (agentTimeZoneOffset !== null && !angular.isUndefined(agentTimeZoneOffset)) {
timezone = agentTimeZoneOffset;
}
}
return originalFilter.apply(this, [date, format, timezone]);
}
For displaying values this is working but I dont find a way to update values. The adjusted value (2am) in the sample would end up in the scope and overwrite the original value of 6am. I can see that when I change the value to 3 and then back to 2. Is there a way to handle this? Like controlling what gets set in the scope when a dom element changes.
I ended up with a directive that handles the case when the value in the view is updated
Directive
app.directive('tzAdapterTime', function () {
return {
require: 'ngModel',
link: function ($scope, $element, $attrs, modelCtrl) {
modelCtrl.$formatters.push(function (inputValue) {
var offset = moment(modelCtrl.$modelValue).parseZone().utcOffset();
return moment(modelCtrl.$modelValue).subtract(offset, 'minute').toDate();
});
modelCtrl.$parsers.push(function (inputValue) {
var offset = moment(inputValue).parseZone().utcOffset();
return moment(inputValue).add(offset, 'minute').toDate();
});
}
};
});
View
<input type="datetime-local" ng-model="article.publish" tz-adapter-time >

Angular date filter converter, but date is always converted to UTC

My filter:
.filter('emedicineDateTimeFormat', function ($filter) {
return function (input) {
if (input == null) { return ""; }
var date = $filter('date')(new Date(input), 'dd.MM.yyyy hh:mm:ss');
return date.toUpperCase();
};
});
if Input is: 2017-01-04T14:30:00
then output is 04.01.2017 03:15:00
and not 04.01.2017 14:15:00
Why?
If you want get 24-hours time use upper-cased H. An example is here.
'dd.MM.yyyy HH:mm:ss'
Are you sure that you didn't misspell in output and expected result?
Do you live in UTC+01:00 timezone?
By default AngularJS uses browser timezone. If you want use UTC you should pass the 3rd argument to date filter 'UTC'. Look here.

ng-Repeat not working with Custom ValueFilter (Value | customFilter) in 1.3.x but in 1.2.1

i am Trying to update a Solution from 1.2.1 to 1.3.15 but i got stuck it seems that there have been a change how the digest Cycle run through loops.
I have a Factory which holds data For all My controller it has a list of Objects and a Current Object Property. It is used for Currency Conversion.
Then i got a filter which can be put on Number values. It references the Factory and uses the Current Property to get the Conversion Rate and modifies the output.
Value = 1000; Current= kiloCurrency= 1000 => {Value | bvcurrency} Outputs: 1;
There is a Function to change the current currency and the Filter should update the output.This worked fine in 1.2.1 but not in 1.3.x
I got some Examples:
Not working 1.3.15: http://jsfiddle.net/dabii/mqkj4td9/7/
Working: 1.2.1: http://jsfiddle.net/dabii/mqkj4td9/8/
app.factory("numberSvc", [function () {
return {
Formats: [{
Display: "LC",
Multiply: 1
}, {
Display: "kLC",
Multiply: 1000
}, {
Display: "MLC",
Multiply: 1000000
}],
Current: {
Display: "kLC",
Multiply: 1000
},
AddCurrency:function(curr){
this.Formats.push(curr);
},
SetCurrent: function(format){
this.Current = format;
}
};
}]);
app.filter('bvcurrency', ['$filter', 'numberSvc', function ($filter, numberSvc) {
return function (input) {
var multi = numberSvc.Current.Multiply,
ret = ( !! input || input === 0) && angular.isNumber(parseFloat(input)) ? $filter('number')(input / multi, 0) : "";
return ret;
};
}]);
By pressing the buttons you can see that the Factory Value changes but not the one using the filter neither aut nor inside the repeat. If i force a Digest by changing a Value then the Value outside repeat will change but not the inside.
It seems that there is some kind of "intelligent" digest running and seeing that the values inside the repeat did not changed and so will not run the digest for them. But it does not see that the output will change because it does not take the filter in account.
Can somebody point me in the right direction to get it working in 1.3.1? Or showing me the mistake?
Kind Regards
Rafael
By default filters are considered stateless, that is the output value only depends on the input value. This gives Angular the chance to optimize: As long as the input value doesn't change, the output value doesn't have to be recalculated. This behavior has changed with 1.3.
Your filter is stateful, so you have to add the $stateful flag in order to let Angular know.
app.filter('bvcurrency', ['$filter', 'numberSvc', function ($filter, numberSvc) {
function filter(input) {
var multi = numberSvc.Current.Multiply,
ret = ( !! input || input === 0) && angular.isNumber(parseFloat(input)) ? $filter('number')(input / multi, 0) : "";
return ret;
};
filter.$stateful = true;
return filter;
}]);

Set an AngularJS date filter format to be used by all references to the date filter?

Rather that having to define a custom format for each call to the date filter, is there a way to globally define a default format (other than 'medium')?
I would like to have the format set in one file rather than all over the place in my code (the date format may end up being changed in the future and a modification in one file would be much nicer than having to make changes in many files).
This is what I am doing now (defining date format each time):
{{systemTime | date:'dd MMMM # HH:mm:ss'}}
{{modifiedTime | date:'dd MMMM # HH:mm:ss'}}
{{getShippedTime() | date:'dd MMMM # HH:mm:ss'}}
etc.
I was thinking of creating a custom filter (let's call it myDate), which would act as a wrapper and then pass off the date string to the Angular date filter with my custom format, so then my code could just look like this:
{{systemTime | myDate}}
{{modifiedTime | myDate}}
{{getShippedTime() | myDate}}
etc.
However, I can't figure out how to make the myDate filter point to the Angular date filter.
Thanks for your help.
Based on some more research and then considering the comment by moderndegree, I have found that the following myDate filter will work:
.filter('myDate', function($filter) {
var angularDateFilter = $filter('date');
return function(theDate) {
return angularDateFilter(theDate, 'dd MMMM # HH:mm:ss');
}
});
Try this
angular.module('yourmodule').filter('myDate', function($filter)
{
return function(input)
{
if(input == null){ return ""; }
var _date = $filter('date')(new Date(input), 'dd MMMM # HH:mm:ss');
return _date.toUpperCase();
};
});
Html
{{systemTime | myDate}}
Date filtering and formatting in Angular js.
Use a decorator,
It's not what you explicitly asked for, use a decorator. it's built in angular and designed to patch services, directives, filters etc ...
in your case, if the date filter is not provided, you should use your custom date format.
app.config(function ($provide) {
$provide.decorator('dateFilter', function ($delegate) {
return function () {
// Check if the date format argument is not provided
if (!arguments[1]) {
arguments[1] = 'dd MMMM # HH:mm:ss';
}
var value = $delegate.apply(null, arguments);
return value;
};
})
});
The format defaults to mediumDate if none is provided. There is nothing built in to have it default to something else.
https://github.com/angular/angular.js/blob/master/src/ng/filter/filters.js#L382
In case you are working with .aspx pages and have the date format stored in a configuration file...
From the .aspx that injects your Angular page, set a global variable with the web.config date format
var _settingsDateFormat = '<%=appSettings.DateFormat%>';
Set a global filter to be used through your app
yourModule.filter('myDateFormat', function ($filter) {
return function (input) {
if (input == null) { return ""; }
var formattedDate = $filter('date')(new Date(input), _settingsDateFormat);
return formattedDate;
};
});
Just add the custom filter to your dates
Effective {{row.StartDate|myDateFormat}} - {{row.StopDate|myDateFormat}}

Resources