The popup calendar show local date but the selected date is UTC - javascript

I want to keep the selected date in UTC format.
But the pop-up calendar is not sync with the selected datetime.
Lets's say when I click 08/13 and the selected date is 08/12
Because in my timezone is 08/13 but the it's still on 08/12 with UTC timezone
HTML
<div class="col-sm-10" ng-click="open($event)">
<input type="text" class="form-control ng-pristine ng-untouched ng-valid ng-isolate-scope ng-valid-date ng-valid-required" datepicker-popup="yyyy/MM/dd" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" required="required" aria-required="false" aria-invalid="false" ng-model="form.start_date" />
</div>
JS controller
app.controller('FlightSkuStartDatepickerCtrl', ['$scope',
function($scope) {
// Disable weekend selection
$scope.disabled = function(date, mode) {
return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6));
};
$scope.toggleMin = function() {
$scope.minDate = $scope.minDate ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1,
class: 'datepicker'
};
$scope.formats = ['YYYY/MM/DD'];
$scope.format = $scope.formats[0];
}
]);

If you are storing it as UTC why do you have problem with keeping it as UTC?. If you want to change your time from UTC to another timezone you can use moment for angular. But you must give moment a timezone for converting. For example:
function utctoTimeZoneFormat(date, current_tz) {
var offset = moment(date).tz(current_tz).utcOffset();
var returnObj = {
"day": "",
"time": ""
}
returnObj.day = moment.utc(date).tz(current_tz).utcOffset(offset).format('dddd');
returnObj.time = moment.utc(date).tz(current_tz).utcOffset(offset).format('HH:mm:ss')
return returnObj;
}
You can pass date parameter as your selected date from the UI and current_tz as your timezone. But you must pass it like " America/Los_Angeles" as title of timezone.
function timeZoneToUTCFormat(date, current_tz) {
var offset = moment(date).tz(current_tz).utcOffset();
offset = offset * -1;
var returnObj = {
"day": "",
"time": ""
}
returnObj.day = moment.utc(date).tz(current_tz).utcOffset(offset).format('dddd');
returnObj.time = moment.utc(date).tz(current_tz).utcOffset(offset).format('HH:mm:ss')
return returnObj;
}
The second function enables you to store your selected date as UTC. You should pass the parameters accordingly. For example; if you are in "America/Los_Angeles" you should pass your timezone as the given string and you'll convert it to UTC. So you can sync your UI and backend by using the two functions written above.

In the newer versions of ui-datepicker there is an easier way to solve this
ng-modal-options='{"timezone":"utc"}'
this remove the timezone component from date
In older versions
The solution is to remove the timezone component of the date part (better have directive for reusability...
myapp.directive("dateToIso", function () {
var linkFunction = function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$parsers.push(function (datepickerValue) {
return moment(datepickerValue).format("YYYY-MM-DD");
});
};
return {
restrict: "A",
require: "ngModel",
link: linkFunction
};
});
You can use it like below
<input ng-model='abc' date-to-iso ui-datepicker>

Related

How to input only YYYY(Format year) in textbox using angularjs

<input type="date" id="exampleInput" name="input" ng-model="startYear"
placeholder="yyyy" min="1111" max="9999" />
I tried above way but didn't work
<div date-input ng-model="date"></div>
Your directive template would look like this:
<input
id="exampleInput"
type="number"
name="input"
ng-model="year"
ng-change="setDate()"
placeholder="yyyy"
min="1111"
max="9999"
/>
While your actual directive would look like:
.directive('dateInput', ['$filter', function($filter) {
return {
restrict: 'A',
scope: {
ngModel: '='
},
templateUrl: './dateInput.html',
link: function(scope) {
scope.$watch('ngModel', function(nv, ov) {
if (!angular.isDefined(nv) && !angular.isDefined(ov)) {
scope.ngModel = new Date();
scope.year = _getYear(scope.ngModel);
} else {
scope.ngModel = new Date(nv);
}
})
angular.extend(scope, {
setDate: setDate
})
function _getYear(date) {
return parseInt($filter('date')(date, 'yyyy'));
}
function setDate() {
var year = parseInt(scope.year),
date = new Date(year, 1, 1);
scope.ngModel = date;
}
}
}
}]);
So basic idea is to extract year from date input using angulars built in date filter or create new date object if value has not been passed and do the same thing.
Edit it and than compose a new date object and bind to ngModel.
You could easily do the same for month and day and replace 1 values that are passed to date object constructor.
Note that you also have to pass date formatted in a way Date object can read it.

