EditListingForm: show validator errors

This commit is contained in:
Vesa Luusua 2017-03-08 16:11:11 +02:00
parent 0a003f5358
commit e09ea4b837
5 changed files with 91 additions and 34 deletions

View file

@ -0,0 +1,3 @@
.error {
color: red;
}

View file

@ -2,9 +2,36 @@ import React, { Component, PropTypes } from 'react';
import { Field, reduxForm, propTypes as formPropTypes } from 'redux-form';
import { intlShape, injectIntl } from 'react-intl';
import { maxLength, required } from '../../util/validators';
import css from './EditListingForm.css';
const MAX_LENGTH = 60;
const maxLength60 = maxLength(`Must be ${MAX_LENGTH} characters or less`, MAX_LENGTH);
const RenderField = ({ input, label, type, meta: { touched, error } }) => {
const component = type === 'textarea'
? <textarea {...input} placeholder={label} />
: <input {...input} placeholder={label} type={type} />;
return (
<div>
<label htmlFor={input.name}>{label}</label>
<div>
{component}
{touched && (error && <span className={css.error}>{error}</span>)}
</div>
</div>
)
};
const { any, bool, shape, string } = PropTypes;
RenderField.propTypes = {
input: any.isRequired,
label: string.isRequired,
type: string.isRequired,
meta: shape({
touched: bool,
error: string,
}).isRequired,
};
class EditListingForm extends Component {
componentDidMount() {
@ -20,21 +47,34 @@ class EditListingForm extends Component {
const {
disabled,
handleSubmit,
intl,
pristine,
saveActionMsg = 'Save listing',
submitting,
} = this.props;
const requiredStr = intl.formatMessage({ id: 'EditListingForm.required' });
const maxLengthStr = intl.formatMessage({ id: 'EditListingForm.maxLength' }, {
maxLength: MAX_LENGTH,
});
const maxLength60 = maxLength(maxLengthStr, MAX_LENGTH);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="title">Title</label>
<Field
name="title"
component="input"
label="Title"
component={RenderField}
type="text"
validate={[required('Required'), maxLength60]}
validate={[required(requiredStr), maxLength60]}
/>
<Field
name="description"
label="Description"
component={RenderField}
type="textarea"
validate={[required(requiredStr)]}
/>
<label htmlFor="description">Description</label>
<Field name="description" component="input" type="textarea" />
<button type="submit" disabled={pristine || submitting || disabled}>{saveActionMsg}</button>
</form>
);
@ -43,8 +83,6 @@ class EditListingForm extends Component {
EditListingForm.defaultProps = { initData: {} };
const { shape, string } = PropTypes;
EditListingForm.propTypes = {
...formPropTypes,
initData: shape({ title: string, description: string }),

View file

@ -1,32 +1,41 @@
exports[`EditListingForm matches snapshot 1`] = `
<form
onSubmit={[Function]}>
<label
htmlFor="title">
Title
</label>
<input
name="title"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
type="text"
value="" />
<label
htmlFor="description">
Description
</label>
<input
name="description"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
type="textarea"
value="" />
<div>
<label
htmlFor="title">
Title
</label>
<div>
<input
name="title"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
placeholder="Title"
type="text"
value="" />
</div>
</div>
<div>
<label
htmlFor="description">
Description
</label>
<div>
<textarea
name="description"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
placeholder="Description"
value="" />
</div>
</div>
<button
disabled={true}
type="submit">

View file

@ -49,3 +49,8 @@ button {
}
}
}
textarea {
width: 100%;
border: 1px solid #ddd;
}

View file

@ -5,6 +5,8 @@
"HeroSearchForm.search": "Search",
"HeroSection.subTitle": "The largest online community to rent music studios",
"HeroSection.title": "Book Studiotime anywhere",
"EditListingForm.required": "Required",
"EditListingForm.maxLength": "Must be {maxLength} characters or less",
"ListingPage.loadingListingData": "Loading listing data",
"ListingPage.noListingData": "Could not find listing data",
"PageLayout.authInfoFailed": "Could not get authentication information.",