Created
June 22, 2020 00:53
-
-
Save adrianspacely/961f2c9a507976d5b9603ad34394b72b to your computer and use it in GitHub Desktop.
Google Chrome's date picker is pretty decent. This gives it the desired UX for copying and pasting in d/m/Y format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Google Chrome's date picker is pretty decent. This gives it the desired UX for copying and pasting. | |
export default function (Vue, options) { | |
Vue.mixin({ | |
updated() { | |
Array.from(document.querySelectorAll('input')).filter(input => input.type === 'date').forEach(input => { | |
input.addEventListener('blur', onBlur); | |
input.addEventListener('copy', onCopy); | |
input.addEventListener('paste', onPaste); | |
}); | |
} | |
}); | |
// It should format short years when tabbing away. | |
const onBlur = event => { | |
if (event.target.value) setDateValue(event.target.value, event.target); | |
}; | |
// We want to copy in the d/m/Y format. | |
const onCopy = event => { | |
event.preventDefault(); | |
if (event.clipboardData) event.clipboardData.setData('text/plain', event.target.value.split('-').reverse().join('/')); | |
else navigator.clipboard.writeText(document.activeElement.value.split('-').reverse().join('/')); | |
}; | |
// Paste should handle different formats and short days, months, and years. | |
const onPaste = async event => { | |
event.preventDefault(); | |
let value = event.clipboardData | |
? event.clipboardData.getData('text/plain') | |
: await navigator.clipboard.readText(); | |
setDateValue(value, event.target); | |
}; | |
// This is the date setting logic used for blur and paste. | |
const setDateValue = (value, element) => { | |
let day, month, year; | |
if (value.includes('-')) { | |
[year, month, day] = value.split('-'); | |
if (! year) return; | |
} else if (value.includes('/')) { | |
[day, month, year] = value.split('/'); | |
if (! day) return; | |
} | |
const shortYear1900sOr2000s = (new Date).getFullYear() - 1900 - 65; | |
if (year && year < shortYear1900sOr2000s) year = parseInt(year) + 2000; | |
if (year && year >= shortYear1900sOr2000s && year <= 100) year = parseInt(year) + 1900; | |
if (! day) day = (new Date).getDate(); | |
if (! month) month = (new Date).getMonth() + 1; | |
if (! year) year = (new Date).getFullYear(); | |
day = parseInt(day); | |
month = parseInt(month); | |
if (day < 10) day = `0${day}`; | |
if (month < 10) month = `0${month}`; | |
element.value = [year, month, day].join('-'); | |
}; | |
// Copy appears to not be reliable for date inputs, this will ensure the copy or paste happens. | |
let cmd = false; | |
document.addEventListener('keyup', event => cmd = false); | |
document.addEventListener('keydown', event => { | |
if (event.code === 'MetaLeft') cmd = true; | |
else if (event.code === 'MetaRight') cmd = true; | |
else if (event.code === 'ControlLeft') cmd = true; | |
else if (event.code === 'ControlRight') cmd = true; | |
else if (cmd === true && document.activeElement.type === 'date') { | |
if (event.code === 'KeyC') document.activeElement.dispatchEvent(new Event('copy')); | |
if (event.code === 'KeyV') document.activeElement.dispatchEvent(new Event('paste')); | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment