Add images to form data

and update snapshot
and refactor
This commit is contained in:
Vesa Luusua 2017-03-10 09:45:22 +02:00
parent 0238dd38f8
commit 128f240c01
4 changed files with 50 additions and 20 deletions

View file

@ -1,6 +1,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 { Promised } from '../../components';
import css from './EditListingForm.css';
@ -17,9 +18,9 @@ const readImage = file => new Promise((resolve, reject) => {
reader.readAsDataURL(file);
});
// Custom inputs with validator messages
const RenderField = ({ input, label, type, meta: { touched, error } }) => {
const RenderField = ({ input, label, type, meta }) => {
const { touched, error } = meta;
const component = type === 'textarea'
? <textarea {...input} placeholder={label} />
: <input {...input} placeholder={label} type={type} />;
@ -28,16 +29,19 @@ const RenderField = ({ input, label, type, meta: { touched, error } }) => {
<label htmlFor={input.name}>{label}</label>
<div>
{component}
{touched && (error && <span className={css.error}>{error}</span>)}
{touched && error ? <span className={css.error}>{error}</span> : null}
</div>
</div>
);
};
const { any, bool, shape, string } = PropTypes;
const { bool, func, object, shape, string } = PropTypes;
RenderField.propTypes = {
input: any.isRequired,
input: shape({
onChange: func.isRequired,
name: string.isRequired,
}).isRequired,
label: string.isRequired,
type: string.isRequired,
meta: shape({
@ -48,17 +52,16 @@ RenderField.propTypes = {
// Add image wrapper. Label is the only visible element, file input is hidden.
const RenderAddImage = props => {
const { accept, input: {name, onChange}, label, type, meta: { touched, warning } } = props;
const { accept, input, label, type, meta } = 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' }}
/>
<input {...inputProps} style={{ display: 'none' }} />
<div>
<label htmlFor={name} className={css.addImage}>{label}</label>
{touched && (warning && <span className={css.warning}>{warning}</span>)}
{touched && warning ? <span className={css.warning}>{warning}</span> : null}
</div>
</div>
);
@ -66,7 +69,11 @@ const RenderAddImage = props => {
RenderAddImage.propTypes = {
accept: string.isRequired,
input: any.isRequired,
input: shape({
value: object,
onChange: func.isRequired,
name: string.isRequired,
}).isRequired,
label: string.isRequired,
type: string.isRequired,
meta: shape({
@ -82,6 +89,12 @@ class EditListingForm extends Component {
this.onImageUploadHandler = this.onImageUploadHandler.bind(this);
}
componentWillReceiveProps(nextProps) {
if (!isEqual(this.props.images, nextProps.images)) {
nextProps.change('images', nextProps.images);
}
}
componentDidMount() {
this.handleInitialize();
}
@ -156,6 +169,15 @@ class EditListingForm extends Component {
/>
</div>
<Field
component={props => {
const { input, type } = props;
return <input {...input} type={type} />;
}}
name="images"
type="hidden"
/>
<Field
name="description"
label="Description"

View file

@ -46,6 +46,15 @@ exports[`EditListingForm matches snapshot 1`] = `
</div>
</div>
</div>
<input
name="images"
onBlur={[Function]}
onChange={[Function]}
onDragStart={[Function]}
onDrop={[Function]}
onFocus={[Function]}
type="hidden"
value="" />
<div>
<label
htmlFor="description">

View file

@ -78,7 +78,7 @@ export default function reducer(state = initialState, action = {}) {
const { file } = state.images[id];
const images = {
...state.images,
[id]: { id, file, error, imageId: null, uploadImageError: true },
[id]: { id, file, imageId: null, uploadImageError: error },
};
return { ...state, images };
}

View file

@ -21,11 +21,15 @@ const formatRequestData = values => {
lat: 40.6,
lng: 73.9,
},
images,
images: images.map(i => i.imageId),
title,
};
};
const onSubmit = submitListing => {
return values => submitListing(values);
};
// N.B. All the presentational content needs to be extracted to their own components
export class EditListingPageComponent extends Component {
componentDidMount() {
@ -35,12 +39,7 @@ export class EditListingPageComponent extends Component {
}
onSubmit(submitListing) {
const { page } = this.props;
const images = page.imageOrder.map(i => page.images[i].imageId);
// When form is submitted we include images in correct order along with submitted values
// TODO figure out a way to attach images to form (e.g. into some hidden input)
return values => submitListing({ ...values, images });
return values => submitListing(values);
}
render() {