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
================================================
React App
================================================
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 (
React.js Controlled Form Components
);
}
}
export default App;
================================================
FILE: src/components/CheckboxOrRadioGroup.js
================================================
import React from 'react';
const CheckboxOrRadioGroup = (props) => (
);
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) => (
);
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) => (
);
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) => (
);
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 (
);
}
}
export default FormContainer;
================================================
FILE: src/index.js
================================================
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
,
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;
}