Skip to content

Commit

Permalink
fix: improve validation when creating input (#26)
Browse files Browse the repository at this point in the history
* Update validation to restrict input to only digits that create a valid date
* Remove guesstimation functionality around selecting from an invalid date
  • Loading branch information
lewisbirks authored Aug 10, 2022
1 parent 64e7586 commit ccb0c22
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 32 deletions.
90 changes: 72 additions & 18 deletions src/__tests__/datepicker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,64 +558,118 @@ describe('Date picker', () => {
expect(previousYearButton.tabIndex).toEqual(0);
});

it('should set focus on nearest date when day input is incorrectly formatted', () => {
it('should set focus on today when day input is not a number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('40');
$(dayInput).val('3 12');
$(monthInput).val('11');
$(yearInput).val('2021');

$(revealButton).trigger('click');

const nearestDate = DateTime.fromObject({ year: 2021, month: 11, day: 30 });
const nearestDateButton = document.querySelector(`[data-test-id="${nearestDate.toLocaleString()}"]`);
const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(nearestDateButton === document.activeElement).toBeTruthy();
expect(nearestDateButton.tabIndex).toEqual(0);
expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});

it('should set focus on nearest date when month input is incorrectly formatted', () => {
it('should set focus on today when month input is not a number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('15');
$(monthInput).val('13');
$(monthInput).val('11 20');
$(yearInput).val('2021');

$(revealButton).trigger('click');

const nearestDate = DateTime.fromObject({ year: 2021, month: 12, day: 15 });
const nearestDateButton = document.querySelector(`[data-test-id="${nearestDate.toLocaleString()}"]`);
const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(nearestDateButton === document.activeElement).toBeTruthy();
expect(nearestDateButton.tabIndex).toEqual(0);
expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});

it('should set focus on 31st December when day and month input is incorrectly formatted', () => {
it('should set focus on today when year input is not a number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('32');
$(dayInput).val('15');
$(monthInput).val('11');
$(yearInput).val('20 22');

$(revealButton).trigger('click');

const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});

it('should set focus on today when day input is an invalid number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('1125');
$(monthInput).val('11');
$(yearInput).val('2022');

$(revealButton).trigger('click');

const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});

it('should set focus on today when month input is an invalid number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('11');
$(monthInput).val('13');
$(yearInput).val('2022');

$(revealButton).trigger('click');

const nearestDate = DateTime.fromObject({ year: 2022, month: 12, day: 31 });
const nearestDateButton = document.querySelector(`[data-test-id="${nearestDate.toLocaleString()}"]`);
const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(nearestDateButton === document.activeElement).toBeTruthy();
expect(nearestDateButton.tabIndex).toEqual(0);
expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});

it('should set focus on today when year input is an invalid number', () => {
datePicker(document.querySelector('.date-picker'), {});
const revealButton = document.querySelector('.date-picker__reveal');
const dayInput = document.querySelector('.date-picker-day');
const monthInput = document.querySelector('.date-picker-month');
const yearInput = document.querySelector('.date-picker-year');

$(dayInput).val('11');
$(monthInput).val('11');
$(yearInput).val('202220222022202220222022');

$(revealButton).trigger('click');

const focusedDate = document.querySelector(`[data-test-id="${now.toLocaleString()}"]`);

expect(focusedDate === document.activeElement).toBeTruthy();
expect(focusedDate.tabIndex).toEqual(0);
});
});

Expand Down
34 changes: 20 additions & 14 deletions src/js/datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,26 +122,32 @@ function datePicker(datePickerElement, options = {}) {
}

function getDateFromInputs() {
var tempDate;
var inputDates = {
const inputDates = {
day: elements.inputs.day.value,
month: elements.inputs.month.value,
year: elements.inputs.year.value,
};

if (parseInt(inputDates.day, 10) && parseInt(inputDates.month, 10)
&& parseInt(inputDates.year, 10)) {
tempDate = new Date(inputDates.year, inputDates.month, 0);
if (inputDates.month > 12 && inputDates.day > tempDate.getDate()) {
return new Date(inputDates.year, 11, 31);
} else if (inputDates.month > 12) {
return new Date(inputDates.year, 11, inputDates.day);
} else if (inputDates.day > tempDate.getDate()) {
return tempDate;
}
return new Date(inputDates.year, inputDates.month - 1, inputDates.day);
function isValidInput(input) {
const expression = /^\d+$/;
return expression.test(input);
}

function isValidDate(input) {
const date = new Date(input.year, input.month - 1, input.day);
return date.getFullYear() === Number(input.year)
&& date.getMonth() + 1 === Number(input.month)
&& date.getDate() === Number(input.day);
}
return new Date();

if (!(isValidInput(inputDates.day)
&& isValidInput(inputDates.month)
&& isValidInput(inputDates.year)
&& isValidDate(inputDates))) {
return new Date();
}

return new Date(inputDates.year, inputDates.month - 1, inputDates.day);
}

function setInputDate(date) {
Expand Down

0 comments on commit ccb0c22

Please sign in to comment.