refactor form to do validation right in component
This commit is contained in:
@ -37,22 +37,31 @@ const checkValidity = [
|
|||||||
'highlight'
|
'highlight'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function formatValue(value, validator, type = 'string') {
|
||||||
|
const formated = getDefaults(type);
|
||||||
|
if (validator && type === 'string') {
|
||||||
|
formated.valid = validator(value);
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
formated.value = value;
|
||||||
|
formated.bsStyle = formated.valid ? 'success' : 'error';
|
||||||
|
}
|
||||||
|
return formated;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidURL(data) {
|
||||||
|
return isURL(data, { 'require_protocol': true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidPhone(data) {
|
||||||
|
return isMobilePhone(data, 'en-US');
|
||||||
|
}
|
||||||
|
|
||||||
export default contain({
|
export default contain({
|
||||||
actions: 'jobActions',
|
actions: 'jobActions',
|
||||||
store: 'jobsStore',
|
store: 'jobsStore',
|
||||||
map({ form = {} }) {
|
map({ form = {} }) {
|
||||||
const {
|
const {
|
||||||
position = getDefaults('string'),
|
|
||||||
locale = getDefaults('string'),
|
|
||||||
description = getDefaults('string'),
|
|
||||||
email = getDefaults('string'),
|
|
||||||
phone = getDefaults('string'),
|
|
||||||
url = getDefaults('string'),
|
|
||||||
logo = getDefaults('string'),
|
|
||||||
name = getDefaults('string'),
|
|
||||||
highlight = getDefaults('bool')
|
|
||||||
} = form;
|
|
||||||
return {
|
|
||||||
position,
|
position,
|
||||||
locale,
|
locale,
|
||||||
description,
|
description,
|
||||||
@ -62,6 +71,17 @@ export default contain({
|
|||||||
logo,
|
logo,
|
||||||
name,
|
name,
|
||||||
highlight
|
highlight
|
||||||
|
} = form;
|
||||||
|
return {
|
||||||
|
position: formatValue(position, isAscii),
|
||||||
|
locale: formatValue(locale, isAscii),
|
||||||
|
description: formatValue(description, isAscii),
|
||||||
|
email: formatValue(email, isEmail),
|
||||||
|
phone: formatValue(phone, isValidPhone),
|
||||||
|
url: formatValue(url, isValidURL),
|
||||||
|
logo: formatValue(logo, isValidURL),
|
||||||
|
name: formatValue(name, isAscii),
|
||||||
|
highlight: formatValue(highlight, null, 'bool')
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
subscribeOnWillMount() {
|
subscribeOnWillMount() {
|
||||||
@ -86,11 +106,12 @@ export default contain({
|
|||||||
|
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
const props = this.props;
|
||||||
let valid = true;
|
let valid = true;
|
||||||
checkValidity.forEach((prop) => {
|
checkValidity.forEach((prop) => {
|
||||||
// if value exist, check if it is valid
|
// if value exist, check if it is valid
|
||||||
if (this.props[prop].value) {
|
if (props[prop].value && props[prop].type !== 'boolean') {
|
||||||
valid = valid && !!this.props[prop].valid;
|
valid = valid && !!props[prop].valid;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -141,9 +162,9 @@ export default contain({
|
|||||||
jobActions.getSavedForm();
|
jobActions.getSavedForm();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChange(name, validator, { target: { value } }) {
|
handleChange(name, { target: { value } }) {
|
||||||
const { jobActions: { handleForm } } = this.props;
|
const { jobActions: { handleForm } } = this.props;
|
||||||
handleForm({ name, value, validator });
|
handleForm({ [name]: value });
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -156,8 +177,10 @@ export default contain({
|
|||||||
url,
|
url,
|
||||||
logo,
|
logo,
|
||||||
name,
|
name,
|
||||||
highlight
|
highlight,
|
||||||
|
jobActions: { handleForm }
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const { handleChange } = this;
|
||||||
const labelClass = 'col-sm-offset-1 col-sm-2';
|
const labelClass = 'col-sm-offset-1 col-sm-2';
|
||||||
const inputClass = 'col-sm-6';
|
const inputClass = 'col-sm-6';
|
||||||
|
|
||||||
@ -178,13 +201,7 @@ export default contain({
|
|||||||
bsStyle={ position.bsStyle }
|
bsStyle={ position.bsStyle }
|
||||||
label='Position'
|
label='Position'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('position', e) }
|
||||||
this.handleChange(
|
|
||||||
'position',
|
|
||||||
isAscii,
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='Position'
|
placeholder='Position'
|
||||||
type='text'
|
type='text'
|
||||||
value={ position.value }
|
value={ position.value }
|
||||||
@ -193,13 +210,7 @@ export default contain({
|
|||||||
bsStyle={ locale.bsStyle }
|
bsStyle={ locale.bsStyle }
|
||||||
label='Location'
|
label='Location'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('locale', e) }
|
||||||
this.handleChange(
|
|
||||||
'locale',
|
|
||||||
isAscii,
|
|
||||||
e,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='Location'
|
placeholder='Location'
|
||||||
type='text'
|
type='text'
|
||||||
value={ locale.value }
|
value={ locale.value }
|
||||||
@ -208,13 +219,7 @@ export default contain({
|
|||||||
bsStyle={ description.bsStyle }
|
bsStyle={ description.bsStyle }
|
||||||
label='Description'
|
label='Description'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('description', e) }
|
||||||
this.handleChange(
|
|
||||||
'description',
|
|
||||||
isAscii,
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='Description'
|
placeholder='Description'
|
||||||
rows='10'
|
rows='10'
|
||||||
type='textarea'
|
type='textarea'
|
||||||
@ -228,13 +233,7 @@ export default contain({
|
|||||||
bsStyle={ name.bsStyle }
|
bsStyle={ name.bsStyle }
|
||||||
label='Company Name'
|
label='Company Name'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('name', e) }
|
||||||
this.handleChange(
|
|
||||||
'name',
|
|
||||||
isAscii,
|
|
||||||
e,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='Foo, INC'
|
placeholder='Foo, INC'
|
||||||
type='text'
|
type='text'
|
||||||
value={ name.value }
|
value={ name.value }
|
||||||
@ -243,13 +242,7 @@ export default contain({
|
|||||||
bsStyle={ email.bsStyle }
|
bsStyle={ email.bsStyle }
|
||||||
label='Email'
|
label='Email'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('email', e) }
|
||||||
this.handleChange(
|
|
||||||
'email',
|
|
||||||
isEmail,
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='Email'
|
placeholder='Email'
|
||||||
type='email'
|
type='email'
|
||||||
value={ email.value }
|
value={ email.value }
|
||||||
@ -258,13 +251,7 @@ export default contain({
|
|||||||
bsStyle={ phone.bsStyle }
|
bsStyle={ phone.bsStyle }
|
||||||
label='Phone'
|
label='Phone'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('phone', e) }
|
||||||
this.handleChange(
|
|
||||||
'phone',
|
|
||||||
(data) => isMobilePhone(data, 'en-US'),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='555-123-1234'
|
placeholder='555-123-1234'
|
||||||
type='tel'
|
type='tel'
|
||||||
value={ phone.value }
|
value={ phone.value }
|
||||||
@ -273,13 +260,7 @@ export default contain({
|
|||||||
bsStyle={ url.bsStyle }
|
bsStyle={ url.bsStyle }
|
||||||
label='URL'
|
label='URL'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('url', e) }
|
||||||
this.handleChange(
|
|
||||||
'url',
|
|
||||||
(data) => isURL(data, { 'require_protocol': true }),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='http://freecatphotoapp.com'
|
placeholder='http://freecatphotoapp.com'
|
||||||
type='url'
|
type='url'
|
||||||
value={ url.value }
|
value={ url.value }
|
||||||
@ -288,13 +269,7 @@ export default contain({
|
|||||||
bsStyle={ logo.bsStyle }
|
bsStyle={ logo.bsStyle }
|
||||||
label='Logo'
|
label='Logo'
|
||||||
labelClassName={ labelClass }
|
labelClassName={ labelClass }
|
||||||
onChange={ (e) => {
|
onChange={ (e) => handleChange('logo', e) }
|
||||||
this.handleChange(
|
|
||||||
'logo',
|
|
||||||
(data) => isURL(data, { 'require_protocol': true }),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
placeholder='http://freecatphotoapp.com/logo.png'
|
placeholder='http://freecatphotoapp.com/logo.png'
|
||||||
type='url'
|
type='url'
|
||||||
value={ logo.value }
|
value={ logo.value }
|
||||||
@ -304,17 +279,15 @@ export default contain({
|
|||||||
<h2>Make it stand out</h2>
|
<h2>Make it stand out</h2>
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
|
checked={ highlight.value }
|
||||||
label='Highlight your ad'
|
label='Highlight your ad'
|
||||||
labelClassName={ 'col-sm-offset-1 col-sm-6'}
|
labelClassName={ 'col-sm-offset-1 col-sm-6'}
|
||||||
onChange={ (e) => {
|
onChange={
|
||||||
this.handleChange(
|
({ target: { checked } }) => handleForm({
|
||||||
'highlight',
|
highlight: !!checked
|
||||||
() => { return true; },
|
})
|
||||||
e
|
}
|
||||||
);
|
type='checkbox' />
|
||||||
}}
|
|
||||||
type='checkbox'
|
|
||||||
value={ highlight.value } />
|
|
||||||
<div className='spacer' />
|
<div className='spacer' />
|
||||||
<Row>
|
<Row>
|
||||||
<Col
|
<Col
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Actions } from 'thundercats';
|
import { Actions } from 'thundercats';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import { getDefaults } from '../utils';
|
|
||||||
import debugFactory from 'debug';
|
import debugFactory from 'debug';
|
||||||
|
|
||||||
const debug = debugFactory('freecc:jobs:actions');
|
const debug = debugFactory('freecc:jobs:actions');
|
||||||
@ -41,32 +40,7 @@ export default Actions({
|
|||||||
closeModal() {
|
closeModal() {
|
||||||
return { showModal: false };
|
return { showModal: false };
|
||||||
},
|
},
|
||||||
handleForm({ name, value, validator = () => {} }) {
|
handleForm(value) {
|
||||||
if (!name) {
|
|
||||||
// operation noop
|
|
||||||
return { replace: null };
|
|
||||||
}
|
|
||||||
if (!validator(value)) {
|
|
||||||
return {
|
|
||||||
transform(oldState) {
|
|
||||||
const { form } = oldState;
|
|
||||||
const newState = assign({}, oldState);
|
|
||||||
newState.form = assign(
|
|
||||||
{},
|
|
||||||
form,
|
|
||||||
{
|
|
||||||
[name]: {
|
|
||||||
value,
|
|
||||||
valid: false,
|
|
||||||
pristine: false,
|
|
||||||
bsStyle: value ? 'error' : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
transform(oldState) {
|
transform(oldState) {
|
||||||
const { form } = oldState;
|
const { form } = oldState;
|
||||||
@ -74,14 +48,7 @@ export default Actions({
|
|||||||
newState.form = assign(
|
newState.form = assign(
|
||||||
{},
|
{},
|
||||||
form,
|
form,
|
||||||
{
|
value
|
||||||
[name]: {
|
|
||||||
value,
|
|
||||||
valid: true,
|
|
||||||
pristine: false,
|
|
||||||
bsStyle: value ? 'success' : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
@ -89,15 +56,7 @@ export default Actions({
|
|||||||
},
|
},
|
||||||
saveForm: null,
|
saveForm: null,
|
||||||
getSavedForm: null,
|
getSavedForm: null,
|
||||||
setForm(job) {
|
setForm(form) {
|
||||||
const form = Object.keys(job).reduce((accu, prop) => {
|
|
||||||
console.log('form', accu);
|
|
||||||
return Object.assign(
|
|
||||||
accu,
|
|
||||||
{ [prop]: getDefaults(typeof prop, job[prop]) }
|
|
||||||
);
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return { form };
|
return { form };
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -18,5 +18,5 @@ export function getDefaults(type, value) {
|
|||||||
if (value) {
|
if (value) {
|
||||||
return Object.assign({}, defaults[type], { value });
|
return Object.assign({}, defaults[type], { value });
|
||||||
}
|
}
|
||||||
return defaults[type];
|
return Object.assign({}, defaults[type]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user