Reputation: 65
I want to display a text box on my webpage which has a Date input mask. For example: When the user visits the page; the text box should be prefilled with dd/mm/yyyy in light grey color. He should overwrite the same using some valid date like 20/12/1990.
How to accomplish this task (JQuery, JavaScript)? Any inputs would be helpful!!
Upvotes: 0
Views: 7703
Reputation: 3045
I was looking for code like this while back. There are a lot of mask plugins but if you want to roll your own this is a good start.
This allows arrow key usage, highlight and delete, overwrite the date just by typing.
let input = document.getElementById("input");
input.addEventListener("keydown", date_mask);
input.addEventListener("focus", on_focus);
let old_date = "01/01/2022";
input.value = old_date;
function date_mask(e) {
if (e.key.match(/Arrow/g)) return; //ignore Arrow keys
let new_date = e.target.value;
new_date = str_splice(new_date,e.target.selectionStart, e.target.selectionEnd, ""); //if we highlighted we are overwriting;
let caret = e.target.selectionStart; //get current caret position
if (e.key.match(/^\w$/g)) {
//only trigger on a single character -
//this prevents it from looking weird as slashes are inserted in an empty input box
e.preventDefault();
new_date = str_splice(new_date, caret, caret, e.key);
caret++;
}
let mask_result = mask(caret, new_date, old_date, "dd/dd/dddd");
e.target.value = mask_result.date;
old_date = mask_result.date;
e.target.setSelectionRange(mask_result.caret, mask_result.caret); //set new caret position
}
function mask(caret, new_date, old_date, mask) {
//CARET CONTROL and WRITE OVER
let diff = new_date.length - old_date.length;
//Caret control
if (diff == 1) {
//we have added a number
if (!new_date.charAt(caret).match(/\d/g)) caret++; //if its not a digit we move the caret forward
new_date = new_date.slice(0, caret) + new_date.slice(caret + 1); //write over the date
} else {
//we have deleted
if (!new_date.charAt(caret - 1).match(/\d/g)) {
//if its not a digit behind us we move the carat backwards
caret = caret - 1 < 0 ? 0 : caret - 1;
}
}
//MASKING
new_date = new_date.replace(/[^\d\n]/g, ""); //remove everything but the digits
let parsed = mask.split("").reduce(
(acc, obj, i) => {
if (i < new_date.length + acc.ctr) {
//we dont want to add extra slashes if the number isnt big enough
if (obj == "d") {
//replace all d's with digits
acc = {
date: (acc.date += new_date.charAt(i - acc.ctr)), //we remove any slashes using the slash counter
ctr: acc.ctr
};
} else {
//its part of the mask (a slash)
acc = { date: (acc.date += obj), ctr: acc.ctr + 1 }; //increment the slash counter
}
}
return acc;
},
{ date: "", ctr: 0 }
);
return { date: parsed.date, caret: caret };
}
function on_focus(e) {
setTimeout(function () { //we have to set a timeout otherwise it won't work
e.target.setSelectionRange(0, 0);
}, 0);
};
function str_splice(str, start, end, replace) {
let del_num = end - start;
str = str.split("");
str.splice(start, end - start, replace);
return str.join("");
}
<input id="input"></input>
Upvotes: 0