Skip to content

Commit 92407d5

Browse files
author
Parth Shah
committed
adding support for formsy forms, custom form components should be deprecated
1 parent 534268a commit 92407d5

19 files changed

+788
-10
lines changed

components/FilePicker/FilePicker.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,18 @@ class FilePicker extends React.Component {
1616
const filepickerElement = this.refs.filepicker
1717
filepicker.setKey(this.props.apiKey)
1818
filepicker.constructWidget(filepickerElement)
19-
filepickerElement.addEventListener('change', this.onChange, false);
19+
filepickerElement.addEventListener('change', this.onChange, false)
2020
}
2121

2222
componentWillUnmount() {
23-
this.refs.filepicker.removeEventListener('change', this.onChange, false);
23+
this.refs.filepicker.removeEventListener('change', this.onChange, false)
2424
}
2525

2626
render() {
27-
const { apiKey, onSuccess, mode, options } = this.props
28-
const element = this.refs.target
27+
const { mode, options } = this.props
2928

3029
// add data-fp- prefix to all keys
31-
const opts = _.mapKeys(options, (v,k) => {
30+
const opts = _.mapKeys(options, (v, k) => {
3231
const hyphenated = k.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase()
3332
return `data-fp-${hyphenated}`
3433
})

components/Forms/BaseInputField.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
import React, { Component, PropTypes } from 'react'
3+
import { Component, PropTypes } from 'react'
44
import _ from 'lodash'
55

66
/**
@@ -62,8 +62,8 @@ BaseInputField.propTypes = {
6262
}
6363
BaseInputField.defaultProps = {
6464
value: '',
65-
onFieldChange: () => {},
66-
validateField: () => {}
65+
// onFieldChange: () => {},
66+
validateField: () => { return { hasError: false, errorMessage: null }}
6767
}
6868

6969

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict'
2+
3+
import React, { PropTypes } from 'react'
4+
import _ from 'lodash'
5+
import classNames from 'classnames'
6+
import BaseInputField from './BaseInputField'
7+
8+
const CheckboxInput = ({index, name, label, value, selectedValue}) => {
9+
const id = [name, 'option', index].join('-')
10+
return (
11+
<div>
12+
<div className="tc-checkbox">
13+
<input id={id} type="checkbox" value={value} checked={value === selectedValue} />
14+
<label htmlFor={id}/>
15+
</div>
16+
<label className="tc-checkbox-label" htmlFor={id}>{label}</label>
17+
</div>
18+
)
19+
}
20+
21+
class CheckboxGroupInput extends BaseInputField {
22+
constructor(props) {
23+
super(props)
24+
this.onChange = this.onChange.bind(this)
25+
}
26+
render() {
27+
const { label, name, wrapperClass} = this.props
28+
const { value, valid, dirty, errorMessage } = this.state
29+
const hasError = dirty && !valid
30+
const renderOption = (opt, idx) => {
31+
return (
32+
<CheckboxInput
33+
key={idx}
34+
index={idx}
35+
name={name}
36+
label={opt.label}
37+
value={opt.value}
38+
selectedValue={value}
39+
onChange={ this.onChange }
40+
/>
41+
)
42+
}
43+
const wrapperClasses = classNames(wrapperClass, 'checkbox-group-input')
44+
return (
45+
<div className={ wrapperClasses }>
46+
<label className="checkbox-group-label">{label}</label>
47+
<div className="checkbox-group-options">{this.props.options.map(renderOption)}</div>
48+
{ hasError ? (<p className="error-message">{errorMessage}</p>) : null}
49+
</div>
50+
)
51+
}
52+
}
53+
CheckboxGroupInput.displayName = 'CheckboxGroupInputField'
54+
CheckboxGroupInput.propTypes = _.assign({}, CheckboxGroupInput.propTypes, {
55+
options: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired
56+
})
57+
58+
export default CheckboxGroupInput

components/Forms/CheckboxInput.jsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict'
2+
3+
import React, { PropTypes } from 'react'
4+
import BaseInputField from './BaseInputField'
5+
import _ from 'lodash'
6+
7+
class CheckboxInput extends BaseInputField {
8+
render() {
9+
const { name, index, label, ...rest } = this.props
10+
const id = [name, 'option', index].join('-')
11+
return (
12+
<div className="checkbox-group-item">
13+
<div className="tc-checkbox">
14+
<input id={id} type="checkbox" {...rest} />
15+
<label htmlFor={id}/>
16+
</div>
17+
<label className="tc-checkbox-label" htmlFor={id}>{label}</label>
18+
</div>
19+
)
20+
}
21+
}
22+
23+
24+
CheckboxInput.displayName = 'CheckboxInputField'
25+
CheckboxInput.propTypes = _.assign({}, CheckboxInput.propTypes, {
26+
label: PropTypes.string.isRequired,
27+
value: PropTypes.any.isRequired
28+
})
29+
30+
export default CheckboxInput

components/Forms/Fields.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import TextInput from './TextInput'
55
import TextareaInput from './TextareaInput'
66
import RadioGroupInput from './RadioGroupInput'
77
import RadioButton from './RadioButton'
8+
import CheckboxInput from './CheckboxInput'
9+
import CheckboxGroupInput from './CheckboxGroupInput'
810
import SliderRadioGroupInput from './SliderRadioGroupInput'
911
import TiledCheckboxInput from './TiledCheckboxInput'
1012

@@ -16,6 +18,8 @@ export default {
1618
TextareaInput,
1719
RadioGroupInput,
1820
RadioButton,
21+
CheckboxInput,
22+
CheckboxGroupInput,
1923
SliderRadioGroupInput,
2024
TiledCheckboxInput
2125
}

components/Forms/Form.jsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class Form extends React.Component {
2424

2525
constructor(props) {
2626
super(props)
27-
2827
this.init = this.init.bind(this)
2928
}
3029

@@ -48,6 +47,12 @@ class Form extends React.Component {
4847
})
4948
}
5049

50+
51+
updateData(data) {
52+
// TODO should re-perform validations
53+
this.setState(_.assign({}, this.state, { dirty: true, formValue: data}))
54+
}
55+
5156
onSubmit(event) {
5257
event.preventDefault()
5358
this.props.onSubmit(this.state.formValue)
@@ -87,6 +92,9 @@ class Form extends React.Component {
8792
dirty: true
8893
})
8994
this.setState(newState)
95+
// call onChange callback if provided
96+
if (this.props.onChange)
97+
this.props.onChange(fieldName, fieldValue, newState)
9098
}
9199

92100
recursiveCloneChildren(children, disableOnPristine) {
@@ -132,6 +140,7 @@ class Form extends React.Component {
132140
return child
133141
})
134142
}
143+
135144
render() {
136145
const { disableOnPristine } = this.props
137146
return (<form>{this.recursiveCloneChildren(this.props.children, disableOnPristine)}</form>)

components/Forms/FormFields.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ textarea{
111111
}
112112
}
113113

114+
.checkbox-group-input {
115+
}
116+
.checkbox-group-item {
117+
display: inline-block;
118+
margin-right: 42px;
119+
label {
120+
@include roboto-bold;
121+
color: $tc-gray-80;
122+
margin-right: 0;
123+
}
124+
}
125+
114126
.radio-group-input {
115127
.radio-group-label {
116128
@include tc-label-md;

components/Forms/RadioGroupInput.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
import React, { Component, PropTypes } from 'react'
3+
import React, { PropTypes } from 'react'
44
import _ from 'lodash'
55
import classNames from 'classnames'
66
import BaseInputField from './BaseInputField'

components/Formsy/Checkbox.jsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { Component } from 'react'
2+
import { HOC as hoc } from 'formsy-react'
3+
import classNames from 'classnames'
4+
5+
class Checkbox extends Component {
6+
7+
constructor(props) {
8+
super(props)
9+
this.changeValue = this.changeValue.bind(this)
10+
}
11+
12+
changeValue(e) {
13+
const value = e.target.checked
14+
this.props.setValue(value)
15+
this.props.onChange(this.props.name, value)
16+
}
17+
18+
render() {
19+
const { label, name } = this.props
20+
const hasError = !this.props.isPristine() && !this.props.isValid()
21+
const classes = classNames('tc-checkbox', {error: hasError})
22+
const disabled = this.props.isFormDisabled() || this.props.disabled
23+
const errorMessage = this.props.getErrorMessage() || this.props.validationError
24+
const setRef = (c) => this.element = c
25+
26+
return (
27+
<div className="checkbox-group-item">
28+
<div className={classes}>
29+
<input
30+
id={name}
31+
ref={setRef}
32+
type="checkbox"
33+
name={name}
34+
checked={this.props.getValue() === true}
35+
disabled={disabled}
36+
onChange={this.changeValue}
37+
/>
38+
<label htmlFor={name}/>
39+
</div>
40+
<label className="tc-checkbox-label" htmlFor={name}>{label}</label>
41+
{ hasError ? (<p className="error-message">{errorMessage}</p>) : null}
42+
</div>
43+
)
44+
}
45+
}
46+
47+
Checkbox.defaultProps = {
48+
onChange: () => {}
49+
}
50+
51+
export default hoc(Checkbox)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { HOC as hoc } from 'formsy-react'
3+
import cn from 'classnames'
4+
5+
class CheckboxGroup extends Component {
6+
7+
constructor(props) {
8+
super(props)
9+
this.changeValue = this.changeValue.bind(this)
10+
}
11+
12+
changeValue() {
13+
const value = []
14+
this.props.options.forEach((option, key) => {
15+
if (this['element-' + key].checked) {
16+
value.push(option.value)
17+
}
18+
})
19+
this.props.setValue(value)
20+
this.props.onChange(this.props.name, value)
21+
}
22+
23+
render() {
24+
const { label, name, options } = this.props
25+
const hasError = !this.props.isPristine() && !this.props.isValid()
26+
const disabled = this.props.isFormDisabled() || this.props.disabled
27+
const errorMessage = this.props.getErrorMessage() || this.props.validationError
28+
29+
const renderOption = (cb, key) => {
30+
const curValue = this.props.getValue() || []
31+
const checked = curValue.indexOf(cb.value) !== -1
32+
const disabled = this.props.isFormDisabled() || cb.disabled || this.props.disabled
33+
const rClass = cn('checkbox-group-item', { disabled })
34+
const id = name+'-opt-'+key
35+
const setRef = (c) => this['element-' + key] = c
36+
return (
37+
<div className={rClass} key={key}>
38+
<div className="tc-checkbox">
39+
<input
40+
id={id}
41+
ref={setRef}
42+
type="checkbox"
43+
name={name}
44+
checked={checked}
45+
disabled={disabled}
46+
onChange={this.changeValue}
47+
/>
48+
<label htmlFor={id}/>
49+
</div>
50+
<label className="tc-checkbox-label" htmlFor={id}>{cb.label}</label>
51+
</div>
52+
)
53+
}
54+
55+
return (
56+
<div>
57+
<label className="checkbox-group-label">{label}</label>
58+
<div className="checkbox-group-options">{options.map(renderOption)}</div>
59+
{ hasError ? (<p className="error-message">{errorMessage}</p>) : null}
60+
</div>
61+
)
62+
}
63+
}
64+
65+
CheckboxGroup.PropTypes = {
66+
options: PropTypes.arrayOf(PropTypes.object).isRequired
67+
}
68+
69+
CheckboxGroup.defaultProps = {
70+
onChange: () => {}
71+
}
72+
73+
export default hoc(CheckboxGroup)

0 commit comments

Comments
 (0)