show only the current month in datepicker and remaining all months should be disabled using angularjs

I have datepicker showing only months.
It should show only current month and remaining months should be disabled.
I have tried with min-date and max-date, but it is not working.
HTML:
<input type="text" class="form-control"
readonly="readonly" ng-model="xxxx"
min-mode="'month'" min-date="startmnth" max-date="endmnth"
datepicker-popup="yyyy-MM" is_open="status.date_opened"
ng-required="true" placeholder="YYYY-MM"
datepicker-options="datepickerOptions"
datepicker-mode="'month'" ng-click="openfromDate($event)"
show-button-bar="false">
JS:
$scope.startmnth = new Date().getMonth()
$scope.endmnth = new Date().getMonth()
$scope.datepickerOptions = {
startingDay: 1,
};
$scope.openfromDate = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.date_opened = true;
};
You can add "dateDisabled: this.disabledDates" as part of your options, and then create a function like this:
this.disabledDates = function(data) {
var date = moment(data.date);
//check date and return true/false to disable/enable
return false;//to disable
}

Format date on bootstrap datetimepicker

I am using the Bootstrap 3 Date/Time Picker (https://github.com/Eonasdan/bootstrap-datetimepicker) and I have problems
formatting the date
<input type="text" id="fmEndDate" class="form-control input-sm"
datetimepicker
format="DD-MM-YYYY hh:mm"
ng-model="workRequest.EndDate"
placeholder="..."
name="fmEndDate"
required
ng-disabled="isDisabled">
But the value is being display as MM/DD/YYYY hh:mm AM
i want 31-12-2017 23:59 for new year eve timestamp
This is my directive
"use strict";
angular.module("datetimepicker", [])
.provider("datetimepicker", function () {
var defaultOptions = { };
this.setOptions = function (options) {
defaultOptions = options;
};
this.$get = function () {
return {
getOptions: function () {
return defaultOptions;
}
};
};
})
.directive("datetimepicker", [
"$timeout",
"datetimepicker",
function ($timeout,datetimepicker) {
var defaultOptions = datetimepicker.getOptions();
return {
require : "?ngModel",
restrict: "AE",
scope : {
datetimepickerOptions: "#"
},
link : function ($scope, $element, $attrs, ngModelCtrl) {
var passedInOptions = $scope.$eval($attrs.datetimepickerOptions);
var options = jQuery.extend({}, defaultOptions, passedInOptions);
$element
.on("dp.change", function (e) {
if (ngModelCtrl) {
$timeout(function () {
ngModelCtrl.$setViewValue(e.target.value);
});
}
})
.datetimepicker(options);
function setPickerValue() {
var date = options.defaultDate || null;
if (ngModelCtrl && ngModelCtrl.$viewValue) {
date = ngModelCtrl.$viewValue;
}
$element
.data("DateTimePicker")
.date(date);
}
if (ngModelCtrl) {
ngModelCtrl.$render = function () {
setPickerValue();
};
}
setPickerValue();
}
};
}
]);
Any ideas?
As shown in the bootstrap3 docs you can define custom formats in JavaScript:
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'your desired Formatting style'
});
});
</script>
</div>
</div>
Even more simple:
$("#fmEndDate").datetimepicker({format: 'dd-mm-yyyy hh:ii'});
Sidenote: Be careful with Date/Time formatting:
As for AngularJS HH format will result in hours as 00-23. While in Bootstrap3 which you are also using HH will result in hours as 01-12.
I highly suggest you to use a library like MomentJS which is doing the troublesome work for you.
Regards,
Megajin

Scope variable not updating in $scope.$watch

