Skip to content

Commit 7382dcc

Browse files
authored
Merge pull request #29 from linuxonrails/port_07_enable_from_ts_to_js_#16
Port 07 Enable From TS to JS (ES6 >ES6). Issue #16
2 parents fc4b6c0 + 9a1e1dd commit 7382dcc

File tree

8 files changed

+266
-0
lines changed

8 files changed

+266
-0
lines changed

07 Enable/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "samplereact-es6",
3+
"version": "1.0.0",
4+
"description": "A little project to provide a set of step by step guided samples using React and ES6",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "webpack-dev-server --inline",
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"author": "",
11+
"license": "MIT",
12+
"dependencies": {
13+
"bootstrap": "^3.3.7",
14+
"react": "^15.3.2",
15+
"react-dom": "^15.3.2"
16+
},
17+
"devDependencies": {
18+
"babel-core": "^6.18.2",
19+
"babel-loader": "^6.2.7",
20+
"babel-preset-es2015": "^6.18.0",
21+
"babel-preset-react": "^6.16.0",
22+
"css-loader": "^0.25.0",
23+
"file-loader": "^0.9.0",
24+
"html-webpack-plugin": "^2.24.1",
25+
"style-loader": "^0.13.1",
26+
"url-loader": "^0.5.7",
27+
"webpack": "^1.13.3",
28+
"webpack-dev-server": "^1.16.2"
29+
},
30+
"repository": {
31+
"type": "git",
32+
"url": "https://github.com/Lemoncode/react-by-sample-es6"
33+
}
34+
}

