Skip to content

Commit

Permalink
Migrate LocationSearchForm to Final Form
Browse files Browse the repository at this point in the history
  • Loading branch information
lyyder committed May 23, 2018
1 parent feb8f79 commit c84538a
Showing 1 changed file with 46 additions and 32 deletions.
78 changes: 46 additions & 32 deletions src/forms/LocationSearchForm/LocationSearchForm.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,73 @@
import React from 'react';
import PropTypes from 'prop-types';
import { func, string } from 'prop-types';
import { compose } from 'redux';
import { Field, reduxForm, propTypes as formPropTypes } from 'redux-form';
import { Form as FinalForm, Field } from 'react-final-form';
import { intlShape, injectIntl } from 'react-intl';
import classNames from 'classnames';
import { Form, LocationAutocompleteInput } from '../../components';

import css from './LocationSearchForm.css';

const LocationSearchFormComponent = props => {
const { rootClassName, className, intl, onSubmit } = props;

const onChange = location => {
const handleChange = location => {
if (location.selectedPlace) {
// Note that we use `onSubmit` instead of the conventional
// `handleSubmit` prop for submitting. We want to autosubmit
// when a place is selected, and don't require any extra
// validations for the form.
onSubmit({ location });
props.onSubmit({ location });
}
};

const classes = classNames(rootClassName || css.root, className);
return (
<FinalForm
{...props}
render={({ rootClassName, className, intl, handleSubmit }) => {
const classes = classNames(rootClassName || css.root, className);

// Allow form submit only when the place has changed
const preventFormSubmit = e => e.preventDefault();

// Allow form submit only when the place has changed
const preventFormSubmit = e => e.preventDefault();
return (
<Form className={classes} onSubmit={preventFormSubmit}>
<Field
name="location"
format={null}
render={({ input, meta }) => {
const { onChange, ...restInput } = input;

return (
<Form className={classes} onSubmit={preventFormSubmit}>
<Field
name="location"
label="Location"
placeholder={intl.formatMessage({ id: 'LocationSearchForm.placeholder' })}
format={null}
component={LocationAutocompleteInput}
iconClassName={css.searchInputIcon}
inputClassName={css.searchInput}
predictionsClassName={css.searchPredictions}
onChange={onChange}
/>
</Form>
// Merge the standard onChange function with custom behaviur. A better solution would
// be to use the FormSpy component from Final Form and pass this.onChange to the
// onChange prop but that breaks due to insufficient subscription handling.
// See: https://github.com/final-form/react-final-form/issues/159
const searchOnChange = value => {
onChange(value);
handleChange(value);
};

const searchInput = { ...restInput, onChange: searchOnChange };
return (
<LocationAutocompleteInput
placeholder={intl.formatMessage({ id: 'LocationSearchForm.placeholder' })}
iconClassName={css.searchInputIcon}
inputClassName={css.searchInput}
predictionsClassName={css.searchPredictions}
input={searchInput}
meta={meta}
/>
);
}}
/>
</Form>
);
}}
/>
);
};

const { func, string } = PropTypes;

LocationSearchFormComponent.defaultProps = { rootClassName: null, className: null };

LocationSearchFormComponent.propTypes = {
...formPropTypes,

rootClassName: string,
className: string,
onSubmit: func.isRequired,
Expand All @@ -58,10 +76,6 @@ LocationSearchFormComponent.propTypes = {
intl: intlShape.isRequired,
};

const defaultFormName = 'TopbarSearchForm';

const LocationSearchForm = compose(reduxForm({ form: defaultFormName }), injectIntl)(
LocationSearchFormComponent
);
const LocationSearchForm = compose(injectIntl)(LocationSearchFormComponent);

export default LocationSearchForm;

0 comments on commit c84538a

Please sign in to comment.