I have a watcher on a $scope variable which sets off a function to change the $scope variable to the beginning of the week of the date chosen. The function is returning the correct date but when I try to set the $scope variable to that date the view does not update. But checking it inside the inspector the $scope variable is changed but the view never updates. Here is the $watch function:
angular.module('hansenApp', ['ngAnimate', 'ui.bootstrap']);
angular.module('hansenApp').controller('DatepickerCtrl', function ($scope) {
$scope.startDate = new Date();
$scope.endDate = new Date();
$scope.status = {
startOpened: false,
endOpened: false,
};
$scope.openStart = function ($event) {
$scope.status.startOpened = true;
};
$scope.openEnd = function ($event) {
$scope.status.endOpened = true;
};
$scope.$watch('startDate', function (dateVal) {
var oldDate = new Date(dateVal);
var tempDate = getStartDateOfWeek(dateVal);
if (oldDate.getTime() != tempDate.getTime()) {
$scope.startDate = tempDate;
}
});
$scope.$watch('endDate', function (dateVal) {
var oldDate = new Date(dateVal);
var tempDate = getEndDateOfWeek(dateVal);
if ($scope.endDate.getTime() != tempDate.getTime()) {
$scope.endDate = tempDate;
}
});
function getStartDateOfWeek(date) {
var ISOweekStart = date;
ISOweekStart.setDate(date.getDate() - date.getDay());
return ISOweekStart;
}
function getEndDateOfWeek(date) {
var ISOweekEnd = date;
ISOweekEnd.setDate(date.getDate() + (6 - date.getDay()));
return ISOweekEnd;
}
});
Edit 1: Here's the view:
<p class="input-group">
<input type="text" id="endDate" class="form-control" uib-datepicker-popup="MM/dd/yyyy" ng-model="endDate" is-open="status.endOpened" close-text="Close" placeholder="End Date:" runat="server" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openEnd($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
You do not change the reference of the date, but just the value of it.
A Date is an object in javascript, hence if you do not change the reference (replace it by a new Date() object) the angular change detector will not trigger again.
So you will have to replace the startDate by a completely new instance of a javascript date with the given properties.
So replace
var ISOweekEnd = date;
by
var ISOweekEnd = new Date();

Add one hour to string on client side

I have two timepicker in my view
#Html.Kendo().TimePickerFor(m=>m.AttendeeStartTime).Format("HH:mm")
#Html.Kendo().TimePickerFor(m=>m.AttendeeEndTime).Format("HH:mm")
This is how it looks
and here is rendered HTML for From Timepicker,
<input data-val="true" data-val-required="The AttendeeStartTime field is required."
id="AttendeeStartTime" name="AttendeeStartTime" type="text" value="09:00" data-role="timepicker"
class="k-input valid" role="textbox" aria-haspopup="true" aria-expanded="false" aria-
owns="AttendeeStartTime_timeview" aria-disabled="false" aria-readonly="false" style="width: 100%;">
Whenever there is change in From timepicker, how can I add one hour to its value and set to to To timepicker?
This is what I have done,
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//var date = new Date();
endTime.value($(this).val());
alert(endTime.value());
This only sets the To value to the same as From when there is change, but I want to add an hour or some timespan to it.
How should i do that?
Use this:
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//try getting the date from the date picker
var date = $("##Html.IdFor(m=>m.AttendeeStartTime)").data("kendoTimePicker").value();
if (date) {
//convert the string to a date
date = new Date(date); //you can probably skip this step since the Kendo DatePicker returns a Date object
//increase the "hours"
date.setHours(date.getHours() + 1);
//set it back in the "to" date picker
$("##Html.IdFor(m=>m.AttendeeEndTime)").data("kendoTimePicker").value(date);
//alert(endTime.value());
}
}
You can write a custom function like this,
function addMinutes(time, minsToAdd) {
function z(n){ return (n<10? '0':'') + n;};
var bits = time.split(':');
var mins = bits[0]*60 + +bits[1] + +minsToAdd;
return z(mins%(24*60)/60 | 0) + ':' + z(mins%60);
}
addMinutes('05:40', '20'); // '06:00'
addMinutes('23:50', 20);
Your scenario should be,
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//var date = new Date();
endTime.value($(this).val());
addMinutes($(this).val(), '60');
alert(endTime.value());

Categories