Repository: lorenseanstewart/react-controlled-form-components
Branch: master
Commit: 181e65d4262b
Files: 14
Total size: 12.2 KB
Directory structure:
gitextract_rlcvmnka/
├── .gitignore
├── .nvmrc
├── README.md
├── package.json
├── public/
│ ├── fake_db.json
│ └── index.html
└── src/
├── App.js
├── components/
│ ├── CheckboxOrRadioGroup.js
│ ├── Select.js
│ ├── SingleInput.js
│ └── TextArea.js
├── containers/
│ └── FormContainer.js
├── index.js
└── styles.css
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
node_modules
# testing
coverage
# production
build
# misc
.DS_Store
.idea/
.env
npm-debug.log
================================================
FILE: .nvmrc
================================================
6.2.1
================================================
FILE: README.md
================================================
### Tutorial: React.js Controlled Form Components
This repo is the companion to my blog post, [React.js Controlled Form Components](http://lorenstewart.me/2016/10/31/react-js-forms-controlled-components/).
[DEMO](http://lorenstewart.me/react-controlled-form-components/)
To get started:
1. Make sure you're using Node 6 or higher (4 and higher will work, though)
2. `npm install create-react-app -g` (if you don't have it installed already)
3. `npm install`
4. `npm run start`
5. Open [http://localhost:3000/](http://localhost:3000/) in your browser
================================================
FILE: package.json
================================================
{
"name": "react-form-components",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "0.6.1"
},
"dependencies": {
"react": "^15.3.2",
"react-dom": "^15.3.2",
"spectre.css": "^0.1.27"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
================================================
FILE: public/fake_db.json
================================================
{
"ownerName": "",
"petSelections": ["dog", "cat", "rabbit", "iguana", "pony", "ferret", "fish", "bird"],
"selectedPets": ["dog", "cat", "ferret"],
"ageOptions": ["18 - 25", "26 - 59", "60 or older"],
"ownerAgeRangeSelection": "",
"siblingOptions": ["yes", "no"],
"siblingSelection": ["yes"],
"currentPetCount": 0,
"description": ""
}
================================================
FILE: public/index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favico.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>
================================================
FILE: src/App.js
================================================
import React, { Component } from 'react';
import '../node_modules/spectre.css/dist/spectre.min.css';
import './styles.css';
import FormContainer from './containers/FormContainer';
class App extends Component {
render() {
return (
<div className="container">
<div className="columns">
<div className="col-md-9 centered">
<h3>React.js Controlled Form Components</h3>
<FormContainer />
</div>
</div>
</div>
);
}
}
export default App;
================================================
FILE: src/components/CheckboxOrRadioGroup.js
================================================
import React from 'react';
const CheckboxOrRadioGroup = (props) => (
<div>
<label className="form-label">{props.title}</label>
<div className="checkbox-group">
{props.options.map(option => {
return (
<label key={option} className="form-label capitalize">
<input
className="form-checkbox"
name={props.setName}
onChange={props.controlFunc}
value={option}
checked={props.selectedOptions.indexOf(option) > -1}
type={props.type} /> {option}
</label>
);
})}
</div>
</div>
);
CheckboxOrRadioGroup.propTypes = {
title: React.PropTypes.string.isRequired,
type: React.PropTypes.oneOf(['checkbox', 'radio']).isRequired,
setName: React.PropTypes.string.isRequired,
options: React.PropTypes.array.isRequired,
selectedOptions: React.PropTypes.array,
controlFunc: React.PropTypes.func.isRequired
};
export default CheckboxOrRadioGroup;
================================================
FILE: src/components/Select.js
================================================
import React from 'react';
const Select = (props) => (
<div className="form-group">
<select
name={props.name}
value={props.selectedOption}
onChange={props.controlFunc}
className="form-select">
<option value="">{props.placeholder}</option>
{props.options.map(opt => {
return (
<option
key={opt}
value={opt}>{opt}</option>
);
})}
</select>
</div>
);
Select.propTypes = {
name: React.PropTypes.string.isRequired,
options: React.PropTypes.array.isRequired,
selectedOption: React.PropTypes.string,
controlFunc: React.PropTypes.func.isRequired,
placeholder: React.PropTypes.string
};
export default Select;
================================================
FILE: src/components/SingleInput.js
================================================
import React from 'react';
const SingleInput = (props) => (
<div className="form-group">
<label className="form-label">{props.title}</label>
<input
className="form-input"
name={props.name}
type={props.inputType}
value={props.content}
onChange={props.controlFunc}
placeholder={props.placeholder} />
</div>
);
SingleInput.propTypes = {
inputType: React.PropTypes.oneOf(['text', 'number']).isRequired,
title: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
controlFunc: React.PropTypes.func.isRequired,
content: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
]).isRequired,
placeholder: React.PropTypes.string,
};
export default SingleInput;
================================================
FILE: src/components/TextArea.js
================================================
import React from 'react';
const TextArea = (props) => (
<div className="form-group">
<label className="form-label">{props.title}</label>
<textarea
className="form-input"
style={props.resize ? null : {resize: 'none'}}
name={props.name}
rows={props.rows}
value={props.content}
onChange={props.controlFunc}
placeholder={props.placeholder} />
</div>
);
TextArea.propTypes = {
title: React.PropTypes.string.isRequired,
rows: React.PropTypes.number.isRequired,
name: React.PropTypes.string.isRequired,
content: React.PropTypes.string.isRequired,
resize: React.PropTypes.bool,
placeholder: React.PropTypes.string,
controlFunc: React.PropTypes.func.isRequired
};
export default TextArea;
================================================
FILE: src/containers/FormContainer.js
================================================
import React, {Component} from 'react';
import CheckboxOrRadioGroup from '../components/CheckboxOrRadioGroup';
import SingleInput from '../components/SingleInput';
import TextArea from '../components/TextArea';
import Select from '../components/Select';
class FormContainer extends Component {
constructor(props) {
super(props);
this.state = {
ownerName: '',
petSelections: [],
selectedPets: [],
ageOptions: [],
ownerAgeRangeSelection: '',
siblingOptions: [],
siblingSelection: [],
currentPetCount: 0,
description: ''
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleFullNameChange = this.handleFullNameChange.bind(this);
this.handleCurrentPetCountChange = this.handleCurrentPetCountChange.bind(this);
this.handleAgeRangeSelect = this.handleAgeRangeSelect.bind(this);
this.handlePetSelection = this.handlePetSelection.bind(this);
this.handleSiblingsSelection = this.handleSiblingsSelection.bind(this);
this.handleDescriptionChange = this.handleDescriptionChange.bind(this);
}
componentDidMount() {
fetch('./fake_db.json')
.then(res => res.json())
.then(data => {
this.setState({
ownerName: data.ownerName,
petSelections: data.petSelections,
selectedPets: data.selectedPets,
ageOptions: data.ageOptions,
ownerAgeRangeSelection: data.ownerAgeRangeSelection,
siblingOptions: data.siblingOptions,
siblingSelection: data.siblingSelection,
currentPetCount: data.currentPetCount,
description: data.description
});
});
}
handleFullNameChange(e) {
this.setState({ ownerName: e.target.value }, () => console.log('name:', this.state.ownerName));
}
handleCurrentPetCountChange(e) {
this.setState({ currentPetCount: e.target.value }, () => console.log('pet count', this.state.currentPetCount));
}
handleAgeRangeSelect(e) {
this.setState({ ownerAgeRangeSelection: e.target.value }, () => console.log('age range', this.state.ownerAgeRangeSelection));
}
handlePetSelection(e) {
const newSelection = e.target.value;
let newSelectionArray;
if(this.state.selectedPets.indexOf(newSelection) > -1) {
newSelectionArray = this.state.selectedPets.filter(s => s !== newSelection)
} else {
newSelectionArray = [...this.state.selectedPets, newSelection];
}
this.setState({ selectedPets: newSelectionArray }, () => console.log('pet selection', this.state.selectedPets));
}
handleSiblingsSelection(e) {
this.setState({ siblingSelection: [e.target.value] }, () => console.log('siblingz', this.state.siblingSelection));
}
handleDescriptionChange(e) {
// const textArray = e.target.value.split('').filter(x => x !== 'e');
// console.log('string split into array of letters',textArray);
// const filteredText = textArray.join('');
// this.setState({ description: filteredText }, () => console.log('description', this.state.description));
this.setState({ description: e.target.value }, () => console.log('description', this.state.description));
}
handleClearForm(e) {
e.preventDefault();
this.setState({
ownerName: '',
selectedPets: [],
ownerAgeRangeSelection: '',
siblingSelection: [],
currentPetCount: 0,
description: ''
});
}
handleFormSubmit(e) {
e.preventDefault();
const formPayload = {
ownerName: this.state.ownerName,
selectedPets: this.state.selectedPets,
ownerAgeRangeSelection: this.state.ownerAgeRangeSelection,
siblingSelection: this.state.siblingSelection,
currentPetCount: this.state.currentPetCount,
description: this.state.description
};
console.log('Send this in a POST request:', formPayload);
this.handleClearForm(e);
}
render() {
return (
<form className="container" onSubmit={this.handleFormSubmit}>
<h5>Pet Adoption Form</h5>
<SingleInput
inputType={'text'}
title={'Full name'}
name={'name'}
controlFunc={this.handleFullNameChange}
content={this.state.ownerName}
placeholder={'Type first and last name here'} />
<Select
name={'ageRange'}
placeholder={'Choose your age range'}
controlFunc={this.handleAgeRangeSelect}
options={this.state.ageOptions}
selectedOption={this.state.ownerAgeRangeSelection} />
<CheckboxOrRadioGroup
title={'Which kinds of pets would you like to adopt?'}
setName={'pets'}
type={'checkbox'}
controlFunc={this.handlePetSelection}
options={this.state.petSelections}
selectedOptions={this.state.selectedPets} />
<CheckboxOrRadioGroup
title={'Are you willing to adopt more than one pet if we have siblings for adoption?'}
setName={'siblings'}
controlFunc={this.handleSiblingsSelection}
type={'radio'}
options={this.state.siblingOptions}
selectedOptions={this.state.siblingSelection} />
<SingleInput
inputType={'number'}
title={'How many pets do you currently own?'}
name={'currentPetCount'}
controlFunc={this.handleCurrentPetCountChange}
content={this.state.currentPetCount}
placeholder={'Enter number of current pets'} />
<TextArea
title={'If you currently own pets, please write their names, breeds, and an outline of their personalities.'}
rows={5}
resize={false}
content={this.state.description}
name={'currentPetInfo'}
controlFunc={this.handleDescriptionChange}
placeholder={'Please be thorough in your descriptions'} />
<input
type="submit"
className="btn btn-primary float-right"
value="Submit"/>
<button
className="btn btn-link float-left"
onClick={this.handleClearForm}>Clear form</button>
</form>
);
}
}
export default FormContainer;
================================================
FILE: src/index.js
================================================
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
================================================
FILE: src/styles.css
================================================
body {
padding-bottom: 80px;
}
form {
border: 3px solid #ccc;
padding: 0 20px 25px 20px;
border-radius: 10px;
}
input[type=checkbox],
input[type=radio] {
margin-right: 8px;
}
.form-label.capitalize {
text-transform: capitalize;
}
.checkbox-group {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.checkbox-group .form-label {
width: 50%;
}
input[type=submit],
.btn-link {
margin-top: 20px;
}
gitextract_rlcvmnka/
├── .gitignore
├── .nvmrc
├── README.md
├── package.json
├── public/
│ ├── fake_db.json
│ └── index.html
└── src/
├── App.js
├── components/
│ ├── CheckboxOrRadioGroup.js
│ ├── Select.js
│ ├── SingleInput.js
│ └── TextArea.js
├── containers/
│ └── FormContainer.js
├── index.js
└── styles.css
SYMBOL INDEX (14 symbols across 2 files)
FILE: src/App.js
class App (line 6) | class App extends Component {
method render (line 7) | render() {
FILE: src/containers/FormContainer.js
class FormContainer (line 7) | class FormContainer extends Component {
method constructor (line 8) | constructor(props) {
method componentDidMount (line 30) | componentDidMount() {
method handleFullNameChange (line 47) | handleFullNameChange(e) {
method handleCurrentPetCountChange (line 50) | handleCurrentPetCountChange(e) {
method handleAgeRangeSelect (line 53) | handleAgeRangeSelect(e) {
method handlePetSelection (line 56) | handlePetSelection(e) {
method handleSiblingsSelection (line 66) | handleSiblingsSelection(e) {
method handleDescriptionChange (line 69) | handleDescriptionChange(e) {
method handleClearForm (line 76) | handleClearForm(e) {
method handleFormSubmit (line 87) | handleFormSubmit(e) {
method render (line 102) | render() {
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
{
"path": ".gitignore",
"chars": 187,
"preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n\n# testing\ncovera"
},
{
"path": ".nvmrc",
"chars": 5,
"preview": "6.2.1"
},
{
"path": "README.md",
"chars": 558,
"preview": "### Tutorial: React.js Controlled Form Components\n\nThis repo is the companion to my blog post, [React.js Controlled Form"
},
{
"path": "package.json",
"chars": 415,
"preview": "{\n \"name\": \"react-form-components\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"devDependencies\": {\n \"react-scripts\""
},
{
"path": "public/fake_db.json",
"chars": 352,
"preview": "{\n \"ownerName\": \"\",\n \"petSelections\": [\"dog\", \"cat\", \"rabbit\", \"iguana\", \"pony\", \"ferret\", \"fish\", \"bird\"],\n \"selecte"
},
{
"path": "public/index.html",
"chars": 1136,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-wid"
},
{
"path": "src/App.js",
"chars": 517,
"preview": "import React, { Component } from 'react';\nimport '../node_modules/spectre.css/dist/spectre.min.css';\nimport './styles.cs"
},
{
"path": "src/components/CheckboxOrRadioGroup.js",
"chars": 910,
"preview": "import React from 'react';\n\nconst CheckboxOrRadioGroup = (props) => (\n\t<div>\n\t\t<label className=\"form-label\">{props.titl"
},
{
"path": "src/components/Select.js",
"chars": 660,
"preview": "import React from 'react';\n\nconst Select = (props) => (\n\t<div className=\"form-group\">\n\t\t<select\n\t\t\tname={props.name}\n\t\t\t"
},
{
"path": "src/components/SingleInput.js",
"chars": 733,
"preview": "import React from 'react';\n\nconst SingleInput = (props) => (\n\t<div className=\"form-group\">\n\t\t<label className=\"form-labe"
},
{
"path": "src/components/TextArea.js",
"chars": 717,
"preview": "import React from 'react';\n\nconst TextArea = (props) => (\n\t<div className=\"form-group\">\n\t\t<label className=\"form-label\">"
},
{
"path": "src/containers/FormContainer.js",
"chars": 5709,
"preview": "import React, {Component} from 'react';\nimport CheckboxOrRadioGroup from '../components/CheckboxOrRadioGroup';\nimport Si"
},
{
"path": "src/index.js",
"chars": 152,
"preview": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(\n <App />,\n doc"
},
{
"path": "src/styles.css",
"chars": 453,
"preview": "body {\n padding-bottom: 80px;\n}\nform {\n border: 3px solid #ccc;\n padding: 0 20px 25px 20px;\n border-radius: "
}
]
About this extraction
This page contains the full source code of the lorenseanstewart/react-controlled-form-components GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (12.2 KB), approximately 3.5k tokens, and a symbol index with 14 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.