Skip to content

Commit

Permalink
Fix date picker lostfocus validations. Add handling onInput for date …
Browse files Browse the repository at this point in the history
…picker
  • Loading branch information
tihonove committed Aug 30, 2017
1 parent 4b89c9f commit 4926028
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 66 deletions.
105 changes: 45 additions & 60 deletions docs/src/components/Pages/Examples/Editors/Editors.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,15 @@ import styled from 'styled-components';
import Input from 'retail-ui/components/Input';
import Button from 'retail-ui/components/Button';
import RadioGroup from 'retail-ui/components/RadioGroup';
import ComboBox from 'retail-ui/components/ComboBox';
import ComboBox from 'retail-ui/components/ComboBoxOld';
import Select from 'retail-ui/components/Select';
import DatePicker from 'retail-ui/components/DatePicker';
import Textarea from 'retail-ui/components/Textarea';
import Checkbox from 'retail-ui/components/Checkbox';
import Link from 'retail-ui/components/Link';
import { validation } from './ValidationBuilder';

import type {
ContactInfo,
ContactInfoValidationInfo,
FormEditorProps,
} from '../../../../Domain/ContactInfo';
import type { ContactInfo, ContactInfoValidationInfo, FormEditorProps } from '../../../../Domain/ContactInfo';

import Demo from '../../../Demo';
import Form from '../../../Form';
Expand All @@ -30,36 +26,22 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.
return (
<Form>
<Form.Line title='Имя'>
<ValidationWrapperV1
renderMessage={text()}
validationInfo={validationInfo.name}>
<Input
value={data.name}
onChange={(e, value) => onChange({ name: value })}
/>
<ValidationWrapperV1 renderMessage={text()} validationInfo={validationInfo.name}>
<Input value={data.name} onChange={(e, value) => onChange({ name: value })} />
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Email'>
<ValidationWrapperV1
validationInfo={validationInfo.email}>
<Input
value={data.email}
onChange={(e, value) => onChange({ email: value })}
/>
<ValidationWrapperV1 validationInfo={validationInfo.email}>
<Input value={data.email} onChange={(e, value) => onChange({ email: value })} />
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Телефон'>
<ValidationWrapperV1
validationInfo={validationInfo.phone}>
<Input
value={data.phone}
onChange={(e, value) => onChange({ phone: value })}
/>
<ValidationWrapperV1 validationInfo={validationInfo.phone}>
<Input value={data.phone} onChange={(e, value) => onChange({ phone: value })} />
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Пол'>
<ValidationWrapperV1
validationInfo={validationInfo.sex}>
<ValidationWrapperV1 validationInfo={validationInfo.sex}>
<RadioGroup
value={data.sex}
items={['male', 'female']}
Expand All @@ -69,8 +51,7 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Город'>
<ValidationWrapperV1
validationInfo={validationInfo.city}>
<ValidationWrapperV1 validationInfo={validationInfo.city}>
<ComboBox
valueToString={x => x}
renderValue={x => x}
Expand All @@ -79,9 +60,7 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.
value={data.city}
source={async query => {
const cities = ['City 1', 'City 2', 'City 3'];
const result = !query
? cities
: cities.filter(x => x.includes(query));
const result = !query ? cities : cities.filter(x => x.includes(query));
return {
values: result,
infos: result,
Expand All @@ -96,18 +75,19 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.
<Select
renderItem={x => x}
renderValue={x => x}
items={[['Православие', 'Православие'], ['Католичество', 'Католичество'], ['Мормонизм', 'Мормонизм']]}
items={[
['Православие', 'Православие'],
['Католичество', 'Католичество'],
['Мормонизм', 'Мормонизм'],
]}
value={data.confession}
onChange={(e, value) => onChange({ confession: value })}
/>
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Согласен'>
<ValidationWrapperV1 validationInfo={validationInfo.confirmed}>
<Checkbox
checked={data.confirmed}
onChange={(e, value) => onChange({ confirmed: value })}
/>
<Checkbox checked={data.confirmed} onChange={(e, value) => onChange({ confirmed: value })} />
</ValidationWrapperV1>
</Form.Line>

Expand All @@ -123,10 +103,7 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.

<Form.Line title='Дата рождения'>
<ValidationWrapperV1 validationInfo={validationInfo.born}>
<DatePicker
value={data.born}
onChange={(e, value) => onChange({ born: value })}
/>
<DatePicker value={data.born} onChange={(e, value) => onChange({ born: value })} />
</ValidationWrapperV1>
</Form.Line>
<Form.Line title='Сcылка'>
Expand All @@ -145,37 +122,43 @@ function FormEditor({ data, validationInfo, onChange }: FormEditorProps): React.
}

const LinkContainer = styled.span`
background-color: ${props => props.error ? '#FDE8E8' : 'transparent'}
background-color: ${props => (props.error ? '#FDE8E8' : 'transparent')}
padding: 1px 5px;
margin: -1px -5px;
`;


type Validate<T, U> = (data: T) => U;

const validate: Validate<ContactInfo, ContactInfoValidationInfo> = validation()
.property(x => x.name)
.required()
.satisfy(x => x.split(' ').length === 2, 'Имя должно состоять из двух слов')
.required()
.satisfy(x => x.split(' ').length === 2, 'Имя должно состоять из двух слов')
.property(x => x.email)
.required()
.satisfy(x => x.includes('@'), 'Почта указана неверно')
.required()
.satisfy(x => x.includes('@'), 'Почта указана неверно')
.property(x => x.phone)
.required()
.satisfy(
phone => phone !== '' && /^[\s\d\-\+\(\)]*$/.test(phone),
'Телефон должен состоять только из цифр, пробелов и знаков -,+,(,)')
.property(x => x.sex).required()
.property(x => x.city).required()
.property(x => x.confession).required()
.property(x => x.confirmed).satisfy(x => x, 'Надо соглашаться', 'submit')
.property(x => x.modalOpened).satisfy(x => x, 'Надо соглашаться', 'submit')
.property(x => x.about).required()
.required()
.satisfy(
phone => phone !== '' && /^[\s\d\-\+\(\)]*$/.test(phone),
'Телефон должен состоять только из цифр, пробелов и знаков -,+,(,)'
)
.property(x => x.sex)
.required()
.property(x => x.city)
.required()
.property(x => x.confession)
.required()
.property(x => x.confirmed)
.satisfy(x => x, 'Надо соглашаться', 'submit')
.property(x => x.modalOpened)
.satisfy(x => x, 'Надо соглашаться', 'submit')
.property(x => x.about)
.required()
.property(x => x.born)
.satisfy(x => x, 'Заполни', 'submit')
.satisfy(x => x, 'Заполни', 'submit')
.satisfy(x => x <= new Date(), 'Дата рождения должна находится в прошлом')
.build();


export default class Editors extends React.Component {
state = {
data: {
Expand Down Expand Up @@ -203,7 +186,9 @@ export default class Editors extends React.Component {
onChange={update => this.setState({ data: { ...this.state.data, ...update } })}
/>
<Form.ActionsBar>
<Button use='primary' onClick={() => this.handleSubmit()}>Сохранить</Button>
<Button use='primary' onClick={() => this.handleSubmit()}>
Сохранить
</Button>
</Form.ActionsBar>
</ValidationContainer>
</Demo>
Expand Down
19 changes: 13 additions & 6 deletions src/Behaviour/ValidationWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export default class ValidationWrapper extends React.Component {
validations.forEach((x, i) => this.processBlur(x, this.state.validationStates[i], i));
this.context.validationContext.instanceProcessBlur(this);
this.isChanging = false;
this.setState({});
}

async processSubmit(): Promise<void> {
Expand Down Expand Up @@ -168,18 +169,14 @@ export default class ValidationWrapper extends React.Component {
{ ...validationState, visible: true },
...validationStates.slice(index + 1),
];
this.setState({
validationStates: validationStates,
});
this.setState({ validationStates: validationStates });
} else if (!validation.error && (!validationStates[index] || validationStates[index].visible === true)) {
validationStates = [
...validationStates.slice(0, index),
{ ...validationState, visible: false },
...validationStates.slice(index + 1),
];
this.setState({
validationStates: validationStates,
});
this.setState({ validationStates: validationStates });
}
const isValid = !validationStates.find(x => x.visible);
this.context.validationContext.onValidationUpdated(this, isValid);
Expand Down Expand Up @@ -265,6 +262,15 @@ export default class ValidationWrapper extends React.Component {
children.props.onBlur();
}
},
onInput: (...args) => {
if (ReactUiDetection.isDatePicker(children)) {
this.isChanging = true;
this.setState({});
}
if (children && children.props && children.props.onInput) {
children.props.onInput(...args);
}
},
onChange: (...args) => {
if (ReactUiDetection.isDatePicker(children)) {
const nextValue = args[1];
Expand All @@ -273,6 +279,7 @@ export default class ValidationWrapper extends React.Component {
!(nextValue == null && children.props.value == null)
) {
this.isChanging = true;
this.handleBlur();
}
} else {
this.isChanging = true;
Expand Down

0 comments on commit 4926028

Please sign in to comment.