-
-
Save AoDev/f1f490b50927ed03c357 to your computer and use it in GitHub Desktop.
Handling forms in React with Mobx observables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react' | |
import PersonForm from './PersonForm' | |
import {observable} from 'mobx' | |
import personData from '../data/person' | |
export default class App extends Component { | |
constructor (props) { | |
super(props) | |
this.person = observable(personData) | |
} | |
render () { | |
return ( | |
<div className="container"> | |
<h1>Handling forms in React with Mobx</h1> | |
<hr/> | |
<PersonForm person={this.person}/> | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* asForm Higher Order Component | |
*/ | |
import React, {Component} from 'react' | |
export default function asForm (MyComponent, formDataProp) { | |
return class Form extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props[formDataProp][key] = value | |
} | |
render () { | |
return <MyComponent {...this.props} updateProperty={this.updateProperty}/> | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
@observer | |
export default class InputCheckboxes extends Component { | |
constructor (props) { | |
super(props) | |
this.onChange = this.onChange.bind(this) | |
} | |
onChange (event) { | |
this.props.onChange(this.props.name, event.target.value) | |
} | |
render () { | |
const {items, name, checkedItems} = this.props | |
return ( | |
<div className="form-group"> | |
<b>{name}</b> | |
{ | |
items.map((item) => { | |
return ( | |
<div className="checkbox" key={`${name}-${item}`}> | |
<label htmlFor={`${name}-${item}`}> | |
<input type="checkbox" name={`${name}`} value={item} id={`${name}-${item}`} | |
checked={checkedItems.indexOf(item) > -1} | |
onChange={this.onChange}/> {item} | |
</label> | |
</div> | |
) | |
}) | |
} | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
@observer | |
export default class InputField extends Component { | |
constructor (props) { | |
super(props) | |
this.onChange = this.onChange.bind(this) | |
} | |
onChange (event) { | |
this.props.onChange(event.target.name, event.target.value) | |
} | |
render () { | |
const input = this.props | |
return ( | |
<div className="form-group"> | |
<label htmlFor={input.id}>{input.label || input.name}</label> | |
<input | |
className="form-control" | |
id={input.id} | |
name={input.name} | |
onChange={this.onChange} | |
type={input.type} | |
value={input.value}/> | |
</div> | |
) | |
} | |
} | |
InputField.propTypes = { | |
onChange: PropTypes.func.isRequired | |
} | |
InputField.defaultProps = { | |
type: 'text' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
import {InputField} from '../../components' | |
@observer | |
export default class PersonAddress extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props.address[key] = value | |
} | |
render () { | |
const {address} = this.props | |
return ( | |
<div> | |
<InputField id="address-city" name="city" value={address.city} onChange={this.updateProperty}/> | |
<InputField id="address-postal-code" name="postalCode" value={address.postalCode} onChange={this.updateProperty}/> | |
<InputField id="address-street" name="street" value={address.street} onChange={this.updateProperty}/> | |
</div> | |
) | |
} | |
} | |
PersonAddress.propTypes = { | |
address: PropTypes.shape({ | |
city: PropTypes.string, | |
postalCode: PropTypes.string, | |
street: PropTypes.string | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
import asForm from './asForm' | |
import InputText from './InputText' | |
@observer | |
class PersonAddress extends Component { | |
render () { | |
const {address, updateProperty} = this.props | |
return ( | |
<div> | |
<InputText id="address-city" name="city" value={address.city} onChange={updateProperty}/> | |
<InputText id="address-postal-code" name="postalCode" value={address.postalCode} onChange={updateProperty}/> | |
<InputText id="address-street" name="street" value={address.street} onChange={updateProperty}/> | |
</div> | |
) | |
} | |
} | |
PersonAddress.propTypes = { | |
address: PropTypes.shape({ | |
city: PropTypes.string, | |
postalCode: PropTypes.string, | |
street: PropTypes.string | |
}) | |
} | |
export default asForm(PersonAddress, 'address') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var person = { | |
fullName: 'John Doe', | |
job: 'Web Developer', | |
email: 'john.doe@example.com', | |
address: { | |
city: 'Budapest', | |
postalCode: '1000', | |
street: 'Reactive street' | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var person = { | |
fullName: 'John Doe', | |
address: { | |
city: 'Budapest', | |
postalCode: '1000', | |
street: 'Reactive street' | |
}, | |
tasks: [ | |
{ | |
id: 1, | |
name: 'Write the article about forms', | |
dueDate: 'yesterday' | |
}, | |
{ | |
id: 2, | |
name: 'Eat something', | |
dueDate: 'Now' | |
}, | |
{ | |
id: 3, | |
name: 'Go to sleep', | |
dueDate: 'Soon' | |
} | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
@observer | |
export default class PersonForm extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
this.onChange = this.onChange.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props.person[key] = value | |
} | |
onChange (event) { | |
this.updateProperty(event.target.name, event.target.value) | |
} | |
render () { | |
const {person} = this.props | |
return ( | |
<div> | |
<h1>My Person Form</h1> | |
<form> | |
<input type="text" name="fullName" value={person.fullName} onChange={this.onChange}/> | |
</form> | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
import {InputField} from '../../components' | |
@observer | |
export default class PersonForm extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props.person[key] = value | |
} | |
render () { | |
const {person} = this.props | |
return ( | |
<div> | |
<h1>My Person Form</h1> | |
<form> | |
<InputField name="fullName" value={person.fullName} onChange={this.updateProperty}/> | |
<InputField name="job" value={person.job} onChange={this.updateProperty}/> | |
<InputField name="email" value={person.email} onChange={this.updateProperty}/> | |
</form> | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
import PersonAddress from './PersonAddress' | |
import {InputField} from '../../components' | |
@observer | |
export default class PersonForm extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props.person[key] = value | |
} | |
render () { | |
const {person} = this.props | |
return ( | |
<div> | |
<h1>My Person Form</h1> | |
<form> | |
<InputField name="fullName" value={person.fullName} onChange={this.updateProperty}/> | |
<InputField name="job" value={person.job} onChange={this.updateProperty}/> | |
<InputField name="email" value={person.email} onChange={this.updateProperty}/> | |
<PersonAddress address={person.address} /> | |
</form> | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react' | |
import {observer} from 'mobx-react' | |
import PersonAddress from './PersonAddress' | |
import PersonTask from './PersonTask' | |
import {InputField} from '../../components' | |
@observer | |
export default class PersonForm extends Component { | |
constructor (props) { | |
super(props) | |
this.updateProperty = this.updateProperty.bind(this) | |
} | |
updateProperty (key, value) { | |
this.props.person[key] = value | |
} | |
render () { | |
const {person} = this.props | |
return ( | |
<div> | |
<h1>My Person Form</h1> | |
<form> | |
<InputField name="fullName" value={person.fullName} onChange={this.updateProperty}/> | |
<InputField name="job" value={person.job} onChange={this.updateProperty}/> | |
<InputField name="email" value={person.email} onChange={this.updateProperty}/> | |
<PersonAddress address={person.address} /> | |
{ | |
person.tasks | |
.map((task) => <PersonTask key={task.id} task={task} />) | |
} | |
</form> | |
</div> | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {observable} from 'mobx' | |
var person = observable({ | |
fullName: 'John Doe', | |
job: 'Web Developer', | |
email: 'john.doe@example.com', | |
address: { | |
city: 'Budapest', | |
postalCode: '1000', | |
street: 'Reactive street' | |
} | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
updateArray (key, value) { | |
const array = this.props[formDataProp][key] | |
const index = array.indexOf(value) | |
if (array.indexOf(value) > -1) { | |
array.splice(index, 1) | |
} else { | |
array.push(value) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment