Angularjs: automatically update date diff? - angularjs

I'm using angular 1.6.1 and I would like to update date diff automatically.
Here is the service that calculate date diff
angular.module("utils", [])
.service('utils', function ($location) {
this.correctDate = function(date) {
var s = date.replace('T', ' ');
return s.replace('.000Z', ' ');
}
this.dateDiff = function(date) {
var oneMinute = 60*1000;
var oneHour = 60*60*1000;
var oneDay = 24*60*60*1000;
var oneWeek = 24*60*60*1000*7;
var oneMonth = 24*60*60*1000*30;
var now = new Date();
var d = new Date(date);
var tNow = now.getTime();
var tDate = d.getTime();
if((tNow - tDate) / oneMonth >= 1){
return Math.floor((tNow - tDate) / oneMonth) + " months";
}
if((tNow - tDate) / oneDay >= 1){
return Math.floor((tNow - tDate) / oneDay) + " days";
}
if((tNow - tDate) / oneHour >= 1){
return Math.floor((tNow - tDate) / oneHour) + " hours";
}
if((tNow - tDate) / oneMinute >= 1){
return Math.floor((tNow - tDate) / oneMinute) + " minutes";
}
return "now";
}
})
Here is the view
<div class="post__date">
<time class="published">
{{dateDiff(correctDate(article.createdAt))}}
</time>
</div>
Now date diff is updated only if I make a click anywhere in app and I even don't understand why. So I have 2 questions :
1) Why does date diff is updated everytime I click anywhere in my angular app ? (Does angular trigger a full digest everytime I click anywhere in app ?)
2) How to update automatically date diff ?

Related

24 hr countdown loop in angular js

Hello am just knew to angular, how can you translate this code into angularjs. My goal is to have it count down 24hrs and restarts again
setInterval(function time(){
var d = new Date();
var hours = 24 - d.getHours();
var min = 60 - d.getMinutes();
if((min + '').length == 1){
min = '0' + min;
}
var sec = 60 - d.getSeconds();
if((sec + '').length == 1){
sec = '0' + sec;
}
jQuery('#the-final-countdown p').html(hours+':'+min+':'+sec)
}, 1000);
This is the html
<div id="the-final-countdown">
<p></p>
</div>
Just wrap the funciton setInterval into $interval in your controller like this:
$interval(function time(){
var d = new Date();
var hours = 24 - d.getHours();
var min = 60 - d.getMinutes();
if((min + '').length == 1){
min = '0' + min;
}
var sec = 60 - d.getSeconds();
if((sec + '').length == 1){
sec = '0' + sec;
}
$scope.data = hours+':'+min+':'+sec;
}, 1000);
and in your view just template with data like this
<p>{{data}}</p>

Calendar start weeks at Monday

