I have a textbox which allows users to choose a date from a calendar in mm/dd/yyyy format. I used the pikaday and moment libraries to achieve this. Now, if the user selects a date that is not in the future, I want to show an error in a label saying that the date is invalid. What is the 'best' way to achieve this? Working with dates in Javascript turned out to be quite a headache.I have provided my current approach:
textbox:
<asp:TextBox ID="txtDepartureDate" runat="server" ForeColor="Gray" onfocus="txtOnFocusDeparture(this)" onblur="txtOnBlurDeparture(this)" oninput="oninputDeparture()" AutoPostBack="True">DEPARTURE DATE</asp:TextBox>
script:
<script type="text/javascript">
function oninputDeparture() {
var inputDate = moment(document.getElementById('txtDepartureDate').value, 'DD/MM/YYYY');
var todayDate = moment().format('DD/MM/YYYY');
var lblError = document.getElementById('lblError');
var daysDiff = todayDate.diff(inputDate, 'days');
if (daysDiff <= 0) {
lblError.innerText = "Departure Day should be after today";
}
else {
lblError.innerText = "";
}
}
</script>
var todayDate = moment().format('DD/MM/YYYY');
var lblError = document.getElementById('lblError');
var daysDiff = todayDate.diff(inputDate, 'days');
moment.diff requires a moment object. todayDate is assigned as string in this case.
Also consider quick exit when the user is still typing
Have a look at the example.
var dateInput = document.getElementById('txtDepartureDate');
var lblError = document.getElementById('lblError');
function setError(text) {
lblError.innerText = text
}
function oninputDeparture() {
var value = dateInput.value;
var dateValue = moment(value, 'DD/MM/YYYY');
if (value.length < 10 || !dateValue.isValid()) {
return;
}
var todayDate = moment();
var daysDiff = todayDate.diff(dateValue, 'days');
if (daysDiff >= 0 && !dateValue.isAfter(todayDate, 'days')) {
setError("Departure Day should be after today");
} else {
setError("");
}
}
setTimeout(() => {
dateInput.value = moment().add(1, 'days').format('DD/MM/YYYY')
oninputDeparture()
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<input id="txtDepartureDate" type="text" oninput="oninputDeparture()" />
<div id="lblError"></div>
Related
I'm trying to make an alert to user when choose a date. For example, when user choose 2018-09-13, then the alert will show message "7 days later will be 2018-09-20". But instead, the alert message shows 2018-09-137.
<input type="date" name = "date" id = "date" onchange="javascript:var chooseDate=(this.value)+7; alert('7 days later will be '+chooseDate);" >
How should I add days into the date ?? please help, thank you.
this.value will return the date as string using the format YYYY-MM-DD, so if you "add" 7, it will be YYYY-MM-DD7. What you could do is create a new Date object, and then add the days you want, like this:
var chooseDate=new Date(this.value);
chooseDate.setDate(chooseDate.getDate()+7);
alert('7 days later will be '+chooseDate);
This will give you the complete date, though, which is something you probably don't want, so you would have to get the values you actually need, like this:
var chooseDate=new Date(this.value);
chooseDate.setDate(chooseDate.getUTCDate()+7);
var futureDate = chooseDate.getFullYear()+'-'+('0'+(chooseDate.getMonth()+1)).slice(-2)+'-'+('0'+(chooseDate.getDate())).slice(-2);
alert('7 days later will be '+chooseDate);
Here you have a working example:
<input type="date" name = "date" id = "date" onchange="var chooseDate=new Date(this.value);chooseDate.setDate(chooseDate.getUTCDate()+7);var futureDate=chooseDate.getFullYear()+'-'+('0'+(chooseDate.getMonth()+1)).slice(-2)+'-'+('0'+(chooseDate.getDate())).slice(-2);alert('7 days later will be '+futureDate);" >
How about this in :
addDays = function(input_date, days) {
var date = new Date(input_date);
date.setDate(date.getDate() + days);
return date;
}
You then call do addDays(this.value, 7) in onchange().
And, please reference on getDate() and setDate().
You are working with string instead of a date object:
function lPad(val) {
return ((10 > val ? '0' : '') + val);
}
function add(input, unit, value) {
var cur = input.value;
var byValue = Number(value);
if (!/^\d{4}\-\d{2}\-\d{2}$/.test(cur) || !/day|month|year/.test(unit) || isNaN(byValue)) {
console.warn('invalid parameters!');
return false;
}
var dt = new Date(cur.replace(/\-/g, '/'));
if (!dt || isNaN(dt)) {
console.warn('invalid date!');
return false;
}
if ('day' === unit) {
dt.setDate(dt.getDate() + byValue);
} else if ('month' === unit) {
dt.setMonth(dt.getMonth() + byValue);
} else {
dt.setFullYear(dt.getFullYear() + byValue);
}
input.value = [dt.getFullYear(), lPad(1 + dt.getMonth()), lPad(dt.getDate())].join('-');
console.log(cur, value, unit, '=', input.value);
return true;
}
<input type="date" onchange="add(this,'day','+7');" title="+7 days" />
<input type="date" onchange="add(this,'month','-1');" title="-1 month" />
<input type="date" onchange="add(this,'year','+2');" title="+2 year" />
try this one ...
<input type="date" name = "date" id = "date" onchange="ggrr(this)" >
<script>
function ggrr(input){
var dateString = input.value;
var myDate = new Date(dateString);
var d = new Date(Date.parse(myDate));
var y = d.getFullYear();
var da = d.getDate() + 7;
var m = d.getMonth();
console.log(y+':'+m+':'+da);
}
</script>
I want new date range in each box, but it return only last text-box date range. I also made text boxes id's dynamic but still I am facing this issues. I have start date and end date for each text box and I calculated date range in PHP for start date and end date and disabled all those dates which is selected by user in their start date and date all is working fine but it returns last textbox dates disabled in datepicker.
Here is the screenshot-
Sample Image
Javascript function for datepicker to disbaled dates for each box -
$(function () {
var count = $('#count').val();
var uid = $('#usersId').val();
var pid = $('#projectsId').val();
for (i = 1; i <= count; i++) {
$('#projectAssStartDate' + i).datepicker({
beforeShowDay: function (date) {
var dateString = jQuery.datepicker.formatDate('yy-mm-dd', date);
minDate: 0;
alert(dateRange);
console.log(dateString);
return [dateRange.indexOf(dateString) == -1];
}
});
var date_range = $('#calendarDateString' + i).val();
var newdate = date_range.replace(/,(?=[^,]*$)/, '');
var res = '"' + newdate + '"';
var startDate, endDate, dateRange = res;
$('#projectAssEndDate' + i).datepicker({
beforeShowDay: function (date) {
var dateString = jQuery.datepicker.formatDate('yy-mm-dd', date);
console.log(dateString);
return [dateRange.indexOf(dateString) == -1];
}
});
}
});
HTML for create boxes id's dynamic and fetch values from it.
<input type="text" class='datepicker' size='11' title='D-MMM-YYYY' name="projectAssStartDate[]" id="projectAssStartDate<?php echo $id;?>" value="" style="padding: 7px 8px 7px 8px;font-weight: bold;" />
<input type="text" class='datepicker' size='11' title='D-MMM-YYYY' name="projectAssEndDate[]" id="projectAssEndDate<?php echo $id;?>" value="" style="padding: 7px 8px 7px 8px;font-weight: bold;" />
<input id="calendarDateString<?php echo $id;?>" name="calendarDateString<?php echo $id;?>" title='D-MMM-YYYY' type="text" value="<?php echo $string;?>" />
<input id="projectsId" name="projectsId[]" type="hidden" value="<?php echo $rows['PROJECT_ID'];?>" />
<input id="usersId" name="usersId[]" type="hidden" value="<?php echo $rows['UM_ID'];?>" />
Please check the answer and reply whether this is the way you needed it to go. If not please comment what change you want with respect to this below code result. And I'm sorry that I have manipulated few of your values to ease my result. Will give details explanation if this is what you are expecting.
$(function () {
var count = 2;//$('#count').val();
var uid = $('#usersId').val();
var pid = $('#projectsId').val();
// populate the array
var startDatearray= ["index 0","2016-06-15","2016-06-20"]; // you dont need to create this array .. just fetch these dates from your database as u need
var endDatearray=["index 0","2016-06-21","2016-06-25"];
var i;
for (i = 1; i <= count; i++) {
$('#projectAssStartDate' + i).datepicker({
beforeShowDay: function (date) {
var i=parseInt($(this).attr('id').replace(/[^0-9\.]/g, ''), 10); // as i wont get here so i took it from the current id
var startDate = startDatearray[i], // some start date
endDate = endDatearray[i]; // some end date
var dateRange = [];
for (var d = new Date(startDate); d <= new Date(endDate); d.setDate(d.getDate() + 1)) {
dateRange.push($.datepicker.formatDate('yy-mm-dd', d));
}
var dateString = jQuery.datepicker.formatDate('yy-mm-dd', date);
minDate: 0;
//alert(date);
console.log(dateString +"__"+[dateRange.indexOf(dateString) == -1] +"__"+dateRange);
return [dateRange.indexOf(dateString) != -1]; // if u need the opposit then you can use { == -1}
}
});
var date_range = $('#calendarDateString' + i).val();
var newdate = date_range.replace(/,(?=[^,]*$)/, '');
var res = '"' + newdate + '"';
var startDate, endDate, dateRange = res;
$('#projectAssEndDate' + i).datepicker({
beforeShowDay: function (date) {
var dateString = jQuery.datepicker.formatDate('yy-mm-dd', date);
console.log(dateString);
var i=parseInt($(this).attr('id').replace(/[^0-9\.]/g, ''), 10); // as i wont get here so i took it from the current id
var startDate = startDatearray[i], // some start date
endDate = endDatearray[i]; // some end date
var dateRange = [];
for (var d = new Date(startDate); d <= new Date(endDate); d.setDate(d.getDate() + 1)) {
dateRange.push($.datepicker.formatDate('yy-mm-dd', d));
}
var dateString = jQuery.datepicker.formatDate('yy-mm-dd', date);
minDate: 0;
//alert(date);
console.log(dateString +"__"+[dateRange.indexOf(dateString) == -1] +"__"+dateRange);
return [dateRange.indexOf(dateString) != -1]; // if u need the opposit then you can use { == -1}
}
});
}
});
How to display the duration?When the dated is entered in textbox,in next field the total number of years(duration).
Example:
if user entered 09/11/2015.it should be displayed as 0.5 as value,by comparing to today's date.
`Now i use the script script
function cal()
{
obj = document.getElementById("Date");
if (obj != null) {
if (obj.value != "") {
var year = obj.value.split("/")[2];
var today = new Date();
if (year > today.getFullYear()) {
alert("Invalid Year");
document.getElementById("Date").value = "";
document.getElementById("year").value = "";
}
else {
document .getElementById("year").value = today.getFullYear() - year;
} }
}
}
`
function aa(){
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var firstDate = new Date(2016,04,12);
var secondDate = new Date(2016,04,25);
var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
alert(diffDays+" Day(s)");
//document.getElementById('test').innerHTML=diffDays;
}
<button onClick="aa()">
Click
</button>
I'm using a datepicker to choose dates, I want to calculate difference between dates choosen & then alert the difference.I'm not able see the code work
HTML datepicker
<input type="date" size="8" name="advDurFrom" />
<input type="date" size="8" name="advDurTo"/>
Javascript
$('input[name=advDurFrom]').click(function() {
var x=$('input[name=advDurFrom]').val();
var date1 = new Date(x);
});
$('input[name=advDurTo]').click(function() {
var y=$('input[name=advDurTo]').val();
var date2 = new Date(y);
});
$('input[name=advDurTo]').focusout(function() {
var diffDays = date2.getTime() - date1.getTime();
alert(diffDays);
});
Html:
<input type="date" name="startdate">
<input type="date" name="enddate">
<button id="calculate">Calculate</button>
<h2 id="result"></h2>
Script:
var startdateInput = document.querySelector('input[name="startdate"]'),
enddateInput = document.querySelector('input[name="enddate"]'),
calculateButton = document.getElementById('calculate'),
resultElement = document.getElementById('result');
calculateButton.addEventListener('click', function(e) {
if( startdateInput.value && enddateInput.value ) {
result.textContent = new Date(enddateInput.value) - new Date(startdateInput.value);
}
});
Or see the JSFiddle http://jsfiddle.net/zJTfM/
The result is the number of milliseconds between the start and end date.
$('input[name=advDurFrom]').live('change', function(e) {
var x=$(this).datepicker( "getDate" );
date1 = x.getTime();
});
$('input[name=advDurTo]').live('change', function(e) {
var y=$(this).datepicker( "getDate" );
date2 = y.getTime();
});
$('input[name=advDurTo]').live('blur', function(e) {
if(date2 && date1){
var diffDays = date2 - date1 ;
alert(diffDays);
} else {
alert("date is not selected.")
}
});
In my project I use this function to calculate difference day between 2 date,I modify some for you. see demo in jsfiddle
HTML:
<input type="text" size="8" name="advDurFrom" />
<input type="text" size="8" name="advDurTo"/>
difference days: <span class="diff"><span>
JS:
function CalendarDays(startDate, endDate) {
if (endDate < startDate)
return 0;
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0, 0, 0, 1); // Start just after midnight
endDate.setHours(23, 59, 59, 999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.round(diff / millisecondsPerDay);
return days;
}
function common_getDateFromUI(str) {
var arr = str.split("/");
var returnDate = new Date(arr[2], arr[1] - 1, arr[0], 0, 0, 0, 0);
return returnDate;
}
$().ready(function(){
$('input[name="advDurFrom"],input[name="advDurTo"]').datepicker( {
showOn : "both",
dateFormat : "dd/mm/yy",
changeMonth : true,
changeYear : true,
buttonImageOnly : true,
onSelect : function(dateText, inst) {
var day1 = common_getDateFromUI($('input[name="advDurFrom"]').val());
var day2 = common_getDateFromUI($('input[name="advDurTo"]').val());
$(".diff").html(CalendarDays(day1,day2));
}
});
});
I think you need to declare the variable globally. Try this code. This is working perfectly for me.
var date1 = "";
var date2 = "";
$('#advDurFrom').click(function () {
var x = $(this).val();
date1 = new Date(x);
});
$('#advDurTo').click(function () {
var y = $(this).val();
date2 = new Date(y);
});
$('#advDurTo').focusout(function () {
var diffDays = date2.getTime() - date1.getTime();
alert(diffDays);
});
And Change the HTML to
<input type="date" size="8" id="advDurFrom" />
<input type="date" size="8" id="advDurTo" />
getTime returns millisecond, you just need to convert into the correct unit. Here an example with days difference. Also use blur event not click or you will end up assigning the value before the user actually inputs it
var isOK = false;
var isOK2 = false;
$('input[name=advDurFrom]').blur(function () {
var x = $('input[name=advDurFrom]').val();
try {
date1 = new Date(x);
isOK = !isNaN(date1);
} catch (e) {
isOK = false;
}
printDiff();
});
$('input[name=advDurTo]').blur(function () {
var y = $('input[name=advDurTo]').val();
try {
date2 = new Date(y);
isOK2 = !isNaN(date2);
} catch (e) {
isOK2 = false;
}
printDiff();
});
function printDiff(){
if (isOK && isOK2) {
var one_day = 1000 * 60 * 60 * 24;
var diff = Math.ceil((date2.getTime() - date1.getTime()) / (one_day));
console.log(diff + ' days');
}
}
Fiddle here
I have function that loops every 500ms, and collects date information:
var mlptoday = {};
var timer = setTimeout(today,500);
function today(){
var d = new Date()
mlptoday.date = checkTime(d.getDate()); //output: "27"
mlptoday.year = d.getFullYear(); //output: "2013"
mlptoday.month = checkTime(d.getMonth()+1); //output: "01"
}
function checkTime(i) { if (i<10){i="0" + i} return i }
In a different function, I would like to check if the date the user gives as input is either the same day, or after the given day.
An example input may be: 2013.01.27.
I use this snippet of code to achieve what I want:
var remTime = "2013.01.27"; //user input
var remTimeArray = remTime.split('.') //output: ["2013","01","27"]
if (
!(remTimeArray[0] >= parent.mlptoday.year &&
remTimeArray[1] >= parent.mlptoday.month) ||
!((remTimeArray[1] == parent.mlptoday.month) ? Boolean(remTimeArray[2]*1 >= parent.mlptoday.date) : true)
){
//the input date is in the past
}
As you could probably guess, this does not work. The conditional statement seems to fail me, because if I invert Boolean(...) with an !(...), it will never fire the error, otherwise it always will.
Here's a snippet, where it works at it should:
var mlptoday = {};
var timer = setTimeout(today,500);
function today(){
var d = new Date();
mlptoday.year = d.getFullYear(); //output: "2013"
mlptoday.month = checkTime(d.getMonth()+1); //output: "01"
mlptoday.date = checkTime(d.getDate()); //output: "27"
$('#values').html(JSON.stringify(mlptoday));
}
function checkTime(i) { if (i<10){i="0" + i} return i }
$(document).ready(function(){
$('form').submit(function(e){
e.preventDefault();
var remTime = $('input').val(); //user input
var remTimeArray = remTime.split('.') //output: ["2013","01","27"]
if (
!(remTimeArray[0] >= mlptoday.year &&
remTimeArray[1] >= mlptoday.month) ||
!((remTimeArray[1] == mlptoday.month) ? Boolean(remTimeArray[2]*1 >= mlptoday.date) : true)
){
$('#past').fadeIn('fast').delay(500).fadeOut('fast');
}
})
})
#past { display:none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form>
<input type="text" id="input" required autocomplete="off" placeholder="yyyy.mm.dd" pattern="^(19|20)\d\d[.](0[1-9]|1[012])[.](0[1-9]|[12][0-9]|3[01])$" required="" />
<button>Check</button>
</form>
<pre id="values"></pre>
<span id="past">the input date is in the past</span>
I need a better way to do this, and I don't want to use any date picker plugins.
I would compare the dates as integers to avoid complex logic.
var todayConcat = "" + parent.mlptoday.year + parent.mlptoday.month + parent.mlptoday.date;
var remTimeConcat = remTime.replace(/\./g, "");
if (remTimeConcat < todayConcat) {
//the input time is in the past
}
Just make sure the dates and months always have the leading zero.