keystone-5
keystone-5 copied to clipboard
CalendarDay field is causing reload (refresh) of the whole page after clicking on "next month" arrow
Describe the bug
basically, when clicking on the next/previous month buttons (image attached) reload is triggered (?!). The weird part is that it only happens on production, not locally.
To Reproduce
- Be sure to configure a CalendarDay field.
- Go to the Admin UI.
- Click on the next/previous month arrow.
Expected behavior
Clicking on one of the arrows will trigger an event that moving to the next/previous month.
Screenshots

System information
Happens on chrome. Using "@keystonejs/fields": "21.0.0",
Huge thanks.
It looks like there hasn't been any activity here in over 6 months. Sorry about that! We've flagged this issue for special attention. It wil be manually reviewed by maintainers, not automatically closed. If you have any additional information please leave us a comment. It really helps! Thank you for you contribution. :)
Reading the source code and managed to replicate the element but solving the error. I have solved I am using a custom input, to correct the refresh of the page when I change the month.
In any folder you want in my case server create a call CustomFields.
There I create a folder called CalendarDay with 3 files.
- Field.js
- Implementation.js
- index.js
Field.js
/** @jsx jsx */
/* eslint-disable react/react-in-jsx-scope, jsx-a11y/no-autofocus */
import { jsx } from '@emotion/core';
import 'react-day-picker/dist/style.css';
import { DayPicker } from "react-day-picker";
import { Input } from '@arch-ui/input';
import { Alert } from '@arch-ui/alert';
import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields';
import { parseISO, compareAsc, formatISO, isValid } from 'date-fns';
const CalendarDayField = ({ autoFocus, field, value, errors, onChange, isDisabled }) => {
const htmlID = `ks-daypicker-${field.path}`;
const handleDayClick = day => onChange(formatISO(day, { representation: 'date' }));
return (
<FieldContainer>
<FieldLabel htmlFor={htmlID} field={field} errors={errors} />
<FieldDescription text={field.adminDoc} />
<FieldInput>
<DayPicker
disabled={[
day =>
isDisabled ||
(field.config.dateTo && compareAsc(day, parseISO(field.config.dateTo)) === 1) ||
(field.config.dateTo && compareAsc(parseISO(field.config.dateFrom), day) === 1),
]}
selected={isValid(parseISO(value)) ? parseISO(value) : undefined}
defaultMonth={isValid(parseISO(value)) ? parseISO(value) : undefined}
onDayClick={handleDayClick}
/>
</FieldInput>
<FieldInput>
<Input
id={htmlID}
autoFocus={autoFocus}
onKeyDown={e => {
// There is a strange bug where after interacting with the day picker
// and then pressing enter on the input the value is changed to the start
// of the month. I think this is bug with the day picker.
// The following is a work-around:
if (e.key === 'Enter') {
e.preventDefault();
}
}}
onChange={e => {
// Tiny bit of date format normalisation for convenience
const normalisedValue = e.target.value.replace('/', '-').replace('\\', '-');
const parsedValue = parseISO(normalisedValue);
if (normalisedValue.length === 10 && isValid(parsedValue)) {
handleDayClick(parsedValue);
} else {
onChange(normalisedValue);
}
}}
disabled={isDisabled}
css={{ color: isValid(parseISO(value)) ? undefined : 'darkred' }}
value={value}
/>
</FieldInput>
{errors.map(({ message, data }) => (
<Alert appearance="danger" key={message}>
{message}
{data ? ` - ${JSON.stringify(data)}` : null}
</Alert>
))}
</FieldContainer>
);
};
export default CalendarDayField;
Implementation.js
const { CalendarDay } = require('@keystonejs/fields');
// Using the text implementation because we're going to stringify the array of results.
// We could store this in another table, but this would require writing a complex controller.
// JSON.stringify feels good enough for this simple field.
module.exports = {
Implementation: CalendarDay.implementation,
MongoIntegerInterface: CalendarDay.adapters.mongoose,
KnexIntegerInterface: CalendarDay.adapters.knex,
};
index.js
const { Implementation, MongoIntegerInterface, KnexIntegerInterface } = require('./Implementation');
module.exports = {
type: 'CustomCalendarDay',
implementation: Implementation,
views: {
Controller: require.resolve('@keystonejs/fields/types/CalendarDay/views/Controller/dist/fields.cjs'),
Field: require.resolve('./Field'),
Filter: require.resolve('@keystonejs/fields/types/CalendarDay/views/Filter/dist/fields.cjs'),
Cell: require.resolve('@keystonejs/fields/types/CalendarDay/views/Cell/dist/fields.cjs'),
},
adapters: {
mongoose: MongoIntegerInterface,
knex: KnexIntegerInterface,
},
};
Now use in Models
const CalendarDay = require('../server/CustomField/CalendarDay')
module.exports = {
fields: {
date: {
type: CalendarDay
}
}
};
NOTE: Install "react-day-picker": "8.0.0-beta.37" from npm install [email protected]