Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b5eaac21a | ||
|
|
73cc989512 | ||
|
|
5a45846cb7 | ||
|
|
2d8d5b125e | ||
|
|
818b7798ee | ||
|
|
15ba8d7e60 | ||
|
|
eab958c3e9 | ||
|
|
3a17b7f638 | ||
|
|
734d39e2d7 | ||
|
|
0d7cace354 | ||
|
|
fa0881bfcf | ||
|
|
62b9e3582a | ||
|
|
949797d4be | ||
|
|
a869fe3819 | ||
|
|
c611af4f39 | ||
|
|
7cab3190ae | ||
|
|
71fe653fcb | ||
|
|
ba1c213ce0 | ||
|
|
46217c9ad7 | ||
|
|
017642e4d7 | ||
|
|
79b0eda61b | ||
|
|
a70f248af5 |
26
gulpfile.js
Normal file
26
gulpfile.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const gulp = require('gulp');
|
||||||
|
const gulpTypescript = require('gulp-typescript');
|
||||||
|
const merge = require('merge2');
|
||||||
|
|
||||||
|
gulp.task('watch', watchTask);
|
||||||
|
gulp.task('rebuild-ag-grid-react', rebuildAgGridReact);
|
||||||
|
|
||||||
|
const tsConfig = '../ag-grid-react/tsconfig.json';
|
||||||
|
const tsProject = gulpTypescript.createProject(tsConfig);
|
||||||
|
|
||||||
|
function rebuildAgGridReact() {
|
||||||
|
const tsResult = gulp
|
||||||
|
.src('../ag-grid-react/src/**/*.ts')
|
||||||
|
.pipe(tsProject());
|
||||||
|
|
||||||
|
return merge([
|
||||||
|
tsResult.dts
|
||||||
|
.pipe(gulp.dest('node_modules/ag-grid-react/lib')),
|
||||||
|
tsResult.js
|
||||||
|
.pipe(gulp.dest('node_modules/ag-grid-react/lib'))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchTask() {
|
||||||
|
gulp.watch(['../ag-grid-react/src/**/*'], rebuildAgGridReact);
|
||||||
|
}
|
||||||
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ag-grid-react-example",
|
"name": "ag-grid-react-example",
|
||||||
"version": "12.0.0",
|
"version": "13.1.0",
|
||||||
"description": "Example Reach applicaiton using ag-Grid.",
|
"description": "Example Reach applicaiton using ag-Grid.",
|
||||||
"main": "dist/ag-grid-react-example.js",
|
"main": "dist/ag-grid-react-example.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -12,17 +12,18 @@
|
|||||||
"copy-examples": "ncp images dist/examples/images && ncp src/index.html dist/examples/index.html && ncp dist/react-examples.js dist/examples/dist/react-examples.js && ncp src dist/examples/src",
|
"copy-examples": "ncp images dist/examples/images && ncp src/index.html dist/examples/index.html && ncp dist/react-examples.js dist/examples/dist/react-examples.js && ncp src dist/examples/src",
|
||||||
"copy-trader": "ncp src-trader-dashboard/index.html dist/trader/index.html && ncp dist/react-trader.js dist/trader/dist/react-trader.js",
|
"copy-trader": "ncp src-trader-dashboard/index.html dist/trader/index.html && ncp dist/react-trader.js dist/trader/dist/react-trader.js",
|
||||||
"copy": "npm run copy-examples && npm run copy-trader",
|
"copy": "npm run copy-examples && npm run copy-trader",
|
||||||
|
"build-large": "webpack --config webpack.config.large.js --progress --profile --bail",
|
||||||
"build-examples": "webpack --config webpack.config.examples.js --progress --profile --bail",
|
"build-examples": "webpack --config webpack.config.examples.js --progress --profile --bail",
|
||||||
"build-dashboard": "webpack --config webpack.config.trader.js --progress --profile --bail",
|
"build-dashboard": "webpack --config webpack.config.trader.js --progress --profile --bail",
|
||||||
"build-all": "npm run build-examples && npm run build-dashboard",
|
"build-all": "npm run build-examples && npm run build-dashboard",
|
||||||
"build": "npm run clean && npm run mkdirs && npm run build-all && npm run copy",
|
"build": "npm run clean && npm run mkdirs && npm run build-all && npm run copy",
|
||||||
"copy-to-docs": "ncp dist/examples ../ag-grid-docs/src/react-examples/examples && ncp dist/trader ../ag-grid-docs/src/react-examples/trader",
|
"copy-to-docs": "ncp dist/examples ../ag-grid-docs/src/framework-examples/react-examples/examples && ncp dist/trader ../ag-grid-docs/src/framework-examples/react-examples/trader",
|
||||||
"build-to-docs": "npm run build && npm run copy-to-docs",
|
"build-to-docs": "npm run build && npm run copy-to-docs",
|
||||||
"start": "npm run examples"
|
"start": "npm run examples"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/ceolter/ag-grid-react-example.git"
|
"url": "https://github.com/ag-grid/ag-grid-react-example.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
"author": "Niall Crosby <niall.crosby@gmail.com>",
|
"author": "Niall Crosby <niall.crosby@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/ceolter/ag-grid-react-example/issues"
|
"url": "https://github.com/ag-grid/ag-grid-react-example/issues"
|
||||||
},
|
},
|
||||||
"homepage": "http://www.ag-grid.com/",
|
"homepage": "http://www.ag-grid.com/",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -43,29 +44,32 @@
|
|||||||
"babel-preset-react": "6.24.x",
|
"babel-preset-react": "6.24.x",
|
||||||
"babel-preset-stage-0": "6.24.x",
|
"babel-preset-stage-0": "6.24.x",
|
||||||
"babel-preset-stage-1": "6.24.x",
|
"babel-preset-stage-1": "6.24.x",
|
||||||
"prop-types": "15.5.x",
|
|
||||||
"css-loader": "0.23.x",
|
"css-loader": "0.23.x",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
"ncp": "2.0.0",
|
"ncp": "2.0.0",
|
||||||
|
"prop-types": "15.5.x",
|
||||||
"rimraf": "2.5.x",
|
"rimraf": "2.5.x",
|
||||||
"style-loader": "0.13.x",
|
"style-loader": "0.13.x",
|
||||||
"webpack": "1.12.x",
|
"webpack": "1.12.x",
|
||||||
"webpack-dev-server": "1.14.x"
|
"webpack-dev-server": "1.14.x",
|
||||||
|
"gulp": "3.9.x",
|
||||||
|
"gulp-typescript": "3.1.x",
|
||||||
|
"merge2": "1.0.x",
|
||||||
|
"typescript": "2.3.x"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "3.3.7",
|
"bootstrap": "3.3.7",
|
||||||
"d3": "4.9.1",
|
"d3": "4.9.1",
|
||||||
"file-loader": "0.11.1",
|
"file-loader": "0.11.1",
|
||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
"react": "15.5.x",
|
"react": "15.6.x",
|
||||||
"react-dom": "15.5.x",
|
"react-dom": "15.6.x",
|
||||||
|
"react-dom-factories": "1.0.0",
|
||||||
"react-redux": "5.0.x",
|
"react-redux": "5.0.x",
|
||||||
"redux": "3.6.x",
|
"redux": "3.6.x",
|
||||||
"url-search-params-polyfill": "1.2.0",
|
"url-search-params-polyfill": "1.2.0",
|
||||||
"ag-grid": "12.0.x",
|
"ag-grid": "13.1.x",
|
||||||
"ag-grid-enterprise": "12.0.x",
|
"ag-grid-enterprise": "13.1.x",
|
||||||
"ag-grid-react": "12.0.x"
|
"ag-grid-react": "13.1.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,21 +23,21 @@ export default class extends Component {
|
|||||||
{
|
{
|
||||||
field: 'price',
|
field: 'price',
|
||||||
headerName: 'Price',
|
headerName: 'Price',
|
||||||
cellFormatter: this.numberFormatter,
|
valueFormatter: this.numberFormatter,
|
||||||
cellRenderer: 'animateShowChange',
|
cellRenderer: 'animateShowChange',
|
||||||
cellStyle: {'text-align': 'right'}
|
cellStyle: {'text-align': 'right'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'bid',
|
field: 'bid',
|
||||||
headerName: 'Bid',
|
headerName: 'Bid',
|
||||||
cellFormatter: this.numberFormatter,
|
valueFormatter: this.numberFormatter,
|
||||||
cellRenderer: 'animateShowChange',
|
cellRenderer: 'animateShowChange',
|
||||||
cellStyle: {'text-align': 'right'}
|
cellStyle: {'text-align': 'right'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'ask',
|
field: 'ask',
|
||||||
headerName: 'Ask',
|
headerName: 'Ask',
|
||||||
cellFormatter: this.numberFormatter,
|
valueFormatter: this.numberFormatter,
|
||||||
cellRenderer: 'animateShowChange',
|
cellRenderer: 'animateShowChange',
|
||||||
cellStyle: {'text-align': 'right'}
|
cellStyle: {'text-align': 'right'}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/App.jsx
17
src/App.jsx
@@ -6,13 +6,14 @@ import DynamicComponentsExample from "./dynamicComponentExample/DynamicComponent
|
|||||||
import RichGridExample from "./richGridExample/RichGridExample";
|
import RichGridExample from "./richGridExample/RichGridExample";
|
||||||
import RichComponentsExample from "./richComponentExample/RichComponentsExample";
|
import RichComponentsExample from "./richComponentExample/RichComponentsExample";
|
||||||
import EditorComponentsExample from "./editorComponentExample/EditorComponentsExample";
|
import EditorComponentsExample from "./editorComponentExample/EditorComponentsExample";
|
||||||
import FloatingRowComponentExample from "./floatingRowExample/FloatingRowComponentExample";
|
import PinnedRowComponentExample from "./pinnedRowExample/PinnedRowComponentExample";
|
||||||
import FullWidthComponentExample from "./fullWidthExample/FullWidthComponentExample";
|
import FullWidthComponentExample from "./fullWidthExample/FullWidthComponentExample";
|
||||||
import GroupedRowInnerRendererComponentExample from "./groupedRowInnerRendererExample/GroupedRowInnerRendererComponentExample";
|
import GroupedRowInnerRendererComponentExample from "./groupedRowInnerRendererExample/GroupedRowInnerRendererComponentExample";
|
||||||
import FilterComponentExample from "./filterComponentExample/FilterComponentExample";
|
import FilterComponentExample from "./filterComponentExample/FilterComponentExample";
|
||||||
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
|
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
|
||||||
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
|
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
|
||||||
import SimpleGridExample from "./floatingFilter/SimpleGridExample";
|
import FloatingFilterGridExample from "./floatingFilter/FloatingFilterGridExample";
|
||||||
|
import SimpleReduxDynamicExample from "./simpleReduxDynamicComponentExample/SimpleReduxExample";
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -45,13 +46,14 @@ class App extends Component {
|
|||||||
<li role="presentation" className={this.state.example === 'dynamic' ? 'active' : null} onClick={() => this.setExample("dynamic")}><a href="#">Dynamic React Component Example</a></li>
|
<li role="presentation" className={this.state.example === 'dynamic' ? 'active' : null} onClick={() => this.setExample("dynamic")}><a href="#">Dynamic React Component Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'rich-dynamic' ? 'active' : null} onClick={() => this.setExample("rich-dynamic")}><a href="#">Dynamic React Components - Richer Example</a></li>
|
<li role="presentation" className={this.state.example === 'rich-dynamic' ? 'active' : null} onClick={() => this.setExample("rich-dynamic")}><a href="#">Dynamic React Components - Richer Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'editor' ? 'active' : null} onClick={() => this.setExample("editor")}><a href="#">Cell Editor Component Example</a></li>
|
<li role="presentation" className={this.state.example === 'editor' ? 'active' : null} onClick={() => this.setExample("editor")}><a href="#">Cell Editor Component Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'floating-row' ? 'active' : null} onClick={() => this.setExample("floating-row")}><a href="#">Pinned Row Renderer Example</a></li>
|
<li role="presentation" className={this.state.example === 'pinned-row' ? 'active' : null} onClick={() => this.setExample("pinned-row")}><a href="#">Pinned Row Renderer Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'full-width' ? 'active' : null} onClick={() => this.setExample("full-width")}><a href="#">Full Width Renderer Example</a></li>
|
<li role="presentation" className={this.state.example === 'full-width' ? 'active' : null} onClick={() => this.setExample("full-width")}><a href="#">Full Width Renderer Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'group-row' ? 'active' : null} onClick={() => this.setExample("group-row")}><a href="#">Grouped Row Inner Renderer Example</a></li>
|
<li role="presentation" className={this.state.example === 'group-row' ? 'active' : null} onClick={() => this.setExample("group-row")}><a href="#">Grouped Row Inner Renderer Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'filter' ? 'active' : null} onClick={() => this.setExample("filter")}><a href="#">Filters Component Example</a></li>
|
<li role="presentation" className={this.state.example === 'filter' ? 'active' : null} onClick={() => this.setExample("filter")}><a href="#">Filters Component Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'floating-filter' ? 'active' : null} onClick={() => this.setExample("floating-filter")}><a href="#">Floating Filters</a></li>
|
<li role="presentation" className={this.state.example === 'floating-filter' ? 'active' : null} onClick={() => this.setExample("floating-filter")}><a href="#">Floating Filters</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'master-detail' ? 'active' : null} onClick={() => this.setExample("master-detail")}><a href="#">Master Detail Example</a></li>
|
<li role="presentation" className={this.state.example === 'master-detail' ? 'active' : null} onClick={() => this.setExample("master-detail")}><a href="#">Master Detail Example</a></li>
|
||||||
<li role="presentation" className={this.state.example === 'simple-redux' ? 'active' : null} onClick={() => this.setExample("simple-redux")}><a href="#">Simple Redux Example</a></li>
|
<li role="presentation" className={this.state.example === 'simple-redux' ? 'active' : null} onClick={() => this.setExample("simple-redux")}><a href="#">Simple Redux Example</a></li>
|
||||||
|
<li role="presentation" className={this.state.example === 'simple-redux-dynamic' ? 'active' : null} onClick={() => this.setExample("simple-redux-dynamic")}><a href="#">Simple Redux Dynamic Component Example</a></li>
|
||||||
</ul>)
|
</ul>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,8 +68,8 @@ class App extends Component {
|
|||||||
case 'editor':
|
case 'editor':
|
||||||
example = <EditorComponentsExample/>;
|
example = <EditorComponentsExample/>;
|
||||||
break;
|
break;
|
||||||
case 'floating-row':
|
case 'pinned-row':
|
||||||
example = <FloatingRowComponentExample/>;
|
example = <PinnedRowComponentExample/>;
|
||||||
break;
|
break;
|
||||||
case 'full-width':
|
case 'full-width':
|
||||||
example = <FullWidthComponentExample/>;
|
example = <FullWidthComponentExample/>;
|
||||||
@@ -85,7 +87,10 @@ class App extends Component {
|
|||||||
example = <SimpleReduxExample/>;
|
example = <SimpleReduxExample/>;
|
||||||
break;
|
break;
|
||||||
case 'floating-filter':
|
case 'floating-filter':
|
||||||
example = <SimpleGridExample/>;
|
example = <FloatingFilterGridExample/>;
|
||||||
|
break;
|
||||||
|
case 'simple-redux-dynamic':
|
||||||
|
example = <SimpleReduxDynamicExample/>;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
example = <RichGridExample/>;
|
example = <RichGridExample/>;
|
||||||
|
|||||||
@@ -18,9 +18,21 @@ export default class MoodEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.refs.container.addEventListener('keydown', this.checkAndToggleMoodIfLeftRight);
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.refs.container.removeEventListener('keydown', this.checkAndToggleMoodIfLeftRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAndToggleMoodIfLeftRight = (event) => {
|
||||||
|
if ([37, 39].indexOf(event.keyCode) > -1) { // left and right
|
||||||
|
this.toggleMood();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
@@ -75,12 +87,11 @@ export default class MoodEditor extends Component {
|
|||||||
background: "#e6e6e6",
|
background: "#e6e6e6",
|
||||||
padding: 15,
|
padding: 15,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
display: "inline-block",
|
display: "inline-block"
|
||||||
// outline: "none"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let unselected = {
|
let unselected = {
|
||||||
paddingLleft: 10,
|
paddingLeft: 10,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
border: "1px solid transparent",
|
border: "1px solid transparent",
|
||||||
padding: 4
|
padding: 4
|
||||||
@@ -93,12 +104,14 @@ export default class MoodEditor extends Component {
|
|||||||
padding: 4
|
padding: 4
|
||||||
};
|
};
|
||||||
|
|
||||||
let happyStyle = this.state.value === 'Happy' ? selected : unselected;
|
let happyStyle = this.state.happy ? selected : unselected;
|
||||||
let sadStyle = this.state.value !== 'Happy' ? selected : unselected;
|
let sadStyle = !this.state.happy ? selected : unselected;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref="container"
|
<div ref="container"
|
||||||
style={mood}>
|
style={mood}
|
||||||
|
tabIndex={1} // important - without this the keypresses wont be caught
|
||||||
|
>
|
||||||
<img src="images/smiley.png" onClick={this.onHappyClick} style={happyStyle}/>
|
<img src="images/smiley.png" onClick={this.onHappyClick} style={happyStyle}/>
|
||||||
<img src="images/smiley-sad.png" onClick={this.onSadClick} style={sadStyle}/>
|
<img src="images/smiley-sad.png" onClick={this.onSadClick} style={sadStyle}/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export default class MoodEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.refs.input.addEventListener('keydown', this.onKeyDown);
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +24,10 @@ export default class MoodEditor extends Component {
|
|||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.refs.input.removeEventListener('keydown', this.onKeyDown);
|
||||||
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let container = ReactDOM.findDOMNode(this.refs.input);
|
let container = ReactDOM.findDOMNode(this.refs.input);
|
||||||
@@ -47,11 +52,20 @@ export default class MoodEditor extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onKeyDown(event) {
|
onKeyDown(event) {
|
||||||
|
if(this.isLeftOrRight(event)) {
|
||||||
|
event.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.isKeyPressedNumeric(event)) {
|
if (!this.isKeyPressedNumeric(event)) {
|
||||||
if (event.preventDefault) event.preventDefault();
|
if (event.preventDefault) event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLeftOrRight(event) {
|
||||||
|
return [37, 39].indexOf(event.keyCode) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
handleChange(event) {
|
handleChange(event) {
|
||||||
this.setState({value: event.target.value});
|
this.setState({value: event.target.value});
|
||||||
}
|
}
|
||||||
@@ -75,7 +89,6 @@ export default class MoodEditor extends Component {
|
|||||||
return (
|
return (
|
||||||
<input ref="input"
|
<input ref="input"
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
onKeyDown={this.onKeyDown}
|
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import {AgGridReact} from "ag-grid-react";
|
import {AgGridReact} from "ag-grid-react";
|
||||||
import FloatingFilter from "./floatingFilter";
|
import FloatingFilter from "./floatingFilter";
|
||||||
|
import overrideStyle from "./floatingFilter.css";
|
||||||
|
|
||||||
export default class extends Component {
|
export default class FloatingFilterGridExample extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@@ -21,7 +22,12 @@ export default class extends Component {
|
|||||||
|
|
||||||
createColumnDefs() {
|
createColumnDefs() {
|
||||||
return [
|
return [
|
||||||
{headerName: "Make", field: "make", floatingFilterComponentFramework: FloatingFilter, filter:'set'},
|
{
|
||||||
|
headerName: "Make",
|
||||||
|
field: "make",
|
||||||
|
floatingFilterComponentFramework: FloatingFilter,
|
||||||
|
filter: 'set'
|
||||||
|
},
|
||||||
{headerName: "Model", field: "model"},
|
{headerName: "Model", field: "model"},
|
||||||
{headerName: "Price", field: "price"}
|
{headerName: "Price", field: "price"}
|
||||||
];
|
];
|
||||||
@@ -36,14 +42,17 @@ export default class extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let containerStyle = {
|
let divStyle = {
|
||||||
height: 115,
|
height: 400,
|
||||||
width: 500
|
width: 945
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// combine the styles
|
||||||
|
const style = Object.assign({}, divStyle, overrideStyle);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={containerStyle} className="ag-fresh">
|
<div style={style} className="ag-fresh">
|
||||||
<h1>Simple ag-Grid React Example</h1>
|
<h1>Floating Filter Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
// properties
|
// properties
|
||||||
columnDefs={this.state.columnDefs}
|
columnDefs={this.state.columnDefs}
|
||||||
3
src/floatingFilter/floatingFilter.css
Normal file
3
src/floatingFilter/floatingFilter.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.ag-floating-filter-button button {
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
@@ -1,35 +1,35 @@
|
|||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
export default class FloatingFilter extends Component {
|
export default class FloatingFilter extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super();
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
parentModel: null
|
parentModel: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onParentModelChanged(parentModel){
|
// when does this get called? how to test this?
|
||||||
this.setState ({
|
onParentModelChanged(parentModel) {
|
||||||
|
this.setState({
|
||||||
parentModel: parentModel
|
parentModel: parentModel
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(item){
|
remove(item) {
|
||||||
this.props.onFloatingFilterChanged({
|
this.props.onFloatingFilterChanged({
|
||||||
model:this.state.parentModel.filter(it=>it != item)
|
model: this.state.parentModel.filter(it => it !== item)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.parentModel) return null;
|
if (!this.state.parentModel) return null;
|
||||||
|
|
||||||
let that = this;
|
// as the backing filter is a set filter what we're doing here is rendering the list in the set
|
||||||
let options = this.state.parentModel.map ((item, i)=>{
|
// and when the [x] removing the selected item, thereby effectively hiding it
|
||||||
let that = this;
|
let options = this.state.parentModel.map((item, i) => {
|
||||||
let removeMeListener = ()=>{
|
let removeMeListener = () => {
|
||||||
this.remove(item)
|
this.remove(item)
|
||||||
}
|
};
|
||||||
let removeMeElement = <a onClick={removeMeListener}>[x]</a>;
|
let removeMeElement = <a onClick={removeMeListener}>[x]</a>;
|
||||||
return <span key={i}>{item}{removeMeElement}</span>;
|
return <span key={i}>{item}{removeMeElement}</span>;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,35 +17,34 @@
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right
|
||||||
|
}
|
||||||
|
|
||||||
.customHeaderMenuButton {
|
.customHeaderMenuButton {
|
||||||
margin-top: 5px;
|
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customHeaderLabel {
|
.customHeaderLabel {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-top: 3px;
|
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customSortDownLabel {
|
.customSortDownLabel {
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-top: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.customSortUpLabel {
|
.customSortUpLabel {
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
margin-top: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.customSortRemoveLabel {
|
.customSortRemoveLabel {
|
||||||
float: left;
|
float: left;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
margin-top: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
@@ -58,13 +57,11 @@
|
|||||||
|
|
||||||
.customHeaderLabel {
|
.customHeaderLabel {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-top: 3px;
|
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customExpandButton {
|
.customExpandButton {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: 5px;
|
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,4 +117,4 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ import "../node_modules/bootstrap/dist/css/bootstrap.css";
|
|||||||
|
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
|
||||||
|
// only required when using enterprise features
|
||||||
|
// import {LicenseManager} from "ag-grid-enterprise/main";
|
||||||
|
// LicenseManager.setLicenseKey("<your license key>");
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
render(
|
render(
|
||||||
<App/>,
|
<App/>,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React, {Component} from "react";
|
|||||||
import {AgGridReact} from "ag-grid-react";
|
import {AgGridReact} from "ag-grid-react";
|
||||||
import StyledRenderer from "./StyledRenderer";
|
import StyledRenderer from "./StyledRenderer";
|
||||||
|
|
||||||
export default class FloatingRowComponentExample extends Component {
|
export default class PinnedRowComponentExample extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@@ -33,8 +33,8 @@ export default class FloatingRowComponentExample extends Component {
|
|||||||
headerName: "Row",
|
headerName: "Row",
|
||||||
field: "row",
|
field: "row",
|
||||||
width: 400,
|
width: 400,
|
||||||
floatingCellRendererFramework: StyledRenderer,
|
pinnedRowCellRendererFramework: StyledRenderer,
|
||||||
floatingCellRendererParams: {
|
pinnedRowCellRendererParams: {
|
||||||
style: {'fontWeight': 'bold'}
|
style: {'fontWeight': 'bold'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -42,8 +42,8 @@ export default class FloatingRowComponentExample extends Component {
|
|||||||
headerName: "Number",
|
headerName: "Number",
|
||||||
field: "number",
|
field: "number",
|
||||||
width: 399,
|
width: 399,
|
||||||
floatingCellRendererFramework: StyledRenderer,
|
pinnedRowCellRendererFramework: StyledRenderer,
|
||||||
floatingCellRendererParams: {
|
pinnedRowCellRendererParams: {
|
||||||
style: {'fontStyle': 'italic'}
|
style: {'fontStyle': 'italic'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -55,7 +55,7 @@ export default class FloatingRowComponentExample extends Component {
|
|||||||
|
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 15; i++) {
|
||||||
rowData.push({
|
rowData.push({
|
||||||
row: "Rou " + i,
|
row: "Row " + i,
|
||||||
number: Math.round(Math.random() * 100)
|
number: Math.round(Math.random() * 100)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -9,46 +9,85 @@ import HeaderGroupComponent from './HeaderGroupComponent.jsx';
|
|||||||
export default class ColDefFactory {
|
export default class ColDefFactory {
|
||||||
|
|
||||||
createColDefs() {
|
createColDefs() {
|
||||||
|
return [
|
||||||
var columnDefs = [
|
{
|
||||||
{headerName: '#', width: 30, checkboxSelection: true, suppressSorting: true,
|
headerName: '#',
|
||||||
suppressMenu: true, pinned: true},
|
width: 30,
|
||||||
|
checkboxSelection: true,
|
||||||
|
suppressSorting: true,
|
||||||
|
suppressMenu: true,
|
||||||
|
pinned: true,
|
||||||
|
icons: {
|
||||||
|
checkboxChecked: '<i class="fa fa-arrow-left"/>',
|
||||||
|
checkboxUnchecked: '<i class="fa fa-arrow-right"/>',
|
||||||
|
checkboxIndeterminate: '<i class="fa fa-arrow-up"/>'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
headerName: 'Employee',
|
headerName: 'Employee',
|
||||||
headerGroupComponentFramework: HeaderGroupComponent,
|
headerGroupComponentFramework: HeaderGroupComponent,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
headerName: "Name", field: "name", enableRowGroup: true, enablePivot: true,
|
headerName: "Name",
|
||||||
width: 150, pinned: true, editable: true,
|
field: "name",
|
||||||
|
enableRowGroup: true,
|
||||||
|
enablePivot: true,
|
||||||
|
width: 150,
|
||||||
|
pinned: true,
|
||||||
|
editable: true,
|
||||||
// use a React cellEditor
|
// use a React cellEditor
|
||||||
cellEditorFramework: NameCellEditor
|
cellEditorFramework: NameCellEditor
|
||||||
}, {
|
}, {
|
||||||
headerName: "Country", field: "country", width: 150, enableRowGroup: true, enablePivot: true,
|
headerName: "Country",
|
||||||
|
field: "country",
|
||||||
|
width: 150,
|
||||||
|
enableRowGroup: true,
|
||||||
|
enablePivot: true,
|
||||||
// an example of using a non-React cell renderer
|
// an example of using a non-React cell renderer
|
||||||
cellRenderer: countryCellRenderer, pinned: true,
|
cellRenderer: countryCellRenderer,
|
||||||
|
pinned: true,
|
||||||
filterParams: {
|
filterParams: {
|
||||||
cellRenderer: countryCellRenderer, cellHeight: 20
|
cellRenderer: countryCellRenderer,
|
||||||
}, columnGroupShow: 'open'
|
cellHeight: 20
|
||||||
|
},
|
||||||
|
columnGroupShow: 'open'
|
||||||
}, {
|
}, {
|
||||||
headerName: "DOB", field: "dob", width: 110, enableRowGroup: true, enablePivot: true, filter:'date',
|
headerName: "DOB",
|
||||||
pinned: true, cellRenderer: function(params) {
|
field: "dob",
|
||||||
return pad(params.value.getDate(), 2) + '/' +
|
width: 110,
|
||||||
pad(params.value.getMonth() + 1, 2)+ '/' +
|
enableRowGroup: true,
|
||||||
params.value.getFullYear();
|
enablePivot: true,
|
||||||
}, columnGroupShow: 'open'
|
filter: 'date',
|
||||||
|
pinned: true,
|
||||||
|
cellRenderer: function (params) {
|
||||||
|
return pad(params.value.getDate(), 2) + '/' +
|
||||||
|
pad(params.value.getMonth() + 1, 2) + '/' +
|
||||||
|
params.value.getFullYear();
|
||||||
|
},
|
||||||
|
columnGroupShow: 'open'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headerName: 'IT Skills',
|
headerName: 'IT Skills',
|
||||||
children: [
|
children: [
|
||||||
{headerName: "Skills", width: 125, suppressSorting: true, field: 'skills', enableRowGroup: true, enablePivot: true,
|
{
|
||||||
|
headerName: "Skills",
|
||||||
|
width: 125,
|
||||||
|
suppressSorting: true,
|
||||||
|
field: 'skills',
|
||||||
|
enableRowGroup: true,
|
||||||
|
enablePivot: true,
|
||||||
// supply a React component
|
// supply a React component
|
||||||
cellRendererFramework: SkillsCellRenderer,
|
cellRendererFramework: SkillsCellRenderer,
|
||||||
// supply a React component
|
// supply a React component
|
||||||
filterFramework: SkillsFilter
|
filterFramework: SkillsFilter
|
||||||
},
|
},
|
||||||
{headerName: "Proficiency", field: "proficiency", width: 135, enableValue: true,
|
{
|
||||||
|
headerName: "Proficiency",
|
||||||
|
field: "proficiency",
|
||||||
|
width: 135,
|
||||||
|
enableValue: true,
|
||||||
// supply a React component
|
// supply a React component
|
||||||
cellRendererFramework: ProficiencyCellRenderer,
|
cellRendererFramework: ProficiencyCellRenderer,
|
||||||
// supply a React component
|
// supply a React component
|
||||||
@@ -65,7 +104,6 @@ export default class ColDefFactory {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
return columnDefs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +111,7 @@ export default class ColDefFactory {
|
|||||||
// need to use React for it.
|
// need to use React for it.
|
||||||
function countryCellRenderer(params) {
|
function countryCellRenderer(params) {
|
||||||
if (params.value) {
|
if (params.value) {
|
||||||
var flag = "<img border='0' width='15' height='10' " +
|
const flag = "<img border='0' width='15' height='10' " +
|
||||||
"style='margin-bottom: 2px' src='http://flags.fmcdn.net/data/flags/mini/"
|
"style='margin-bottom: 2px' src='http://flags.fmcdn.net/data/flags/mini/"
|
||||||
+ RefData.COUNTRY_CODES[params.value] + ".png'>";
|
+ RefData.COUNTRY_CODES[params.value] + ".png'>";
|
||||||
return flag + " " + params.value;
|
return flag + " " + params.value;
|
||||||
|
|||||||
@@ -76,10 +76,6 @@ export default class RichGridExample extends Component {
|
|||||||
this.columnApi = params.columnApi;
|
this.columnApi = params.columnApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAll() {
|
|
||||||
this.api.selectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
deselectAll() {
|
deselectAll() {
|
||||||
this.api.deselectAll();
|
this.api.deselectAll();
|
||||||
}
|
}
|
||||||
@@ -156,7 +152,8 @@ export default class RichGridExample extends Component {
|
|||||||
<div style={{padding: 4}} className={'toolbar'}>
|
<div style={{padding: 4}} className={'toolbar'}>
|
||||||
<span>
|
<span>
|
||||||
Grid API:
|
Grid API:
|
||||||
<button onClick={this.selectAll.bind(this)}>Select All</button>
|
{/* use ref to access the api in selectAll */}
|
||||||
|
<button onClick={() => { this.refs.myGrid.api.selectAll() }}>Select All</button>
|
||||||
<button onClick={this.deselectAll.bind(this)}>Clear Selection</button>
|
<button onClick={this.deselectAll.bind(this)}>Clear Selection</button>
|
||||||
</span>
|
</span>
|
||||||
<span style={{marginLeft: 20}}>
|
<span style={{marginLeft: 20}}>
|
||||||
@@ -186,6 +183,7 @@ export default class RichGridExample extends Component {
|
|||||||
gridTemplate = (
|
gridTemplate = (
|
||||||
<div style={{height: 400, width: 945}} className="ag-fresh">
|
<div style={{height: 400, width: 945}} className="ag-fresh">
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
ref="myGrid"
|
||||||
// gridOptions is optional - it's possible to provide
|
// gridOptions is optional - it's possible to provide
|
||||||
// all values as React props
|
// all values as React props
|
||||||
gridOptions={this.gridOptions}
|
gridOptions={this.gridOptions}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default class SortableHeaderComponent extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.props.column.addEventListener('sortChanged', this.onSortChanged.bind(this));
|
// this.sortChanged = this.onSortChanged.bind(this);
|
||||||
|
this.props.column.addEventListener('sortChanged', this.onSortChanged);
|
||||||
|
|
||||||
//The state of this component contains the current sort state of this column
|
//The state of this component contains the current sort state of this column
|
||||||
//The possible values are: 'asc', 'desc' and ''
|
//The possible values are: 'asc', 'desc' and ''
|
||||||
@@ -16,6 +17,9 @@ export default class SortableHeaderComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.props.column.removeEventListener('sortChanged', this.onSortChanged);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let sortElements = [];
|
let sortElements = [];
|
||||||
@@ -51,7 +55,7 @@ export default class SortableHeaderComponent extends React.Component {
|
|||||||
this.props.setSort(order, event.shiftKey);
|
this.props.setSort(order, event.shiftKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
onSortChanged() {
|
onSortChanged = () => {
|
||||||
if (this.props.column.isSortAscending()) {
|
if (this.props.column.isSortAscending()) {
|
||||||
this.setState({
|
this.setState({
|
||||||
sorted: 'asc'
|
sorted: 'asc'
|
||||||
|
|||||||
57
src/simpleReduxDynamicComponentExample/GridComponent.jsx
Normal file
57
src/simpleReduxDynamicComponentExample/GridComponent.jsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React, {Component} from "react";
|
||||||
|
|
||||||
|
import {AgGridReact} from "ag-grid-react";
|
||||||
|
import {connect} from "react-redux";
|
||||||
|
|
||||||
|
import PriceRenderer from "./PriceRenderer";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This component serves to display the row data (provided by redux)
|
||||||
|
*/
|
||||||
|
class GridComponent extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
columnDefs: [
|
||||||
|
{headerName: 'Symbol', field: 'symbol'},
|
||||||
|
{headerName: 'Price', field: 'price', cellClass: 'align-right', cellRendererFramework: PriceRenderer}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onGridReady(params) {
|
||||||
|
this.gridApi = params.api;
|
||||||
|
this.columnApi = params.columnApi;
|
||||||
|
|
||||||
|
this.gridApi.sizeColumnsToFit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// row data will be provided via redux on this.props.rowData
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={{height: 400, width: 945, marginTop: 15}}
|
||||||
|
className="ag-fresh">
|
||||||
|
<AgGridReact
|
||||||
|
// properties
|
||||||
|
columnDefs={this.state.columnDefs}
|
||||||
|
rowData={this.props.rowData}
|
||||||
|
|
||||||
|
// events
|
||||||
|
onGridReady={this.onGridReady}>
|
||||||
|
</AgGridReact>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pull off row data changes
|
||||||
|
export default connect(
|
||||||
|
(state) => {
|
||||||
|
return {
|
||||||
|
rowData: state.rowData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)(GridComponent);
|
||||||
85
src/simpleReduxDynamicComponentExample/HeaderComponent.jsx
Normal file
85
src/simpleReduxDynamicComponentExample/HeaderComponent.jsx
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import React, {Component} from "react";
|
||||||
|
import {connect} from "react-redux";
|
||||||
|
// take this line out if you do not want to use ag-Grid-Enterprise
|
||||||
|
import "ag-grid-enterprise";
|
||||||
|
|
||||||
|
import {setCurrency, updateRowData} from "./gridDataActions";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This component serves both to host the demo controls, which in turn will drive row data state changes
|
||||||
|
*/
|
||||||
|
class HeaderComponent extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// provide the initial data to the store (which in turn will populate the grid)
|
||||||
|
this.props.dispatch(updateRowData(this.createRowData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrency(currencySymbol, exchangeRate) {
|
||||||
|
this.props.dispatch(setCurrency(currencySymbol, exchangeRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={{marginTop: 15}}>
|
||||||
|
<button onClick={this.setCurrency.bind(this, '£', 1)}>Set Currency to GBP</button>
|
||||||
|
<button onClick={this.setCurrency.bind(this, '$', 1.29)}>Set Currency to USD</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following methods are for creating dummy row data
|
||||||
|
createRowData() {
|
||||||
|
let rowData = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 14; i++) {
|
||||||
|
let newItem = this.createItem();
|
||||||
|
rowData.push(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowData;
|
||||||
|
}
|
||||||
|
|
||||||
|
createItem() {
|
||||||
|
return {
|
||||||
|
symbol: this.createUniqueRandomSymbol(),
|
||||||
|
price: Math.floor(Math.random() * 100)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a unique symbol, eg 'ADG' or 'ZJD'
|
||||||
|
createUniqueRandomSymbol() {
|
||||||
|
let symbol;
|
||||||
|
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
let isUnique = false;
|
||||||
|
while (!isUnique) {
|
||||||
|
symbol = '';
|
||||||
|
// create symbol
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
symbol += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||||
|
}
|
||||||
|
// check uniqueness
|
||||||
|
isUnique = true;
|
||||||
|
this.props.rowData.forEach(function (oldItem) {
|
||||||
|
if (oldItem.symbol === symbol) {
|
||||||
|
isUnique = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pull off row data
|
||||||
|
export default connect(
|
||||||
|
(state) => {
|
||||||
|
return {
|
||||||
|
rowData: state.rowData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)(HeaderComponent);
|
||||||
37
src/simpleReduxDynamicComponentExample/PriceRenderer.jsx
Normal file
37
src/simpleReduxDynamicComponentExample/PriceRenderer.jsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import React, {Component} from "react";
|
||||||
|
import {connect} from "react-redux";
|
||||||
|
|
||||||
|
class PriceRenderer extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
convertedValue: this.applyExchangeRate(props.exchangeRate, props.value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
this.setState({
|
||||||
|
convertedValue: this.applyExchangeRate(nextProps.exchangeRate, nextProps.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<span>{this.props.currencySymbol}{this.state.convertedValue}</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyExchangeRate = (exchangeRate, value) => {
|
||||||
|
return parseFloat(value * exchangeRate).toFixed(2); // simplified/naive exchange rate implementation!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
(state) => {
|
||||||
|
return {
|
||||||
|
currencySymbol: state.currencySymbol,
|
||||||
|
exchangeRate: state.exchangeRate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)(PriceRenderer);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import React, {Component} from "react";
|
||||||
|
import {Provider} from "react-redux";
|
||||||
|
import {createStore} from "redux";
|
||||||
|
// take this line out if you do not want to use ag-Grid-Enterprise
|
||||||
|
import "ag-grid-enterprise";
|
||||||
|
|
||||||
|
import HeaderComponent from "./HeaderComponent";
|
||||||
|
import GridComponent from "./GridComponent";
|
||||||
|
|
||||||
|
import gridData from "./gridDataReducer";
|
||||||
|
|
||||||
|
let store = createStore(gridData);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This component serves as a container for both the header and grid components. It's primarily here to act as a container
|
||||||
|
* for the redux Provider
|
||||||
|
*/
|
||||||
|
export default class SimpleReduxExample extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Provider store={store}>
|
||||||
|
<div>
|
||||||
|
<h1>Simple Redux Example using Connected React Components</h1>
|
||||||
|
<HeaderComponent />
|
||||||
|
<GridComponent />
|
||||||
|
</div>
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
13
src/simpleReduxDynamicComponentExample/gridDataActions.jsx
Normal file
13
src/simpleReduxDynamicComponentExample/gridDataActions.jsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export function updateRowData(rowData) {
|
||||||
|
return {
|
||||||
|
type: 'ROW_DATA_CHANGED',
|
||||||
|
rowData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function setCurrency(currencySymbol, exchangeRate) {
|
||||||
|
return {
|
||||||
|
type: 'CURRENCY_CHANGED',
|
||||||
|
currencySymbol,
|
||||||
|
exchangeRate
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/simpleReduxDynamicComponentExample/gridDataReducer.jsx
Normal file
17
src/simpleReduxDynamicComponentExample/gridDataReducer.jsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export default (state = {rowData: [], currencySymbol: '£', exchangeRate: 1}, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'ROW_DATA_CHANGED':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
rowData: action.rowData,
|
||||||
|
};
|
||||||
|
case 'CURRENCY_CHANGED':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
currencySymbol: action.currencySymbol,
|
||||||
|
exchangeRate: action.exchangeRate
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user