07 Enable/readme.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# 07 Enable
2+
3+
4+
Let's continue with the update name sample, this time we want to disable the
5+
"update" button when the input is empty or when the value hasn't changed.
6+
7+
We will take a startup point sample _06 MoveBacktOStateless_.
8+
9+
Summary steps:
10+
11+
- Add a condition to disable
12+
13+
14+
## Prerequisites
15+
16+
Install [Node.js and npm](https://nodejs.org/en/) (v6.6.0 or newer) if they are not already installed on your computer.
17+
18+
> Verify that you are running at least node v6.x.x and npm 3.x.x by running `node -v` and `npm -v` in a terminal/console window. Older versions may produce errors.
19+
20+
## Steps to build it
21+
22+
- Copy the content from _06 MoveBacktoStateless_.
23+
24+
- Let's start by adding a condition to disable the field whenever is empty. Replace only the input tag in _src/nameEdit.jsx_ with the following code:
25+
26+
```jsx
27+
<input type="submit" value="Change"
28+
className="btn btn-default"
29+
onClick={props.onNameUpdateRequest}
30+
disabled={props.editingUserName === ''}
31+
/>
32+
```
33+
34+
- Now comes the tricky part, detect when the name hasn't changed.<br />
35+
First we will add a new property called _userName_ with type `string` in _src/nameEdit.jsx_. This one will hold the last accepted userName.
36+
37+
```jsx
38+
interface Props {
39+
userName : string;
40+
editingUserName : string;
41+
onEditingNameUpdated : (newEditingName : string) => any;
42+
onNameUpdateRequest : () => void;
43+
}
44+
```
45+
46+
- We will add to the enable condition one more test, checking if name has changed.
47+
Replace again only the input tag in _src/nameEdit.jsx_ with the following code:
48+
49+
```jsx
50+
<input type="submit" value="Change"
51+
className="btn btn-default"
52+
onClick={props.onNameUpdateRequest}
53+
disabled={props.editingUserName === '' || props.userName === props.editingUserName}
54+
/>
55+
```
56+
57+
- Now we have to feed this property from the parent control (Add `UserName={this.state.userName}` to the NameEditComponent in _src/app.jsx_). The `NameEditComponent` should be like:
58+
59+
```jsx
60+
<NameEditComponent
61+
UserName={this.state.userName}
62+
editingUserName={this.state.editingUserName}
63+
onEditingNameUpdated={this.updateEditingName.bind(this)}
64+
onNameUpdateRequest={this.setUsernameState.bind(this)}
65+
/>
66+
```
67+
68+
69+
- Let's give a try
70+
71+
```
72+
npm start
73+
```

07 Enable/src/app.jsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import {HelloComponent} from './hello';
3+
import {NameEditComponent} from './nameEdit';
4+
5+
export class App extends React.Component {
6+
constructor(props) {
7+
super(props);
8+
9+
const defaultUserName = 'defaultUserName';
10+
this.state = {userName: defaultUserName, editingUserName: defaultUserName};
11+
}
12+
13+
setUsernameState() {
14+
this.setState({userName: this.state.editingUserName});
15+
}
16+
17+
updateEditingName(editingName) {
18+
this.setState({editingUserName: editingName});
19+
}
20+
21+
render() {
22+
return (
23+
<div>
24+
<HelloComponent userName={this.state.userName} />
25+
<NameEditComponent
26+
userName={this.state.userName}
27+
editingUserName={this.state.editingUserName}
28+
onEditingNameUpdated={this.updateEditingName.bind(this)}
29+
onNameUpdateRequest={this.setUsernameState.bind(this)} />
30+
</div>
31+
);
32+
}
33+
}

07 Enable/src/hello.jsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
3+
export const HelloComponent = (props) => {
4+
return (
5+
<h2>Hello user: {props.userName}!</h2>
6+
);
7+
}
8+
9+
HelloComponent.propTypes = {
10+
userName: React.PropTypes.string.isRequired
11+
};

07 Enable/src/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<h1>Sample app</h1>
9+
<div id="root"></div>
10+
</body>
11+
</html>

07 Enable/src/main.jsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
import {render} from 'react-dom';
3+
import {App} from './app';
4+
5+
render(
6+
<App />
7+
, document.getElementById('root'));

07 Enable/src/nameEdit.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
3+
export const NameEditComponent = (props) => {
4+
return (
5+
<div>
6+
<label>Update Name:</label>
7+
<input value={props.editingUserName}
8+
onChange={(e) => props.onEditingNameUpdated(e.target.value)} />
9+
<input type="submit" value="Change"
10+
className="btn btn-default"
11+
onClick={props.onNameUpdateRequest}
12+
disabled={props.editingUserName === '' || props.userName === props.editingUserName}
13+
/>
14+
</div>
15+
);
16+
}
17+
18+
NameEditComponent.propTypes = {
19+
userName: React.PropTypes.string.isRequired,
20+
editingUserName: React.PropTypes.string.isRequired,
21+
onEditingNameUpdated: React.PropTypes.func.isRequired,
22+
onNameUpdateRequest: React.PropTypes.func.isRequired
23+
};

07 Enable/webpack.config.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
var path = require('path');
2+
var webpack = require('webpack');
3+
var HtmlWebpackPlugin = require('html-webpack-plugin');
4+
5+
var basePath = __dirname;
6+
7+
module.exports = {
8+
context: path.join(basePath, 'src'),
9+
resolve: {
10+
extensions: ['', '.js', '.jsx']
11+
},
12+
target: 'web',
13+
entry: [
14+
'./main.jsx',
15+
'../node_modules/bootstrap/dist/css/bootstrap.css'
16+
],
17+
output: {
18+
path: path.join(basePath, 'dist'),
19+
filename: 'bundle.js'
20+
},
21+
22+
devtool: 'source-map',
23+
24+
devServer: {
25+
contentBase: './dist', //Content base
26+
inline: true, //Enable watch and live reload
27+
host: 'localhost',
28+
port: 8080,
29+
stats: 'errors-only'
30+
},
31+
32+
module: {
33+
loaders: [
34+
{
35+
test: /\.jsx?$/,
36+
exclude: /node_modules/,
37+
loader: 'babel',
38+
query: {
39+
presets: ['react', 'es2015']
40+
}
41+
},
42+
{
43+
test: /\.css$/,
44+
loader: 'style-loader!css-loader'
45+
},
46+
// Loading glyphicons => https://github.com/gowravshekar/bootstrap-webpack
47+
// Using here url-loader and file-loader
48+
{
49+
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
50+
loader: 'url?limit=10000&mimetype=application/font-woff'
51+
},
52+
{
53+
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
54+
loader: 'url?limit=10000&mimetype=application/octet-stream'
55+
},
56+
{
57+
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
58+
loader: 'file'
59+
},
60+
{
61+
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
62+
loader: 'url?limit=10000&mimetype=image/svg+xml'
63+
}
64+
]
65+
},
66+
plugins: [
67+
// Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin
68+
new HtmlWebpackPlugin({
69+
filename: 'index.html', // Name of file in ./dist/
70+
template: 'index.html', // Name of template in ./src
71+
hash: true
72+
})
73+
]
74+
}

0 commit comments

Comments
 (0)