Skip to content

Instantly share code, notes, and snippets.

@insin
Last active May 30, 2023 19:55
Show Gist options
  • Save insin/407de6bb93dfe077433f to your computer and use it in GitHub Desktop.
Save insin/407de6bb93dfe077433f to your computer and use it in GitHub Desktop.

Instructions

  • Either:
    • git clone https://gist.github.com/407de6bb93dfe077433f.git EmailList
    • or download and extract this Gist
  • Run npm install
  • Run npm start, wait for webpack: bundle is now VALID and open http://localhost:3000

Changes made while the server is running will be hot reloaded.

require('array.prototype.fill')
var React = require('react')
var EmailList = require('./EmailList')
var App = React.createClass({
render() {
return <div className="App">
<EmailList quantity={5}/>
</div>
}
})
module.exports = App
.EmailList__email {
margin-bottom: .5em;
}
.EmailList__email--invalid {
outline: 1px solid #f00;
}
require('./EmailList.css')
var React = require('react')
var update = require('react/lib/update')
var classNames = require('classnames')
var DEFAULT_FIELD = {value: '', touched: false, valid: null}
var EMAIL_RE = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i
var EmailList = React.createClass({
propTypes: {
quantity: React.PropTypes.number.isRequired
},
getInitialState() {
return {
fields: Array(this.props.quantity).fill(DEFAULT_FIELD)
}
},
componentWillReceiveProps(nextProps) {
var {quantity} = this.props
var {quantity: nextQuantity} = nextProps
var {fields} = this.state
if (nextQuantity < quantity) {
this.setState({
fields: fields.slice(0, nextQuantity)
})
}
else if (nextQuantity > quantity) {
this.setState({
fields: fields.concat(Array(nextQuantity - quantity).fill(DEFAULT_FIELD))
})
}
},
handleChange(index, event) {
this.setState({
fields: update(this.state.fields, {
[index]: {
value: {$set: event.target.value},
touched: {$set: true}
}
})
})
},
handleBlur(index) {
var field = this.state.fields[index]
if (field.touched) {
this.setState({
fields: update(this.state.fields, {
[index]: {
valid: {$set: EMAIL_RE.test(field.value)}
}
})
})
}
},
render() {
var {fields} = this.state
return <ol className="EmailList">
{fields.map((field, index) => <li>
<input className={classNames('EmailList__email', {
'EmailList__email--invalid': field.valid === false
})}
key={index}
value={field.value}
placeholder="Email Address"
onChange={this.handleChange.bind(this, index)}
onBlur={this.handleBlur.bind(this, index)} />
</li>)}
</ol>
}
});
module.exports = EmailList
{
"scripts": {
"start": "heatpack App.js"
},
"dependencies": {
"array.prototype.fill": "^1.0.1",
"classnames": "^2.1.3",
"react": "^0.13.3"
},
"devDependencies": {
"react-heatpack": "^1.2.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment