Skip to content

Instantly share code, notes, and snippets.

@afbroman
Created July 8, 2019 14:32
Show Gist options
  • Save afbroman/9b31f3332b33ab33eeae74d9b36581e5 to your computer and use it in GitHub Desktop.
Save afbroman/9b31f3332b33ab33eeae74d9b36581e5 to your computer and use it in GitHub Desktop.
function validate(inputs) {
return {
name: inputs.name.length > 3 ? null : 'Company name should be longer than 3 characters',
shareholders: inputs.shareholders.map(shareholder => {
return {
name: shareholder.name.length > 3 ? null : 'Shareholder name should be longer than 3 characters',
shares: shareholder.shares > 0 ? null : 'Shareholder should have at least one share'
};
}),
}
}
class IncorporationForm extends React.Component {
constructor() {
super();
this.state = {
name: '',
shareholders: [{ name: '', shares: 0 }],
};
}
handleNameChange = (evt) => {
this.setState({ name: evt.target.value });
}
handleShareholderNameChange = (idx) => (evt) => {
const newShareholders = this.state.shareholders.map((shareholder, sidx) => {
if (idx !== sidx) return shareholder;
return { ...shareholder, name: evt.target.value };
});
this.setState({ shareholders: newShareholders });
}
handleShareholderSharesChange = (idx) => (evt) => {
const newShareholders = this.state.shareholders.map((shareholder, sidx) => {
if (idx !== sidx) return shareholder;
return { ...shareholder, shares: parseInt(evt.target.value || "0", 10) };
});
this.setState({ shareholders: newShareholders });
}
handleSubmit = (evt) => {
evt.preventDefault();
const { name, shareholders } = this.state;
alert(`Incorporated: ${name} with ${shareholders.length} shareholders`);
}
handleAddShareholder = () => {
this.setState({ shareholders: this.state.shareholders.concat([{ name: '', shares: 0 }]) });
}
handleRemoveShareholder = (idx) => () => {
this.setState({ shareholders: this.state.shareholders.filter((s, sidx) => idx !== sidx) });
}
render() {
const errors = validate({
name: this.state.name,
shareholders: this.state.shareholders,
});
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Company name, e.g. Magic Everywhere LLC"
value={this.state.name}
onChange={this.handleNameChange}
/>
{errors.name ? <p className="error-message">{errors.name}</p> : null}
<h4>Shareholders</h4>
{this.state.shareholders.map((shareholder, idx) => (
<div className="shareholder">
<div>
<label>
Shareholder #{idx + 1} name
<input
type="text"
placeholder={`#${idx + 1} name`}
value={shareholder.name}
onChange={this.handleShareholderNameChange(idx)}
/>
</label>
{errors.shareholders[idx].name ? <p className="error-message">{errors.shareholders[idx].name}</p> : null}
</div>
<div>
<label>
Shares
<input
type="text"
placeholder={`#${idx + 1} shares`}
value={shareholder.shares.toString()}
onChange={this.handleShareholderSharesChange(idx)}
/>
</label>
{errors.shareholders[idx].shares ? <p className="error-message">{errors.shareholders[idx].shares}</p> : null}
</div>
<button type="button" onClick={this.handleRemoveShareholder(idx)} className="small">-</button>
</div>
))}
<button type="button" onClick={this.handleAddShareholder} className="small">Add Shareholder</button>
<button>Incorporate</button>
</form>
)
}
}
ReactDOM.render(<IncorporationForm />, document.body);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment