-
-
Save gradosevic/a10d3e9c6ad522213effc597e994d279 to your computer and use it in GitHub Desktop.
React Form Handling - handleFormInputChange (Live version: http://bl.ocks.org/insin/raw/082c0d88f6290a0ea4c7/)
This file contains 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 INPUT_TYPES = 'color|date|datetime|datetime-local|file|month|number|password|range|search|tel|text|time|url|week'.split('|') | |
var App = React.createClass({ | |
getInitialState: function() { | |
return {} | |
}, | |
onChange: handleFormInputChange, | |
render: function() { | |
return <form className="pure-form pure-form-stacked" onChange={this.onChange}> | |
<div className="pure-control-group"> | |
<input name="input" placeholder="input"/> | |
</div> | |
{INPUT_TYPES.map(function(type) { | |
var name = 'input[' + type + ']' | |
return <div className="pure-control-group"> | |
<input type={type} name={name} placeholder={name}/> | |
</div> | |
}.bind(this))} | |
<div className="pure-control-group"> | |
<textarea name="textarea" placeholder="textarea"></textarea> | |
</div> | |
<div className="pure-control-group"> | |
<label className="pure-checkbox"> | |
<input type="checkbox" name="checkbox"/> Single checkbox | |
</label> | |
</div> | |
<div className="pure-control-group"> | |
<label className="pure-checkbox"> | |
<input type="checkbox" name="checkbox-multiple" value="1"/> Multi-checkbox 1 | |
</label> | |
<label className="pure-checkbox"> | |
<input type="checkbox" name="checkbox-multiple" value="2"/> Multi-checkbox 2 | |
</label> | |
<label className="pure-checkbox"> | |
<input type="checkbox" name="checkbox-multiple" value="3"/> Multi-checkbox 3 | |
</label> | |
</div> | |
<div className="pure-control-group"> | |
<label className="pure-radio"> | |
<input type="radio" name="radio" value="1"/> Radio 1 | |
</label> | |
<label className="pure-radio"> | |
<input type="radio" name="radio" value="2"/> Radio 2 | |
</label> | |
</div> | |
<div className="pure-control-group"> | |
<select name="select-one"> | |
<option value="1">1</option> | |
<option value="2">2</option> | |
<option value="3">3</option> | |
<option value="4">4</option> | |
<option value="5">5</option> | |
<option value="6">6</option> | |
</select> | |
</div> | |
<div className="pure-control-group"> | |
<select name="select-multiple" multiple> | |
<option value="1">1</option> | |
<option value="2">2</option> | |
<option value="3">3</option> | |
<option value="4">4</option> | |
<option value="5">5</option> | |
<option value="6">6</option> | |
</select> | |
</div> | |
<pre>this.state: {JSON.stringify(this.state, null, 2)}</pre> | |
</form> | |
} | |
}) | |
React.render(<App/>, document.getElementById('app')) |
This file contains 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
/* | |
Assumptions | |
----------- | |
These aren't prescriptive, they're just a log of the decisions that had to be | |
made when writing the code below: | |
* User input maps directly to context component state by name | |
* State for the following inputs which represent multiple values with the same | |
name is an Array of Strings: | |
* Multiple selects | |
* Checkbox groups | |
* If a checkbox is not part of a same-named group, its state is Boolean | |
* The user agent implements/has: | |
* Array.isArray() | |
* Array.prototype.indexOf() | |
* RadioNodeList, NodeList or HTMLCollection type for same-named inputs in form.elements | |
*/ | |
function handleFormInputChange(e) { | |
var el = e.target | |
var name = el.name | |
var type = el.type | |
var stateChange = {} | |
if (type == 'select-multiple') { | |
var selectedOptions = [] | |
for (var i = 0, l = el.options.length; i < l; i++) { | |
if (el.options[i].selected) { | |
selectedOptions.push(el.options[i].value) | |
} | |
} | |
stateChange[name] = selectedOptions | |
} | |
else if (type == 'checkbox') { | |
var objType = Object.prototype.toString.call(el.form.elements[name]) | |
if (objType == '[object RadioNodeList]' || objType == '[object NodeList]' || objType == '[object HTMLCollection]') { | |
var checkedBoxes = (Array.isArray(this.state[name]) ? this.state[name].slice() : []) | |
if (el.checked) { | |
checkedBoxes.push(el.value) | |
} | |
else { | |
checkedBoxes.splice(checkedBoxes.indexOf(el.value), 1) | |
} | |
stateChange[name] = checkedBoxes | |
} | |
else { | |
stateChange[name] = el.checked | |
} | |
} | |
else { | |
stateChange[name] = el.value | |
} | |
this.setState(stateChange) | |
} |
This file contains 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>React Form Handling - handleFormInputChange</title> | |
<script src="http://fb.me/react-0.12.0.js"></script> | |
<script src="http://fb.me/JSXTransformer-0.12.0.js"></script> | |
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css"> | |
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/grids-responsive-min.css"> | |
<style> | |
.content { max-width: 800px; margin: 0 auto; } | |
</style> | |
</head> | |
<body> | |
<div class="content"> | |
<div id="app"></div> | |
</div> | |
<script src="handleFormInputChange.js"></script> | |
<script type="text/jsx" src="app.jsx"></script> | |
<a href="https://gist.github.com/insin/082c0d88f6290a0ea4c7"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment