Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CalendarDay field is causing reload (refresh) of the whole page after clicking on "next month" arrow #355

Open
Yair-Ohana opened this issue Apr 13, 2021 · 2 comments

Comments

@Yair-Ohana
Copy link

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

  1. Be sure to configure a CalendarDay field.
  2. Go to the Admin UI.
  3. 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

image

System information

Happens on chrome.
Using "@keystonejs/fields": "21.0.0",

Huge thanks.

@stale
Copy link

stale bot commented Sep 11, 2021

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. :)

@emmatown emmatown transferred this issue from keystonejs/keystone Nov 16, 2021
@Brandyweb
Copy link

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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants