I have written a simple javascript function that takes the input of a date textfield and convert it to dd-mm-yyyy format.
function dateConvert(dateValue) {
if(dateValue == null) {
var grDate = null;
}
else {
var n = dateValue.search("/");
if( n >= 0) {
var res = dateValue.split("/");
var day = res[0];
if( day.length == 1 ) {
day = "0"+day;
}
var month = res[1];
if( month.length == 1 ) {
month = "0"+month;
}
var year = res[2];
var grDate = day+"-"+month+"-"+year;
/*alert(grDate);*/
}
else {
var grDate = dateValue;
}
}
document.getElementById("mydate").value = grDate;
}
<input type="text" name="mydate" id="mydate" onblur="dateConvert(this.value)" />
Is there a way to make function "global" and use it to every textfield that calls the function without having to write it e.g. 3 times if I want to use it in 3 different date textfields?
Thanks for the replay to Dominik. Make my mind spin
I didn't use event listener but querySelectorAll
Here is the correct version. It works fine
function myFunction() {
var x = document.querySelectorAll(".mydate");
var i;
for (i = 0; i < x.length; i++) {
var dateValue = x[i].value;
if(dateValue == null) {
var grDate = null;
}
else {
var n = dateValue.search("/");
if( n >= 0) {
var res = dateValue.split("/");
var day = res[0];
if( day.length == 1 ) {
day = "0"+day;
}
var month = res[1];
if( month.length == 1 ) {
month = "0"+month;
}
var year = res[2];
var grDate = day+"-"+month+"-"+year;
/*alert(grDate);*/
}
else {
var grDate = dateValue;
}
}
x[i].value = grDate;
}
}
for inputs
<p><input type="text" name="field1" class="mydate" onblur="myFunction()" /></p>
<p><input type="text" name="field2" class="mydate" onblur="myFunction()" /></p>
<p><input type="text" name="field3" class="mydate" onblur="myFunction()" /></p>
Excellent question - because this is the perfect example where a custom element solves the problem.
It's really easy:
customElements.define('my-date', class extends HTMLInputElement {
constructor() {
super();
this.dateConvert = this.dateConvert.bind(this);
this.addEventListener('blur', this.dateConvert);
}
dateConvert() {
if (this.value) {
let n, res, day, month, year;
n = this.value.search("/");
if (n >= 0) {
res = this.value.split("/");
day = res[0];
if (day.length == 1) {
day = "0" + day;
}
month = res[1];
if (month.length == 1) {
month = "0" + month;
}
year = res[2];
this.value = `${day}-${month}-${year}`;
}
}
}
}, { extends: 'input' });
<input is="my-date" />
Now you can even add new date inputs dynamically and they come with your behaviour automatically. No fuddling around in the DOM, just an element that does exactly what you need any time it's in the HTML anywhere.
Please note that unfortunately Safari does not support customizing built-in elements, so you either will have to resort to a polyfill (check https://github.com/webcomponents/polyfills/tree/master/packages/custom-elements or https://github.com/ungap/custom-elements#readme) for that, or use an autonomous custom elements like this:
customElements.define('my-date', class extends HTMLElement {
constructor() {
super();
this.input = document.createElement('input');
this.appendChild(this.input);
this.dateConvert = this.dateConvert.bind(this);
this.input.addEventListener('blur', this.dateConvert);
}
dateConvert() {
if (this.value) {
let n, res, day, month, year;
n = this.value.search("/");
if (n >= 0) {
res = this.value.split("/");
day = res[0];
if (day.length == 1) {
day = "0" + day;
}
month = res[1];
if (month.length == 1) {
month = "0" + month;
}
year = res[2];
this.value = `${day}-${month}-${year}`;
}
}
}
get value() {
return this.input.value;
}
set value(val) {
this.input.value = val;
}
});
<my-date></my-date>
Just as a sidenote, you might want to consider using the built-in API for dateTime conversion/formatting:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
Related
I have this code which you can select date and get results according to it. Now in the place of months and years selection i want a button that shows previous month and another button that shows next month. Like that Next day and previous day. Can someone please help me with this code snippet.
1. Button one - Previous month
2. Button two - Next month
3. Button three - Previous Day
4. Button four - Next Day
All results should be on HTML page.
<HTML>
<HEAD>
<TITLE></TITLE>
<STYLE TYPE="text/css">
TD, TH {text-align:center}
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
function getFirstDay(theYear, theMonth){
var firstDate = new Date(theYear,theMonth,1)
return firstDate.getDay()
}
function getMonthLen(theYear, theMonth) {
var oneDay = 1000 * 60 * 60 * 24
var thisMonth = new Date(theYear, theMonth, 1)
var nextMonth = new Date(theYear, theMonth + 1, 1)
var len = Math.ceil((nextMonth.getTime() -
thisMonth.getTime())/oneDay)
return len
}
var theMonths = ["January","February","March","April","May","June","July","August",
"September","October","November","December"]
function getObject(obj) {
var theObj
if (document.all) {
if (typeof obj == "string") {
return document.all(obj)
} else {
return obj.style
}
}
if (document.getElementById) {
if (typeof obj == "string") {
return document.getElementById(obj)
} else {
return obj.style
}
}
return null
}
function populateTable(form) {
var theMonth = form.chooseMonth.selectedIndex
var theYear = parseInt(form.chooseYear.options[form.chooseYear.selectedIndex].text)
// initialize date-dependent variables
var firstDay = getFirstDay(theYear, theMonth)
var howMany = getMonthLen(theYear, theMonth)
// fill in month/year in table header
getObject("tableHeader").innerHTML = theMonths[theMonth] +
" " + theYear
// initialize vars for table creation
var dayCounter = 1
var TBody = getObject("tableBody")
// clear any existing rows
while (TBody.rows.length > 0) {
TBody.deleteRow(0)
}
var newR, newC
var done=false
while (!done) {
// create new row at end
newR = TBody.insertRow(TBody.rows.length)
for (var i = 0; i < 7; i++) {
// create new cell at end of row
newC = newR.insertCell(newR.cells.length)
if (TBody.rows.length == 1 && i < firstDay) {
// no content for boxes before first day
newC.innerHTML = ""
continue
}
if (dayCounter == howMany) {
// no more rows after this one
done = true
}
// plug in date (or empty for boxes after last day)
newC.innerHTML = (dayCounter <= howMany) ?
dayCounter++ : ""
}
}
}
function fillYears() {
var today = new Date()
var thisYear = today.getFullYear()
var yearChooser = document.dateChooser.chooseYear
for (i = thisYear; i < thisYear + 5; i++) {
yearChooser.options[yearChooser.options.length] = new Option(i, i)
}
setCurrMonth(today)
}
// set month choice to current month
function setCurrMonth(today) {
document.dateChooser.chooseMonth.selectedIndex = today.getMonth()
}
</SCRIPT>
</HEAD>
<BODY onLoad="fillYears(); populateTable(document.dateChooser)">
<H1>Calender</H1>
<HR>
<TABLE style="width:100%;height:80%;" ID="calendarTable" BORDER=1 ALIGN="center">
<TR>
<TH ID="tableHeader" COLSPAN=7></TH>
</TR>
<TR><TH>Sun</TH><TH>Mon</TH><TH>Tue</TH><TH>Wed</TH>
<TH>Thu</TH><TH>Fri</TH><TH>Sat</TH></TR>
<TBODY ID="tableBody"></TBODY>
<TR>
<TD COLSPAN=7>
<P>
<FORM NAME="dateChooser">
<SELECT NAME="chooseMonth"
onChange="populateTable(this.form)">
<OPTION SELECTED>January<OPTION>February
<OPTION>March<OPTION>April<OPTION>May
<OPTION>June<OPTION>July<OPTION>August
<OPTION>September<OPTION>October
<OPTION>November<OPTION>December
</SELECT>
<SELECT NAME="chooseYear" onChange="populateTable(this.form)">
</SELECT>
</FORM>
</P></TD>
</TR>
</TABLE>
</BODY>
</HTML
I suggest to use moment.js. It helps alot when you work with time and date.
e.g. after pressing a button "next month" you can use moment().add(1, 'months') to add 1 month to your current date. you can store the date after switching e.g. on data attributes or hidden input or ...
complete documentation you can find on https://momentjs.com/docs/
We have set of checkbox which is identified as date checkbox. These are known as check-in date. Check-out is 1 greater then check-in date. For example if check-in date is 24/09/2017 then checkout is 25/09/2017.
So We are trying to get short date range if continuous date selected, For example, if we have four date 24/09/2017,25/09/2017,26/09/2017,27/09/2017. If we select 24/09/2017 then check-in date is 24/09/2017 and checkout is 25/09/2017. But if we select 24 and 25,26 then in array we have three values
checkindat:"24/09/2017",checkouts:"25/09/2017"
and
checkindat:"25/09/2017",checkouts:"26/09/2017"
and
checkindat:"26/09/2017",checkouts:"27/09/2017"
so we want if date range in sequence then it would show check-in date as 24/0/2017 and checkout date as 27/09/2017. But if we un-check date then it would work as its working now.
here is some part of my code in this jsfiddle
var alreadycheckin = [];
$("input[class='check htcheck']:checkbox").change(function() {
var roomids = $(this).attr("roomid");
checkindat = $(this).attr("name");
var new_dates = moment(checkindat, "DD.MM.YYYY");
var checkid = new_dates.format('DD-MM-YYYY');
//if ($(this).is(":checked"))
{
var html = '';
arr = [];
var roomcods = $(this).attr("value");
var roomids = $(this).attr("roomid");
checkindat = $(this).attr("name");
var new_dates = moment(checkindat, "DD.MM.YYYY");
var checkid = new_dates.format('DD-MM-YYYY');
//console.log(checkid);
var checkouts = new_dates.add(1, 'days').format('DD/MM/YYYY');
var roomcodes = $(this).attr("value");
var uniq = roomids + '_' + name + '_' + checkindat;
uniq = uniq.split("/").join("").split("_").join("");
var uniqs = '';
//console.log($("#aa"+roomids));
// alreadycheckin.push({ roomids : roomids, checkindat : checkindat, checkouts: checkouts });
var arrElement = {
roomids: roomids,
checkindat: checkindat,
checkouts: checkouts
};
if ($(this).is(":checked")) {
//alreadycheckin[uniq]={ roomids : roomids, checkindat : checkindat, checkouts: checkouts };
alreadycheckin.push(arrElement);
} else {
var index1 = arr.indexOf(arrElement);
alreadycheckin.splice(index1, 1);
}
var tmpAlreadycheckin = [];
// tmpAlreadycheckin=alreadycheckin.slice(0);
for (var i = 0; i < alreadycheckin.length; i++) {
if (i > 0) {
if (typeof alreadycheckin[i - 1] != "undefined" || alreadycheckin[i - 1] != null) {
if (alreadycheckin[i].checkouts == alreadycheckin[i - 1].checkindat) {
console.log("111");
var arrElement1 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i - 1].checkouts
};
tmpAlreadycheckin.push(arrElement1);
//tmpAlreadycheckin[i].checkouts =tmpAlreadycheckin[i+1].checkouts;
//tmpAlreadycheckin.splice(i+1, 1);
} else {
console.log("2222");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
} else {
console.log("3333");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
} else {
console.log("3333");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
}
console.log(tmpAlreadycheckin);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<input roomid="15" id="15_24/09/2017" class="check htcheck" name="24/09/2017" value="1" type="checkbox">24/09/2017 <br/>
<input roomid="15" id="15_25/09/2017" class="check htcheck" name="25/09/2017" value="1" type="checkbox">25/09/2017 <br/>
<input roomid="15" id="15_26/09/2017" class="check htcheck" name="26/09/2017" value="1" type="checkbox">26/09/2017 <br/>
<input roomid="15" id="15_27/09/2017" class="check htcheck" name="27/09/2017" value="1" type="checkbox">27/09/2017 <br/>
If you have an array of objects in this format: [{checkindat:"24/09/2017",checkouts:"25/09/2017"},{checkindat:"25/09/2017",checkouts:"26/09/2017"}] :then you could first sort the array by checkindate, and then iterate over the array backwards. You would start on the last element, look at its checkindat, then compare it to the previous element's checkouts. If they're the same, update the previous elements checkouts to the one ahead of it, and then delete the one ahead of it.
My database contains the dates. I have a calendar that appears on the User Interface. I want the calendar to reflect the dates from mysql database ie. populate the calendar with the dates from database.
<SCRIPT LANGUAGE="JavaScript">
// day of week of month's first day
function getFirstDay(theYear, theMonth){
var firstDate = new Date(theYear,theMonth,1)
return firstDate.getDay()
}
// number of days in the month
function getMonthLen(theYear, theMonth) {
var oneDay = 1000 * 60 * 60 * 24
var thisMonth = new Date(theYear, theMonth, 1)
var nextMonth = new Date(theYear, theMonth + 1, 1)
var len = Math.ceil((nextMonth.getTime() -
thisMonth.getTime())/oneDay)
return len
}
// create array of English month names
var theMonths = ["January","February","March","April","May","June","July","August",
"September","October","November","December"]
// return IE4+ or W3C DOM reference for an ID
function getObject(obj) {
var theObj
if (document.all) {
if (typeof obj == "string") {
return document.all(obj)
} else {
return obj.style
}
}
if (document.getElementById) {
if (typeof obj == "string") {
return document.getElementById(obj)
} else {
return obj.style
}
}
return null
}
// clear and re-populate table based on form's selections
function populateTable(form) {
var theMonth = form.chooseMonth.selectedIndex
var theYear = parseInt(form.chooseYear.options[form.chooseYear.selectedIndex].text)
// initialize date-dependent variables
var firstDay = getFirstDay(theYear, theMonth)
var howMany = getMonthLen(theYear, theMonth)
// fill in month/year in table header
getObject("tableHeader").innerHTML = theMonths[theMonth] +
" " + theYear
// initialize vars for table creation
var dayCounter = 1
var TBody = getObject("tableBody")
// clear any existing rows
while (TBody.rows.length > 0) {
TBody.deleteRow(0)
}
var newR, newC
var done=false
while (!done) {
// create new row at end
newR = TBody.insertRow(TBody.rows.length)
for (var i = 0; i < 7; i++) {
// create new cell at end of row
newC = newR.insertCell(newR.cells.length)
if (TBody.rows.length == 1 && i < firstDay) {
// no content for boxes before first day
newC.innerHTML = ""
continue
}
if (dayCounter == howMany) {
// no more rows after this one
done = true
}
// plug in date (or empty for boxes after last day)
newC.innerHTML = (dayCounter <= howMany) ?
dayCounter++ : ""
}
}
}
// create dynamic list of year choices
function fillYears() {
var today = new Date()
var thisYear = today.getFullYear()
var yearChooser = document.dateChooser.chooseYear
for (i = thisYear; i < thisYear + 5; i++) {
yearChooser.options[yearChooser.options.length] = new Option(i, i)
}
setCurrMonth(today)
}
// set month choice to current month
function setCurrMonth(today) {
document.dateChooser.chooseMonth.selectedIndex = today.getMonth()
}
</SCRIPT>
</HEAD>
<BODY onLoad="fillYears(); populateTable(document.dateChooser)">
<H1>Month at a Glance (Dynamic HTML)</H1>
<HR>
<TABLE ID="calendarTable" BORDER=1 ALIGN="center">
<TR>
<TH ID="tableHeader" COLSPAN=7></TH>
</TR>
<TR><TH>Sun</TH><TH>Mon</TH><TH>Tue</TH><TH>Wed</TH>
<TH>Thu</TH><TH>Fri</TH><TH>Sat</TH></TR>
<TBODY ID="tableBody"></TBODY>
<TR>
<TD COLSPAN=7>
<P>
<FORM NAME="dateChooser">
<SELECT NAME="chooseMonth"
onChange="populateTable(this.form)">
<OPTION SELECTED>January<OPTION>February
<OPTION>March<OPTION>April<OPTION>May
<OPTION>June<OPTION>July<OPTION>August
<OPTION>September<OPTION>October
<OPTION>November<OPTION>December
</SELECT>
<SELECT NAME="chooseYear" onChange="populateTable(this.form)">
</SELECT>
</FORM>
</P></TD>
</TR>
</TABLE>
</BODY>
</HTML>
I need help to get this working. I have done a script that validate the field "Personalnumber". But i dont know how to link the togheter and get it working.
Can someone help?
//If the form looks weird, i have deleted all the other fields just to get a shorter code.
<script>
function validatePNum(sPNum)
{
var numbers = sPNum.match(/^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/);
var checkSum = 0;
var d = new Date();
if (!isDate(sPNum.substring(0,4),sPNum.substring(4,6),sPNum.substring(6,8))) {
alert("Datumet " + sPNum.substring(0,8) + " är inte korrekt.");
return false;
}
if (numbers == null) { return false; }
var n;
for (var i = 3; i <= 12; i++)
{
n=parseInt(numbers[i]);
if (i % 2 == 0) {
checkSum+=n;
} else {
checkSum+=(n*2)%9+Math.floor(n/9)*9
}
}
if (checkSum%10==0) { return true;}
return false;
}
function getYear(y) { return (y < 1000) ? y + 1900 : y; }
function isDate(year, month, day)
{
month = month - 1; // 0-11 in JavaScript
var tmpDate = new Date(year,month,day);
if ( (getYear(tmpDate.getYear()) == year) &&
(month == tmpDate.getMonth()) &&
(day == tmpDate.getDate()) )
return true;
else
return false;
}
</script>
<form method="post" name="post" action="index.php?site=register">
<tr>
<td class="border_1" align="left">Personnummer:</td>
<td class="border_1"><input id="personalnumber" type="text" name="personalnumber" value="$personalnumber" size="30"/><small> YYYYMMDDXXXX</small></td>
</tr>
<div align="center"><input name="save" type="submit" value="Registera" /></div>
</form>
First of all change the name in your form to something like name="myForm". Then, you can link your JS code with your form by taking the value of the field, ie var x = document.forms["myForm"].value;. Not tested, but this is a way to link your js code with the form in your html.
You Can use jQuery
just add to your form id (like form_id in my example).
$('#form_id').submit(function(){
validatePNum(sPNum)
//do more things
});
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.