One image is required. Show validation msg.

This commit is contained in:
Vesa Luusua 2017-03-13 16:46:24 +02:00
parent f97e9f5a89
commit 447943b1bf
5 changed files with 54 additions and 42 deletions

View file

@ -4,7 +4,7 @@
.imagesContainer {
width: 100%;
min-height: 150px;
min-height: 110px;
}
.addImageWrapper {
@ -59,3 +59,12 @@
justify-content: center;
align-items: center;
}
.imageRequiredWrapper {
width: 100%;
clear: both;
}
.imageRequiredError {
composes: error;
}

View file

@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
import { Field, reduxForm, propTypes as formPropTypes } from 'redux-form';
import { intlShape, injectIntl } from 'react-intl';
import { isEqual } from 'lodash';
import { maxLength, required } from '../../util/validators';
import { noEmptyArray, maxLength, required } from '../../util/validators';
import { Promised } from '../../components';
import css from './EditListingForm.css';
@ -57,17 +57,13 @@ RenderField.propTypes = {
// Add image wrapper. Label is the only visible element, file input is hidden.
const RenderAddImage = props => {
const { accept, input, label, type, meta } = props;
const { accept, input, label, type } = props;
const { name, onChange } = input;
const { touched, warning } = meta;
const inputProps = { accept, id: name, name, onChange, type };
return (
<div className={css.addImageWrapper}>
<input {...inputProps} style={{ display: 'none' }} />
<div>
<label htmlFor={name} className={css.addImage}>{label}</label>
{touched && warning ? <span className={css.warning}>{warning}</span> : null}
</div>
<label htmlFor={name} className={css.addImage}>{label}</label>
</div>
);
};
@ -81,10 +77,6 @@ RenderAddImage.propTypes = {
}).isRequired,
label: string.isRequired,
type: string.isRequired,
meta: shape({
touched: bool,
warning: string,
}).isRequired,
};
class EditListingForm extends Component {
@ -134,6 +126,7 @@ class EditListingForm extends Component {
},
);
const maxLength60 = maxLength(maxLengthStr, TITLE_MAX_LENGTH);
const imageRequiredStr = intl.formatMessage({ id: 'EditListingForm.imageRequired' });
return (
<form onSubmit={handleSubmit}>
@ -159,11 +152,7 @@ class EditListingForm extends Component {
renderFulfilled={dataURL => {
return (
<div className={css.thumbnail}>
<img
src={dataURL}
alt={encodeURIComponent(i.file.name)}
className={css.thumbnailImage}
/>
<img src={dataURL} alt={i.file.name} className={css.thumbnailImage} />
{uploadingOverlay}
</div>
);
@ -180,16 +169,24 @@ class EditListingForm extends Component {
onChange={this.onImageUploadHandler}
type="file"
/>
</div>
<Field
component={props => {
const { input, type } = props;
return <input {...input} type={type} />;
}}
name="images"
type="hidden"
/>
<Field
component={props => {
const { input, type, meta: { error, touched } } = props;
return (
<div className={css.imageRequiredWrapper}>
<input {...input} type={type} />
{touched && error
? <span className={css.imageRequiredError}>{error}</span>
: null}
</div>
);
}}
name="images"
type="hidden"
validate={[noEmptyArray(imageRequiredStr)]}
/>
</div>
<Field
name="description"

View file

@ -37,24 +37,25 @@ exports[`EditListingForm matches snapshot 1`] = `
}
}
type="file" />
<div>
<label
className={undefined}
htmlFor="addImage">
+ Add image
</label>
</div>
<label
className={undefined}
htmlFor="addImage">
+ Add image
</label>
</div>
<div
className={undefined}>
<input
name="images"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
type="hidden"
value="" />
</div>
</div>
<input
name="images"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
type="hidden"
value="" />
<div>
<label
htmlFor="description">

View file

@ -6,6 +6,7 @@
"HeroSection.subTitle": "The largest online community to rent music studios",
"HeroSection.title": "Book Studiotime anywhere",
"EditListingForm.required": "Required",
"EditListingForm.imageRequired": "You need to add at least one image.",
"EditListingForm.maxLength": "Must be {maxLength} characters or less",
"ListingPage.loadingListingData": "Loading listing data",
"ListingPage.noListingData": "Could not find listing data",

View file

@ -14,3 +14,7 @@ export const maxLength = (message, maximumLength) =>
value => {
return !value || value.length <= maximumLength ? VALID : message;
};
export const noEmptyArray = message => value => {
return value && Array.isArray(value) && value.length > 0 ? VALID : message;
};