What do you have to change so that week start from Monday not Sunday?
I can not post the code here, always get an error message and I do not understand because my English is not so good.
`function calendar() {
// show info on init
showInfo();
// vars
var day_of_week = new Array(
'So','Mo', 'Di',
'Mi', 'Do', 'Fr', 'Sa'),
month_of_year = new Array(
'Januar', 'Februar', 'März',
'April', 'May', 'Juni', 'July',
'August', 'September', 'Oktober',
'November', 'Dezember'),
Calendar = new Date(),
year = Calendar.getYear(),
month = Calendar.getMonth(),
today = Calendar.getDate(),
weekday = Calendar.getDay(),
html = '';
// start in 1 and this month
Calendar.setDate(1);
Calendar.setMonth(month);
// template calendar
html = '<table>';
// head
html += '<thead>';
html += '<tr class="head_cal"><th colspan="7">' + month_of_year[month] +
'</th></tr>';
html += '<tr class="subhead_cal"><th colspan="7">' + Calendar.getFullYear()
+
'</th></tr>';
html += '<tr class="week_cal">';
for (index = 0; index < 7; index++) {
if (weekday == index ) {
html += '<th class="week_event">' + day_of_week[index] + '</th>';
} else {
html += '<th>' + day_of_week[index] + '</th>';
}
}
html += '</tr>';
html += '</thead>';
// body
html += '<tbody class="days_cal">';
html += '</tr>';
// white zone
for (index = 0; index < Calendar.getDay(); index++) {
html += '<td class="white_cal"> </td>';
}
for (index = 0; index < 31; index++) {
if (Calendar.getDate() > index) {
week_day = Calendar.getDay();
if (week_day === 0) {
html += '</tr>';
}
if (week_day !== 7) {
// this day
var day = Calendar.getDate();
var info = (Calendar.getMonth() + 1) + '/' + day + '/' +
Calendar.getFullYear();
if (today === Calendar.getDate()) {
html += '<td><a class="today_cal" href="#" data-id="' +
info + '" onclick="return showInfo(\'' +
info + '\')">' +
day + '</a></td>';
showInfo(info);
} else {
html += '<td><a href="#" data-id="' +
info + '" onclick="return showInfo(\'' +
info + '\')">' +
day + '</a></td>';
}
}
if (week_day == 7) {
html += '</tr>';
}
}
Calendar.setDate(Calendar.getDate() + 1);
} // end for loop
return html;
}`
Codepen
In your day_of_week array change the order of days so that Sunday comes last.
Instead of this:
var day_of_week = new Array('So', 'Mo', 'Di','Mi', 'Do', 'Fr', 'Sa')
Do this:
var day_of_week = new Array('Mo', 'Di','Mi', 'Do', 'Fr', 'Sa', 'So')
Also, you should have a quick read of the help to see how to create links to external sites like Codepen etc (use the question mark '?' in the question editor if you need it). That will help you with things like posting code, links, formatting etc.
Also, when you are linking to an external code site (like Codepen or JSFiddle) you have to include some code in your question or answer as well as the link to the full code.
Update
OK - I see what you mean. Your day of week date does not correctly correspond to the day (as in Jun 3 2017 is a Saturday but showing as a Sunday) after my suggestion.
Because the order of the days changed (ie Monday became the first day of the week), you need to offset your weekday by -1 day.
In your white zone you need to change the first Calendar.getDay() loop from:
for (index = 0; index < Calendar.getDay(); index++)
to:
for (index = 0; index < Calendar.getDay() -1; index++)
That takes care of the first week in the month where there is white-space before the month. Then you need to fix all the other calendar dates. So change the next loop's Calendar.getDay() to offset that too. From this:
week_day = Calendar.getDay();
to this:
week_day = Calendar.getDay() -1;
You should go through the rest of your code and check other months to make sure you are not going to get an invalid date (NaN) because you are decreasing the date by one day.
Update 2
Try this piece of code. This provides a Monday - Sunday calendar and will create the table accordingly. You can easily modify the relevant table cells to include your hook into events and the actual date with styling etc.
If you wanted to you could create the table header with a loop for the days and with a little modification could make the first day of any given week whatever you wanted. I have tested it with each month of this year from Jan through June and the dates work fine.
_('#calendar').innerHTML = calendar();
// short querySelector
function _(s) {
return document.querySelector(s);
}
function calendar() {
var html = '<table><thead><tr>';
html += '<td>Mon</td>';
html += '<td>Tue</td>';
html += '<td>Wed</td>';
html += '<td>Thu</td>';
html += '<td>Fri</td>';
html += '<td>Sat</td>';
html += '<td>Sun</td>';
html += '</tr></thead>';
return html + '<tbody>' + calendarRows(new Date("2017/07/02")) + '</tbody></table>';
}
function calendarRows(dt) {
var html = '';
// Get the number of days in the month
var d = new Date(dt.getFullYear(), dt.getMonth()+1, 0);
var totalDays = d.getDate();
// Get the first day of the month
var f = new Date(dt);
f.setDate(1);
// The first day of the month for the date passed
var firstDayOfMonth = f.getDay();
// The actual date of the month in the calendar
var calendarDate = 1;
// The actual day in any given week. 1 === first day, 7 === last
var dayOfWeek = 1;
while (dayOfWeek < 9 && calendarDate <= totalDays) {
if (dayOfWeek === 8) {
dayOfWeek = 1;
}
// If we are at the start of a new week, create a new row
if (dayOfWeek === 1) {
html += '<tr>';
}
// Process the calendar day
html += '<td>';
// Is this the first day of the month?
if (calendarDate === 1 && firstDayOfMonth === dayOfWeek) {
html += calendarDate;
calendarDate ++;
}
else {
if (calendarDate === 1 || calendarDate > totalDays) {
html += ' ';
}
else {
html += calendarDate;
calendarDate ++;
}
}
html +='</td>';
// Are we at the end of a week?
if (dayOfWeek === 7) {
html += '</tr>';
}
dayOfWeek ++;
}
return html;
}
Hopefully that will work for you. You could always tighten up the code, but I leave that up to you. I've tried to make it easy to modify, but admit I put it together rather quickly to try and help you out.
And if you end up modifying the while loop variables just make sure you don't get yourself into an infinite loop.
Update 3
OK - I have created a Codepen for you that has it working with your formatting. You will still need to make the popup events work and add the relevant code to show events in the calendar. You can also tighten the code up if you need. I left it verbose so you can see what is going on.
_('#calendar').innerHTML = calendar();
// short querySelector
function _(s) {
return document.querySelector(s);
}
// show info
function showInfo(event) {
// Your code in here
}
// toggle event show or hide
function hideEvent(){
_('#calendar_data').classList.toggle('show_data');
}
function calendar() {
//showInfo();
var calDate = new Date("2017/06/02");
var weekdays = new Array( 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
var months = new Array(
'Januar', 'Februar', 'März',
'April', 'May', 'Juni', 'July',
'August', 'September', 'Oktober',
'November', 'Dezember');
// Working vars
var d = calDate.getDate(),
m = calDate.getMonth(),
y = calDate.getFullYear(),
day = calDate.getDay(),
today = calDate.getDate();
var html = '<table><thead>';
// Month
html += '<tr class="head_cal"><th colspan="7">' + months[m] + '</th></tr>';
// Year
html += '<tr class="subhead_cal"><th colspan="7">' + y + '</th></tr>';
// Days of week
html += '<tr class="week_cal">';
for (i = 0; i < 7; i++) {
if (today == i) {
html += '<th class="week_event">' + weekdays[i] + '</th>';
} else {
html += '<th>' + weekdays[i] + '</th>';
}
}
html += '</tr>';
html += '</thead>';
// Individual calendar days
html += '<tbody class="days_cal">' + calendarRows(calDate, d, m, y, day, today) + '</tbody></table>';
return html;
}
function calendarRows(calDate, d, m, y, day, today) {
var html = '';
// Get the number of days in the month
var tempDt = new Date(calDate.getFullYear(), calDate.getMonth()+1, 0);
var totalDays = tempDt.getDate();
// Get the first day of the month
tempDt.setDate(1);
var firstDayOfMonth = tempDt.getDay();
// Reset the day to 1 (first day of any month)
d = 1;
// Counter for tracking day of week. 1 === first day, 7 === last
var dayOfWeek = 1;
while (dayOfWeek < 9 && d <= totalDays) {
if (dayOfWeek === 8) {
dayOfWeek = 1;
}
// If we are at the start of a new week, create a new row
if (dayOfWeek === 1) {
html += '<tr>';
}
// Is this the first day of the month?
if (d === 1 && firstDayOfMonth === dayOfWeek) {
html += makeCell(d, m, y, today);
d ++;
}
else {
if (d === 1 || d > totalDays) {
html += '<td> </td>';
}
else {
html += makeCell(d, m, y, today);
d ++;
}
}
// Are we at the end of a week?
if (dayOfWeek === 7) {
html += '</tr>';
}
dayOfWeek ++;
}
return html;
}
function makeCell(d, m, y, today) {
var info = (m + 1) + "/" + d + "/" + y;
var cell = "<td><a href='#' ";
cell += d === today ? "class='today_cal' " : "";
cell += "data-id='" + info + "' onclick=\"return showInfo('" + info + "')\">";
cell += d + "</a></td>";
return cell;
}
If you modularize your code into smaller chunks (like the makeCell()), you will find it is easier to figure out what is going on and it is easier to get your brain around the more complex code problems.
Hope this helps.
Update 4
Updated the same Codepen - I think this fixed your issue, plus you can set the first day of the week to whatever day you want and the calendar should adjust accordingly. Code change was in the CalendarRows function:
function calendarRows(calDate, d, m, y, day, today) {
var html = '';
// Get the number of days in the month
var tempDt = new Date(calDate.getFullYear(), calDate.getMonth()+1, 0);
var totalDays = tempDt.getDate();
// Get the first day of the month
tempDt.setDate(1);
var firstDayOfMonth = tempDt.getDay();
// Reset the day to 1 (first day of any month)
d = 1;
// Weekdays are 0 === Sunday, 6 === Saturday
var firstDayOfWeek = 1, // <-- this means weeks start on Monday
lastDayOfWeek = 0, // <-- this measn Sunday
dayOfWeek = firstDayOfWeek,
safety = 0,
endLoop = false;
while (endLoop === false) {
safety ++;
if ((dayOfWeek === firstDayOfWeek && d > totalDays) || safety === 50) {
if (safety === 50) console.error("Infinite loop safety break");
break;
}
// If we are at the start of a new week, create a new row
if (dayOfWeek === firstDayOfWeek) {
html += '<tr>';
}
// Is this the first day of the month?
if (d === 1 && firstDayOfMonth === dayOfWeek) {
html += makeCell(d, m, y, today);
d ++;
}
else {
if (d === 1 || d > totalDays) {
html += '<td> </td>';
}
else {
html += makeCell(d, m, y, today);
d ++;
}
}
// Are we at the end of a week?
if (dayOfWeek === lastDayOfWeek) {
html += '</tr>';
}
// Add a day to the current day counter
dayOfWeek ++;
// If we get to Saturday, reset the next day to Sunday
if (dayOfWeek === 7)
dayOfWeek = 0;
}
return html;
}

split time between start time and end time for user given minutes as input

In my app I have a drop-down for booking an appointment with psychiatrist. Here the user gives the input as minutes, to talk to the doctor,so in drop-down it should look like a normal timings like 9-10 am, 10-11pm so on till 5pm, so the customer can see the available timing to book the appointment. I'm struggling to get this time split. I have done only the conversion from mins to hours and after that Im struck with the time split.Hoping for some help here, or any valid guidance for proceeding to get the time split.
Controller:
myApp.controller('ctrl', function ($scope) {
$scope.calc = function () {
var time = $scope.timeSelect;
if (time < 60) {
var a = (time) + 'm';
} else if (time % 60 == 0) {
var a = (time - time % 60) / 60 + 'h';
} else {
var a = ((time - time % 60) / 60 + 'h' + ' ' + time % 60 + 'm');
}
$scope.result =a;
}
$scope.result='';
});
Whenever you are dealing with dates and times I highly recommend using Momentj.js. Here is an extremely contrived example to demonstrate how you might use Moment.js to set your time periods.
angular.module("app", ["angularMoment"])
.controller("ctrl", function($scope, moment) {
var startingTime = moment().hours(9).minutes(0);
var endingTime = moment().hours(17).minutes(0);
$scope.selectedTimeslot = "";
$scope.intervals = [15, 30, 45, 60, 90, 120];
$scope.interval = 60;
$scope.timeslots = [];
$scope.setTimeSlots = function() {
$scope.timeslots = [];
var currentStartTime = angular.copy(startingTime); // use copy to avoid reference issues since we're dealing with objects and not primitives
while (currentStartTime < endingTime) {
$scope.timeslots.push(currentStartTime.format("h:mm") + " - " + currentStartTime.add($scope.interval, "minute").format("h:mm"));
}
}
$scope.setTimeSlots();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/1.0.0/angular-moment.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
Interval in minutes: <select ng-model="interval" ng-change="setTimeSlots()" ng-options="i for i in intervals"></select>
<br/>Timeslots:
<select ng-model="selectedTimeslot" ng-options="slot for slot in timeslots">
<option value="">Please select</option>
</select><br/><br/>
Selected timeslot: {{selectedTimeslot}}
</div>
This might work for you:
function createTimeSlots(startHour, endHour, interval) {
if (!startHour) {
endHour = 8;
}
if (!endHour) {
endHour = 20;
}
var timeSlots = [],
dateTime = new Date(),
timeStr = '';
dateTime.setHours(startHour, 0, 0, 0);
while (new Date(dateTime.getTime() + interval * 60000).getHours() < endHour) {
timeStr = dateTime.getHours() + ':' + dateTime.getMinutes();
timeStr += '-';
dateTime = new Date(dateTime.getTime() + interval * 60000);
timeStr += dateTime.getHours() + ':' + dateTime.getMinutes();
timeSlots.push(timeStr);
}
return timeSlots;
}
console.log(createTimeSlots(9, 18, 45));
"9:0-9:45",
"9:45-10:30",
"10:30-11:15",
"11:15-12:0",
"12:0-12:45",
"12:45-13:30",
"13:30-14:15",
"14:15-15:0",
"15:0-15:45",
"15:45-16:30",
"16:30-17:15"
You might wanna add some 0 padding on the getHours() and getMinutes() so that 1:0 will be printed as 01:00.
From the question I get a rough idea of what you need, so I hope this helps you on your way. First, I would make a separate function to convert a time (in number of minutes from midnight, as an easy example) to a string, like this:
function timeToString(time) {
if (time < 12 * 60)
return (time - time % 60) / 60 + ":" + time % 60 + "am";
else return (time - time % 60 - 12*60) / 60 + ":" + time % 60 + "pm";
}
Then the array to fill the drop-down can be created like this:
var times = [];
for (t = startHour * 60; t < endHour * 60; t += duration) {
times[times.length] = timeToString(t) + ' - ' + timeToString(t + duration);
}

How to select a week with date picker

I'm using angular bootstrap datepicker. i have only one datepicker and need to select week(sunday to saturday) not day of week
for ex,
Select Week period from popup calender .
Select week period 19 July, 2015 to 25 July, 2015
Here comes output as 07/19/2015 To 07/25/2015
in jQuery, i know how to do it, jQuery weekpicker . I am curious how to select week using AngularJS
I would be grateful for any assistance.
Thanks.
Calculate week from date picker, you can try this one
$('#date').datepicker({onSelect: function() {
var mon = $(this).datepicker('getDate');
mon.setDate(mon.getDate() + 1 - (mon.getDay() || 7));
var sun = new Date(mon.getTime());
sun.setDate(sun.getDate() + 6);
alert(mon + ' ' + sun);
}});
See from this link - https://forum.jquery.com/topic/datepicker-select-week
Thanks Afroza Yasmin :-)
Finally, i got it
Please see the source How the select week with pick viewer
angular.module('app', ['ui.bootstrap']).controller("BodyCtrl", function($scope) { $scope.formData = {}; $scope.data = {};$scope.dateOptions = {
formatYear: 'yy',
startingDay: 0,
showWeeks:'false'};$scope.$watch('formData.dueDate',function(dateVal){
var weekYear = getWeekNumber(dateVal);
var year = weekYear[0];
var week = weekYear[1];
if(angular.isDefined(week) && angular.isDefined(year)){
var startDate = getStartDateOfWeek(week, year);
}
var weekPeriod = getStartDateOfWeek(week, year);
if(weekPeriod[0] != 'NaN/NaN/NaN' && weekPeriod[1] != 'NaN/NaN/NaN'){
$scope.formData.dueDate = weekPeriod[0] + " to "+ weekPeriod[1];
}
});
function getStartDateOfWeek(w, y) {
var simple = new Date(y, 0, 1 + (w - 1) * 7);
var dow = simple.getDay();
var ISOweekStart = simple;
if (dow <= 4)
ISOweekStart.setDate(simple.getDate() - simple.getDay());
else
ISOweekStart.setDate(simple.getDate() + 7 - simple.getDay());
var ISOweekEnd = new Date(ISOweekStart);
ISOweekEnd.setDate(ISOweekEnd.getDate() + 6);
ISOweekStart = ISOweekStart.getDate()+'/'+(ISOweekStart.getMonth()+1)+'/'+ISOweekStart.getFullYear();
ISOweekEnd = ISOweekEnd.getDate()+'/'+(ISOweekEnd.getMonth()+1)+'/'+ISOweekEnd.getFullYear();
return [ISOweekStart, ISOweekEnd];
}
function getWeekNumber(d) {
d = new Date(+d);
d.setHours(0,0,0);
d.setDate(d.getDate() + 4 - (d.getDay()||7));
var yearStart = new Date(d.getFullYear(),0,1);
var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
return [d.getFullYear(), weekNo];
}
});
Thanks all

Calculate age from given year in AngularJS

I'm new for AngularJs. I have to calculate age from give year. How I can in PHP?
My script and view files are following,
My .Js:
function mycontroller($scope){
$scope.sales = [
{
name: 'steptoinstall',
year: 1986,
}
]; }
My view.php:
<li ng-repeat="sale in sales" >
{{sale.name}} {{ **AGE** }}
</li>
And,
If I have full date like '10-01-1989', then how can I?
If only year means,
view.PHP
<li ng-repeat="sale in sales" >
{{sale.name}} {{ yearToAge(sale.year) }}
</li>
.Js File:
$scope.yearToAge= function(y) {
return new Date().getFullYear() - y;
}
If Date format given,
view.PHP
<li ng-repeat="sale in sales" >
{{sale.name}} {{ dateToAge(sale.dob) }} // dob should be in dd/mm/yyyy format
</li>
.Js File:
$scope.dateToAge = function(date1){
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1;
var curr_year = d.getFullYear();
var today = curr_date + "-" + curr_month + "-" + curr_year;
var x = date1.split("-");
var y = today.split("-");
var bdays = x[1];
var bmonths = x[0];
var byear = x[2];
var sdays = y[1];
var smonths = y[0];
var syear = y[2];
if(sdays < bdays)
{
sdays = parseInt(sdays) + 30;
smonths = parseInt(smonths) - 1;
var fdays = sdays - bdays;
}
else{
var fdays = sdays - bdays;
}
if(smonths < bmonths)
{
smonths = parseInt(smonths) + 12;
syear = syear - 1;
var fmonths = smonths - bmonths;
}
else
{
var fmonths = smonths - bmonths;
}
var fyear = syear - byear;
return fyear;
}
Add this to your JS
$scope.ageFromYear = function(year) {
return new Date().getFullYear() - year;
}
Then, you can do this in your HTML:
<li ng-repeat="sale in sales" >
{{sale.name}} {{ ageFromYear(sale.year) }}
</li>
In PHP, the idea is built on converting the date into UNIX timestamp, then converting the current date too. then subtracting them, and finally dividing that number on the number of seconds in the year and get its floor to get the numbers of years.
This is a handled as following:
$d = '10-01-1989';
$dT = strtotime($d);
$cur = strtotime(date("m-d-Y"));
$diff = $cur - $dT;
$years = floor($diff/(60*60*24*365));
echo $years;
Checkout this DEMO: http://codepad.org/ErV8RauU

Resources