I want to enter a “/” when user enters MM(2 digit) so it will be like MM/YYYY.
I have done similar for credit card number input which insert a space after 4 digit on keypress.
JavaScript
x
6
1
let ccNumber = e.target.value.split(" ").join("");
2
if (ccNumber.length > 0) {
3
ccNumber = ccNumber.match(new RegExp('.{1,4}', 'g')).join(" ");
4
}
5
e.target.value = ccNumber;
6
Advertisement
Answer
Fiddle
This works with
- Regular keyboard input
- Copy/Cut/Paste
- Selected text
Adding the /
Because you’re programmatically adding the /
character, you have to update the cursor position whenever that affects the new input value. This can be more than one character if the user is pasting something. Most of the code complexity revolves around this issue.
There are a lot of comments in the code explaining the various situations that come up because of the /
.
Full Code
JavaScript
1
93
93
1
var date = document.getElementById('date');
2
3
date.addEventListener('keypress', updateInput);
4
date.addEventListener('change', updateInput);
5
date.addEventListener('paste', updateInput);
6
date.addEventListener('keydown', removeText);
7
date.addEventListener('cut', removeText);
8
9
function updateInput(event) {
10
event.preventDefault();
11
var string = getString(event);
12
var selectionStart = this.selectionStart;
13
var selectionEnd = this.selectionEnd;
14
var selectionLength = selectionEnd - selectionStart;
15
var sanitizedString = string.replace(/[^0-9]+/g, '');
16
// Do nothing if nothing is added after sanitization
17
if (sanitizedString.length === 0) {
18
return;
19
}
20
// Only paste numbers that will fit
21
var valLength = date.value.replace(/[^0-9]+/g, '').length;
22
var availableSpace = 6 - valLength + selectionLength;
23
// If `/` is selected it should not count as available space
24
if (selectionStart <= 2 && selectionEnd >= 3) {
25
availableSpace -= 1;
26
}
27
// Remove numbers that don't fit
28
if (sanitizedString.length > availableSpace) {
29
sanitizedString = sanitizedString.substring(0, availableSpace);
30
}
31
var newCursorPosition = selectionEnd + sanitizedString.length - selectionLength;
32
// Add one to cursor position if a `/` gets inserted
33
if (selectionStart <= 2 && newCursorPosition >= 2) {
34
newCursorPosition += 1;
35
}
36
// Previous input value before current cursor position
37
var valueStart = date.value.substring(0, this.selectionStart);
38
// Previous input value after current cursor position
39
var valueEnd = date.value.substring(this.selectionEnd, date.value.length);
40
var proposedValue = valueStart + sanitizedString + valueEnd;
41
// Remove anything that's not a number
42
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
43
format(sanitized);
44
this.setSelectionRange(newCursorPosition, newCursorPosition);
45
}
46
47
function removeText(event) {
48
if (event.key === 'Backspace' || event.type === 'cut') {
49
event.preventDefault();
50
var selectionStart = this.selectionStart;
51
var selectionEnd = this.selectionEnd;
52
var selectionLength = selectionEnd - selectionStart;
53
// If pressing backspace with no selected text
54
if (selectionLength === 0 && event.type !== 'cut') {
55
selectionStart -= 1;
56
// Remove number from before `/` if attempting to delete `/`
57
if (selectionStart === 2) {
58
selectionStart -= 1;
59
}
60
}
61
var valueStart = date.value.substring(0, selectionStart);
62
var valueEnd = date.value.substring(selectionEnd, date.value.length);
63
// Account for added `/`
64
if (selectionStart === 2) {
65
selectionStart += 1;
66
}
67
var proposedValue = valueStart + valueEnd;
68
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
69
format(sanitized);
70
this.setSelectionRange(selectionStart, selectionStart);
71
}
72
}
73
74
function getString(event) {
75
if (event.type === 'paste') {
76
var clipboardData = event.clipboardData || window.clipboardData;
77
return clipboardData.getData('Text');
78
} else {
79
return String.fromCharCode(event.which);
80
}
81
}
82
83
function format(sanitized) {
84
var newValue;
85
var month = sanitized.substring(0, 2);
86
if (sanitized.length < 2) {
87
newValue = month;
88
} else {
89
var year = sanitized.substring(2, 6);
90
newValue = month + '/' + year;
91
}
92
date.value = newValue;
93
}
JavaScript
1
1
1
<input id="date" type="text" maxlength="7">