Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c338f851e0 | ||
|
|
58df719d45 | ||
|
|
2b6e3e8f41 | ||
|
|
f470a4c33d | ||
|
|
b51caf4746 | ||
|
|
30746397ef | ||
|
|
4998a51817 | ||
|
|
518a95ee89 | ||
|
|
3debbabe28 | ||
|
|
550f6c4077 | ||
|
|
99bc479b60 | ||
|
|
f5c1a4ba17 | ||
|
|
168a127e51 | ||
|
|
f9b1f8527a | ||
|
|
eee938e0e7 | ||
|
|
449a88e832 | ||
|
|
60181add9a | ||
|
|
847005c758 | ||
|
|
ca64dae64c | ||
|
|
3591b78e4b | ||
|
|
2fedd32efd | ||
|
|
849472a031 | ||
|
|
a2743f9076 | ||
|
|
d9724f7ab5 | ||
|
|
c0443ba6ef | ||
|
|
88752be90b | ||
|
|
2080ebb054 | ||
|
|
172c2a05b0 | ||
|
|
badb5ea485 | ||
|
|
c3af000642 | ||
|
|
7b6b609cdf | ||
|
|
5ffb682014 | ||
|
|
de18262157 | ||
|
|
1f6c1e41a1 | ||
|
|
ba3762bbd3 | ||
|
|
455f982d6c | ||
|
|
0c927ae3c5 | ||
|
|
2bd8d4c987 | ||
|
|
318f78de84 | ||
|
|
9ca52a727d | ||
|
|
56ccdd028c | ||
|
|
a5ccb6d622 | ||
|
|
25e1f1c184 | ||
|
|
8dd0f96b32 | ||
|
|
cf0796eb84 | ||
|
|
a64626e67e | ||
|
|
95445e558c | ||
|
|
79a6206026 | ||
|
|
f8ac0e5c98 | ||
|
|
06d9e88e88 | ||
|
|
f860a740f3 | ||
|
|
90ec337474 | ||
|
|
05d4341dfc | ||
|
|
df77361fd4 | ||
|
|
983b5974cf | ||
|
|
b030235bbc | ||
|
|
351d93b8fb | ||
|
|
43af1237bd | ||
|
|
fc76e85d77 | ||
|
|
6979c51eaf | ||
|
|
f035ee7a9d | ||
|
|
a982e0f2a7 | ||
|
|
cbb4a31be6 |
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/node_modules
|
||||
/dist
|
||||
package-lock.json
|
||||
17
README.md
@@ -1,29 +1,18 @@
|
||||
|
||||
ag-Grid React Example
|
||||
==============
|
||||
|
||||
Examples of running ag-Grid inside React application.
|
||||
|
||||
See [www.ag-grid.com](http://www.ag-grid.com) for an overview and full documentation.
|
||||
|
||||
Frameworks Supported
|
||||
====================
|
||||
Framework specific Getting Started guides:
|
||||
[Angular 1](https://www.ag-grid.com/best-angularjs-data-grid/) | [Angular 2](https://www.ag-grid.com/best-angular-2-data-grid/) | [Aurelia](https://www.ag-grid.com/best-aurelia-data-grid/)
|
||||
[Javascript](https://www.ag-grid.com/best-javascript-data-grid/) | [React](https://www.ag-grid.com/best-react-data-grid/) | [TypeScript](https://www.ag-grid.com/ag-grid-typescript-webpack-2/)
|
||||
[VueJS](https://www.ag-grid.com/best-vuejs-data-grid/) | [Web Components](https://www.ag-grid.com/best-web-component-data-grid/)
|
||||
|
||||
There are two examples:
|
||||
## Examples
|
||||
|
||||
1. standard - shows a typical grid demonstrating many ag-Grid features
|
||||
|
||||
2. large - shows a very large grid (767 columns and 1,000 rows) using React cell renderers
|
||||
|
||||
See [www.ag-grid.com](http://www.ag-grid.com) for full documentation and examples.
|
||||
|
||||
Building
|
||||
==============
|
||||
|
||||
To build:
|
||||
- `npm install`
|
||||
- `npm install webpack -g`
|
||||
- `npm run examples`, `npm run large` or `npm run trader`
|
||||
- navigate to localhost:8080
|
||||
|
||||
51
config/webpack.config.examples.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const path = require('path');
|
||||
|
||||
const SRC_DIR = path.resolve(__dirname, '../src-examples');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: SRC_DIR + "/index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../'),
|
||||
filename: "dist/react-examples.js"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: "style-loader!css-loader"
|
||||
},
|
||||
{
|
||||
test: /\.js$|\.jsx$/,
|
||||
include: SRC_DIR,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['@babel/preset-react', '@babel/preset-env'],
|
||||
plugins: [
|
||||
require('@babel/plugin-proposal-function-bind'),
|
||||
require('@babel/plugin-proposal-class-properties')
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
|
||||
loader: 'file-loader?name=[path]/[name].[ext]'
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
|
||||
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
|
||||
react: path.resolve('./node_modules/react')
|
||||
},
|
||||
extensions: ['.js', '.jsx']
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
devServer: {
|
||||
port: 8080,
|
||||
historyApiFallback: true
|
||||
}
|
||||
};
|
||||
46
config/webpack.config.large.js
Normal file
@@ -0,0 +1,46 @@
|
||||
const path = require('path');
|
||||
|
||||
const SRC_DIR = path.resolve(__dirname, '../src-large-data');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: SRC_DIR + "/index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../'),
|
||||
filename: "dist/react-large.js"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: "style-loader!css-loader"
|
||||
},
|
||||
{
|
||||
test: /\.js$|\.jsx$/,
|
||||
include: SRC_DIR,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['@babel/preset-react', '@babel/preset-env'],
|
||||
plugins: [
|
||||
require('@babel/plugin-proposal-function-bind'),
|
||||
require('@babel/plugin-proposal-class-properties')
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
|
||||
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
|
||||
react: path.resolve('./node_modules/react')
|
||||
},
|
||||
extensions: ['.js', '.jsx']
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
devServer: {
|
||||
port: 8080,
|
||||
}
|
||||
};
|
||||
46
config/webpack.config.trader.js
Normal file
@@ -0,0 +1,46 @@
|
||||
const path = require('path');
|
||||
|
||||
const SRC_DIR = path.resolve(__dirname, '../src-trader-dashboard');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: SRC_DIR + "/index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../'),
|
||||
filename: "dist/react-trader.js"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: "style-loader!css-loader"
|
||||
},
|
||||
{
|
||||
test: /\.js$|\.jsx$/,
|
||||
include: SRC_DIR,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['@babel/preset-react', '@babel/preset-env'],
|
||||
plugins: [
|
||||
require('@babel/plugin-proposal-function-bind'),
|
||||
require('@babel/plugin-proposal-class-properties')
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
|
||||
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
|
||||
react: path.resolve('./node_modules/react')
|
||||
},
|
||||
extensions: ['.js', '.jsx']
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
devServer: {
|
||||
port: 8080,
|
||||
}
|
||||
};
|
||||
8618
olympicWinners.json
76
package.json
@@ -1,30 +1,29 @@
|
||||
{
|
||||
"name": "ag-grid-react-example",
|
||||
"version": "13.3.0",
|
||||
"version": "19.1.2",
|
||||
"description": "Example Reach applicaiton using ag-Grid.",
|
||||
"main": "dist/ag-grid-react-example.js",
|
||||
"scripts": {
|
||||
"trader": "webpack-dev-server --content-base src-trader-dashboard/ --config webpack.config.trader.js --progress --colors --hot --inline",
|
||||
"examples": "webpack-dev-server --content-base src/ --config webpack.config.examples.js --progress --colors --hot --inline",
|
||||
"large": "webpack-dev-server --config webpack.config.large.js --progress --colors --hot --inline",
|
||||
"trader": "webpack-dev-server --content-base src-trader-dashboard/ --config config/webpack.config.trader.js --mode development --open",
|
||||
"examples": "webpack-dev-server --content-base src-examples/ --config config/webpack.config.examples.js --mode development --open",
|
||||
"large": "webpack-dev-server --content-base src-large-data/ --config config/webpack.config.large.js --mode development --open",
|
||||
"clean": "rimraf dist",
|
||||
"mkdirs": "mkdirp dist/trader/dist dist/examples/dist",
|
||||
"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 src-examples/images dist/examples/images && ncp src-examples/index.html dist/examples/index.html && ncp dist/react-examples.js dist/examples/dist/react-examples.js && ncp src-examples/ 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": "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-dashboard": "webpack --config webpack.config.trader.js --progress --profile --bail",
|
||||
"build-large": "webpack --config config/webpack.config.large.js --progress --profile --bail",
|
||||
"build-examples": "webpack --config config/webpack.config.examples.js --progress --profile --bail",
|
||||
"build-dashboard": "webpack --config config/webpack.config.trader.js --progress --profile --bail",
|
||||
"build-all": "npm run build-examples && npm run build-dashboard",
|
||||
"build": "npm run clean && npm run mkdirs && npm run build-all && npm run copy",
|
||||
"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",
|
||||
"start": "npm run examples"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ag-grid/ag-grid-react-example.git"
|
||||
},
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"react",
|
||||
"grid",
|
||||
@@ -38,39 +37,36 @@
|
||||
},
|
||||
"homepage": "http://www.ag-grid.com/",
|
||||
"devDependencies": {
|
||||
"babel-core": "6.24.x",
|
||||
"babel-loader": "6.4.x",
|
||||
"babel-preset-es2015": "6.24.x",
|
||||
"babel-preset-react": "6.24.x",
|
||||
"babel-preset-stage-0": "6.24.x",
|
||||
"babel-preset-stage-1": "6.24.x",
|
||||
"css-loader": "0.23.x",
|
||||
"@babel/core": "7.1.2",
|
||||
"babel-loader": "8.0.4",
|
||||
"@babel/preset-env": "7.1.0",
|
||||
"@babel/preset-react": "7.0.0",
|
||||
"@babel/plugin-proposal-class-properties": "7.1.0",
|
||||
"@babel/plugin-proposal-function-bind": "7.0.0",
|
||||
"css-loader": "1.0.0",
|
||||
"file-loader": "2.0.0",
|
||||
"gulp": "3.9.1",
|
||||
"merge2": "^1.2.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"ncp": "2.0.0",
|
||||
"prop-types": "15.5.x",
|
||||
"rimraf": "2.5.x",
|
||||
"style-loader": "0.13.x",
|
||||
"webpack": "1.12.x",
|
||||
"webpack-dev-server": "1.14.x",
|
||||
"gulp": "3.9.x",
|
||||
"gulp-typescript": "3.1.x",
|
||||
"merge2": "1.0.x",
|
||||
"typescript": "2.3.x"
|
||||
"prop-types": "15.6.2",
|
||||
"rimraf": "~2.6.2",
|
||||
"style-loader": "~0.23.0",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.0.8",
|
||||
"webpack-dev-server": "^3.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ag-grid": "13.3.x",
|
||||
"ag-grid-enterprise": "13.3.x",
|
||||
"ag-grid-react": "13.3.x",
|
||||
"bootstrap": "3.3.7",
|
||||
"ag-grid-community": "^19.1.0",
|
||||
"ag-grid-enterprise": "^19.1.0",
|
||||
"ag-grid-react": "^19.1.0",
|
||||
"bootstrap": "4.1.3",
|
||||
"d3": "4.9.1",
|
||||
"file-loader": "0.11.1",
|
||||
"lodash": "4.17.4",
|
||||
"react": "15.6.x",
|
||||
"react-dom": "15.6.x",
|
||||
"react-dom-factories": "1.0.0",
|
||||
"react-redux": "5.0.x",
|
||||
"react-router-dom": "4.2.x",
|
||||
"redux": "3.6.x",
|
||||
"url-search-params-polyfill": "1.2.0"
|
||||
"lodash": "^4.17.11",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-redux": "5.0.7",
|
||||
"react-router-dom": "4.3.1",
|
||||
"redux": "^4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src-examples/App.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, {Component} from "react";
|
||||
import {Redirect, Route, Switch} from "react-router-dom";
|
||||
|
||||
import NavItem from "./NavItem";
|
||||
|
||||
import RichGridDeclarativeExample from "./richGridDeclarativeExample/RichGridDeclarativeExample";
|
||||
import SimpleReduxDynamicExample from "./simpleReduxDynamicComponentExample/SimpleReduxExample";
|
||||
|
||||
const SideBar = () => (
|
||||
<div style={{float: "left", width: 335, marginRight: 25}}>
|
||||
<ul className="nav nav-pills">
|
||||
<NavItem to='/rich-grid-declarative'>Rich Grid with Declarative Markup</NavItem>
|
||||
<NavItem to='/simple-redux-dynamic'>Simple Redux Dynamic Component Example</NavItem>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<SideBar/>
|
||||
<div style={{float: "left"}}>
|
||||
<Switch>
|
||||
<Redirect from="/" exact to="/rich-grid-declarative"/>
|
||||
<Route exact path='/rich-grid-declarative' component={RichGridDeclarativeExample}/>
|
||||
<Route exact path='/simple-redux-dynamic' component={SimpleReduxDynamicExample}/>
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, {PropTypes} from 'react'
|
||||
import {Route, Link} from 'react-router-dom'
|
||||
import React from 'react'
|
||||
import * as PropTypes from 'prop-types';
|
||||
import {Link, Route} from 'react-router-dom'
|
||||
|
||||
// for bootstrap li active functionality
|
||||
export default function NavItem({children, to, exact}) {
|
||||
return (
|
||||
<Route path={to} exact={exact} children={({match}) => (
|
||||
<li className={match ? 'active' : null}>
|
||||
<Link to={to}>{children}</Link>
|
||||
<li className="nav-item">
|
||||
<Link className={match ? 'nav-link active' : 'nav-link'} to={to}>{children}</Link>
|
||||
</li>
|
||||
)}/>
|
||||
)
|
||||
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 99 B After Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 99 B After Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
|
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 289 B |
|
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
|
Before Width: | Height: | Size: 136 B After Width: | Height: | Size: 136 B |
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 89 B After Width: | Height: | Size: 89 B |
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
|
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
|
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 222 B |
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 739 B |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 883 B |
|
Before Width: | Height: | Size: 902 B After Width: | Height: | Size: 902 B |
|
Before Width: | Height: | Size: 953 B After Width: | Height: | Size: 953 B |
|
Before Width: | Height: | Size: 394 B After Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 893 B After Width: | Height: | Size: 893 B |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 570 B |
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="dist/react-examples.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="../dist/react-examples.js" charset="utf-8"></script>
|
||||
<!-- Example uses font awesome icons -->
|
||||
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
line-height: 1
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
div.card-body > a {
|
||||
margin-top: 5px
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import React from "react";
|
||||
import {render} from "react-dom";
|
||||
import {BrowserRouter} from "react-router-dom";
|
||||
|
||||
import "ag-grid-root/dist/styles/ag-grid.css";
|
||||
import "ag-grid-root/dist/styles/theme-fresh.css";
|
||||
import "ag-grid-community/dist/styles/ag-grid.css";
|
||||
import "ag-grid-community/dist/styles/ag-theme-balham.css";
|
||||
import "../node_modules/bootstrap/dist/css/bootstrap.css";
|
||||
|
||||
import App from "./App";
|
||||
@@ -37,7 +37,7 @@ export default class DateComponent extends React.Component {
|
||||
width: '30px'
|
||||
};
|
||||
let yyyyStyle = {
|
||||
width: '60px'
|
||||
width: '40px'
|
||||
};
|
||||
let resetStyle = {
|
||||
padding: '2px',
|
||||
@@ -41,16 +41,20 @@ export default class ProficiencyFilter extends React.Component {
|
||||
this.setState(newState, this.props.filterChangedCallback);
|
||||
}
|
||||
|
||||
|
||||
getModel() {
|
||||
return ''
|
||||
}
|
||||
|
||||
setModel(model) {
|
||||
}
|
||||
|
||||
render() {
|
||||
const rows = [];
|
||||
PROFICIENCY_NAMES.forEach((name) => {
|
||||
const selected = this.state.selected === name;
|
||||
rows.push(
|
||||
<div key={name}>
|
||||
<div key={name} style={{marginTop: 3}}>
|
||||
<label style={{paddingLeft: 4}}>
|
||||
<input type="radio" checked={selected} name={Math.random()}
|
||||
onChange={this.onButtonPressed.bind(this, name)}/>
|
||||
@@ -1,23 +1,28 @@
|
||||
import React, {Component} from "react";
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import {AgGridColumn, AgGridReact} from "ag-grid-react";
|
||||
import RowDataFactory from "./RowDataFactory";
|
||||
import ColDefFactory from "./ColDefFactory.jsx";
|
||||
import DateComponent from "./DateComponent.jsx";
|
||||
import SortableHeaderComponent from "./SortableHeaderComponent";
|
||||
import SkillsCellRenderer from './SkillsCellRenderer.jsx';
|
||||
import NameCellEditor from './NameCellEditor.jsx';
|
||||
import ProficiencyCellRenderer from './ProficiencyCellRenderer.jsx';
|
||||
import RefData from './RefData';
|
||||
import SkillsFilter from './SkillsFilter.jsx';
|
||||
import ProficiencyFilter from './ProficiencyFilter.jsx';
|
||||
import HeaderGroupComponent from './HeaderGroupComponent.jsx';
|
||||
import SortableHeaderComponent from './SortableHeaderComponent.jsx';
|
||||
|
||||
import "./RichGridExample.css";
|
||||
import "./RichGridDeclarativeExample.css";
|
||||
// take this line out if you do not want to use ag-Grid-Enterprise
|
||||
import "ag-grid-enterprise";
|
||||
|
||||
export default class RichGridExample extends Component {
|
||||
export default class RichGridDeclarativeExample extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
quickFilterText: null,
|
||||
showToolPanel: false,
|
||||
columnDefs: new ColDefFactory().createColDefs(),
|
||||
sideBar: false,
|
||||
rowData: new RowDataFactory().createRowData(),
|
||||
icons: {
|
||||
columnRemoveFromGroup: '<i class="fa fa-remove"/>',
|
||||
@@ -25,100 +30,89 @@ export default class RichGridExample extends Component {
|
||||
sortAscending: '<i class="fa fa-long-arrow-down"/>',
|
||||
sortDescending: '<i class="fa fa-long-arrow-up"/>',
|
||||
groupExpanded: '<i class="fa fa-minus-square-o"/>',
|
||||
groupContracted: '<i class="fa fa-plus-square-o"/>',
|
||||
columnGroupOpened: '<i class="fa fa-minus-square-o"/>',
|
||||
columnGroupClosed: '<i class="fa fa-plus-square-o"/>'
|
||||
groupContracted: '<i class="fa fa-plus-square-o"/>'
|
||||
}
|
||||
};
|
||||
|
||||
// the grid options are optional, because you can provide every property
|
||||
// to the grid via standard React properties. however, the react interface
|
||||
// doesn't block you from using the standard JavaScript interface if you
|
||||
// wish. Maybe you have the gridOptions stored as JSON on your server? If
|
||||
// you do, the providing the gridOptions as a standalone object is just
|
||||
// what you want!
|
||||
this.gridOptions = {
|
||||
//We register the react date component that ag-grid will use to render
|
||||
dateComponentFramework: DateComponent,
|
||||
// this is how you listen for events using gridOptions
|
||||
onModelUpdated: function () {
|
||||
console.log('event onModelUpdated received');
|
||||
},
|
||||
defaultColDef: {
|
||||
headerComponentFramework: SortableHeaderComponent,
|
||||
headerComponentParams: {
|
||||
menuIcon: 'fa-bars'
|
||||
}
|
||||
},
|
||||
// this is a simple property
|
||||
rowBuffer: 10, // no need to set this, the default is fine for almost all scenarios,
|
||||
floatingFilter: true
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
this.onRowSelected = this.onRowSelected.bind(this);
|
||||
this.onCellClicked = this.onCellClicked.bind(this);
|
||||
}
|
||||
|
||||
onToggleToolPanel(event) {
|
||||
this.setState({showToolPanel: event.target.checked});
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
/* Grid Events we're listening to */
|
||||
onGridReady = (params) => {
|
||||
this.api = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
}
|
||||
};
|
||||
|
||||
onCellClicked = (event) => {
|
||||
console.log('onCellClicked: ' + event.data.name + ', col ' + event.colIndex);
|
||||
};
|
||||
|
||||
onRowSelected = (event) => {
|
||||
console.log('onRowSelected: ' + event.node.data.name);
|
||||
};
|
||||
|
||||
/* Demo related methods */
|
||||
onToggleSidebar = (event) => {
|
||||
this.setState({sideBar: event.target.checked});
|
||||
};
|
||||
|
||||
deselectAll() {
|
||||
this.api.deselectAll();
|
||||
}
|
||||
|
||||
setCountryVisible(visible) {
|
||||
this.columnApi.setColumnVisible('country', visible);
|
||||
}
|
||||
|
||||
onQuickFilterText(event) {
|
||||
onQuickFilterText = (event) => {
|
||||
this.setState({quickFilterText: event.target.value});
|
||||
}
|
||||
};
|
||||
|
||||
onCellClicked(event) {
|
||||
console.log('onCellClicked: ' + event.data.name + ', col ' + event.colIndex);
|
||||
}
|
||||
|
||||
onRowSelected(event) {
|
||||
console.log('onRowSelected: ' + event.node.data.name);
|
||||
}
|
||||
|
||||
onRefreshData() {
|
||||
let newRowData = new RowDataFactory().createRowData();
|
||||
onRefreshData = () => {
|
||||
this.setState({
|
||||
rowData: newRowData
|
||||
rowData: new RowDataFactory().createRowData()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
invokeSkillsFilterMethod() {
|
||||
invokeSkillsFilterMethod = () => {
|
||||
let skillsFilter = this.api.getFilterInstance('skills');
|
||||
let componentInstance = skillsFilter.getFrameworkComponentInstance();
|
||||
componentInstance.helloFromSkillsFilter();
|
||||
}
|
||||
};
|
||||
|
||||
dobFilter() {
|
||||
let dateFilterComponent = this.gridOptions.api.getFilterInstance('dob');
|
||||
dateFilterComponent.setFilterType('equals');
|
||||
dateFilterComponent.setDateFrom('2000-01-01');
|
||||
dobFilter = () => {
|
||||
let dateFilterComponent = this.api.getFilterInstance('dob');
|
||||
dateFilterComponent.setModel({
|
||||
type: 'equals',
|
||||
dateFrom: '2000-01-01'
|
||||
});
|
||||
|
||||
// as the date filter is a React component, and its using setState internally, we need
|
||||
// to allow time for the state to be set (as setState is an async operation)
|
||||
// simply wait for the next tick
|
||||
setTimeout(() => {
|
||||
this.gridOptions.api.onFilterChanged();
|
||||
this.api.onFilterChanged();
|
||||
}, 0)
|
||||
};
|
||||
|
||||
static countryCellRenderer(params) {
|
||||
if (params.value) {
|
||||
return `<img border='0' width='15' height='10' style='margin-bottom: 2px' src='http://flags.fmcdn.net/data/flags/mini/${RefData.COUNTRY_CODES[params.value]}.png'> ${params.value}`;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static dateCellRenderer(params) {
|
||||
return RichGridDeclarativeExample.pad(params.value.getDate(), 2) + '/' +
|
||||
RichGridDeclarativeExample.pad(params.value.getMonth() + 1, 2) + '/' +
|
||||
params.value.getFullYear();
|
||||
}
|
||||
|
||||
static pad(num, totalStringSize) {
|
||||
let asString = num + "";
|
||||
while (asString.length < totalStringSize) asString = "0" + asString;
|
||||
return asString;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{width: '900px'}}>
|
||||
<h1>Rich Grid Example</h1>
|
||||
<h1>Rich Grid with Declarative Markup Example</h1>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<div style={{float: "left"}}>
|
||||
<b>Employees Skills and Contact Details</b><span id="rowCount"/>
|
||||
@@ -129,83 +123,123 @@ export default class RichGridExample extends Component {
|
||||
<span>
|
||||
Grid API:
|
||||
<button onClick={() => {
|
||||
this.refs.myGrid.api.selectAll()
|
||||
this.api.selectAll()
|
||||
}} className="btn btn-primary">Select All</button>
|
||||
<button onClick={this.deselectAll.bind(this)}
|
||||
className="btn btn-primary">Clear Selection</button>
|
||||
<button onClick={() => {
|
||||
this.api.deselectAll()
|
||||
}} className="btn btn-primary">Clear Selection</button>
|
||||
</span>
|
||||
<span style={{float: "right"}}>
|
||||
Column API:
|
||||
<button onClick={this.setCountryVisible.bind(this, false)} className="btn btn-primary">Hide Country Column</button>
|
||||
<button onClick={this.setCountryVisible.bind(this, true)} className="btn btn-primary">Show Country Column</button>
|
||||
<button onClick={() => {
|
||||
this.columnApi.setColumnVisible('country', false)
|
||||
}} className="btn btn-primary">Hide Country Column</button>
|
||||
<button onClick={() => {
|
||||
this.columnApi.setColumnVisible('country', true)
|
||||
}} className="btn btn-primary">Show Country Column</button>
|
||||
</span>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%", marginTop: 10, marginBottom: 10}}>
|
||||
<div style={{float: "left"}}>
|
||||
<label>
|
||||
<input type="checkbox" onChange={this.onToggleToolPanel.bind(this)}
|
||||
style={{marginRight: 5}}/>
|
||||
Show Tool Panel
|
||||
<input type="checkbox" onChange={this.onToggleSidebar} style={{marginRight: 5}}/>
|
||||
Show Side Bar
|
||||
</label>
|
||||
</div>
|
||||
<div style={{float: "left", marginLeft: 20}}>
|
||||
<button onClick={this.onRefreshData.bind(this)} className="btn btn-primary">Refresh Data
|
||||
</button>
|
||||
<button onClick={this.onRefreshData} className="btn btn-primary">Refresh Data</button>
|
||||
</div>
|
||||
<div style={{float: "left", marginLeft: 20}}>
|
||||
<input type="text" onChange={this.onQuickFilterText.bind(this)}
|
||||
placeholder="Type text to filter..."/>
|
||||
<input type="text" onChange={this.onQuickFilterText} placeholder="Type text to filter..."/>
|
||||
</div>
|
||||
<div style={{float: "right"}}>
|
||||
Filter API:
|
||||
<button onClick={this.invokeSkillsFilterMethod.bind(this, false)}
|
||||
<button onClick={this.invokeSkillsFilterMethod}
|
||||
className="btn btn-primary">Invoke Skills Filter Method
|
||||
</button>
|
||||
<button onClick={this.dobFilter.bind(this)} className="btn btn-primary">DOB equals to
|
||||
01/01/2000
|
||||
<button onClick={this.dobFilter} className="btn btn-primary">DOB equals to 01/01/2000
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{height: 400, width: 900}} className="ag-fresh">
|
||||
<div style={{height: 400, width: 900}} className="ag-theme-balham">
|
||||
<AgGridReact
|
||||
ref="myGrid"
|
||||
// gridOptions is optional - it's possible to provide
|
||||
// all values as React props
|
||||
gridOptions={this.gridOptions}
|
||||
|
||||
// listening for events
|
||||
onGridReady={this.onGridReady}
|
||||
onRowSelected={this.onRowSelected}
|
||||
onCellClicked={this.onCellClicked}
|
||||
|
||||
// binding to simple properties
|
||||
showToolPanel={this.state.showToolPanel}
|
||||
sideBar={this.state.sideBar}
|
||||
quickFilterText={this.state.quickFilterText}
|
||||
|
||||
// binding to an object property
|
||||
icons={this.state.icons}
|
||||
|
||||
// binding to array properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
// no binding, just providing hard coded strings for the properties
|
||||
suppressRowClickSelection="true"
|
||||
// boolean properties will default to true if provided (ie enableColResize => enableColResize="true")
|
||||
suppressRowClickSelection
|
||||
rowSelection="multiple"
|
||||
enableColResize="true"
|
||||
enableSorting="true"
|
||||
enableFilter="true"
|
||||
groupHeaders="true"
|
||||
rowHeight="22"
|
||||
/>
|
||||
enableColResize
|
||||
enableSorting
|
||||
enableFilter
|
||||
floatingFilter
|
||||
groupHeaders
|
||||
|
||||
// setting grid wide date component
|
||||
dateComponentFramework={DateComponent}
|
||||
|
||||
// setting default column properties
|
||||
defaultColDef={{
|
||||
headerComponentFramework: SortableHeaderComponent,
|
||||
headerComponentParams: {
|
||||
menuIcon: 'fa-bars'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AgGridColumn headerName="#" width={30}
|
||||
checkboxSelection suppressSorting suppressMenu suppressFilter pinned>
|
||||
</AgGridColumn>
|
||||
<AgGridColumn headerName="Employee" headerGroupComponentFramework={HeaderGroupComponent}>
|
||||
<AgGridColumn field="name" width={150}
|
||||
cellEditorFramework={NameCellEditor}
|
||||
enableRowGroup enablePivot pinned editable/>
|
||||
<AgGridColumn field="country" width={150}
|
||||
cellRenderer={RichGridDeclarativeExample.countryCellRenderer}
|
||||
filterParams={{
|
||||
cellRenderer: RichGridDeclarativeExample.countryCellRenderer,
|
||||
cellHeight: 20
|
||||
}}
|
||||
enableRowGroup enablePivot pinned editable/>
|
||||
<AgGridColumn field="dob" width={175} headerName="DOB" filter="agDateColumnFilter"
|
||||
pinned columnGroupShow="open"
|
||||
cellRenderer={RichGridDeclarativeExample.dateCellRenderer}/>
|
||||
</AgGridColumn>
|
||||
<AgGridColumn headerName="IT Skills">
|
||||
<AgGridColumn field="skills" width={120} enableRowGroup enablePivot suppressSorting
|
||||
cellRendererFramework={SkillsCellRenderer}
|
||||
filterFramework={SkillsFilter}/>
|
||||
<AgGridColumn field="proficiency" width={135} enableValue
|
||||
cellRendererFramework={ProficiencyCellRenderer}
|
||||
filterFramework={ProficiencyFilter}/>
|
||||
</AgGridColumn>
|
||||
<AgGridColumn headerName="Contact">
|
||||
<AgGridColumn field="mobile" width={150} filter="text"/>
|
||||
<AgGridColumn field="landline" width={150} filter="text"/>
|
||||
<AgGridColumn field="address" width={500} filter="text"/>
|
||||
</AgGridColumn>
|
||||
</AgGridReact>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{marginTop: 10}}>
|
||||
<div className="row">
|
||||
<div className="col-sm-12"><h1>Rich Grid Example</h1></div>
|
||||
<div className="col-sm-12"><h1>Rich Grid with Declarative Markup Example</h1></div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<h5>This example demonstrates many features of ag-Grid.</h5>
|
||||
<h5>This example demonstrates many features of ag-Grid, with Grid and Column Definition
|
||||
defined declaratively (i.e. with markup).</h5>
|
||||
<p><span style={{fontWeight: 500}}>Select All/Clear Selection</span>: Select or Deselect
|
||||
All
|
||||
Rows</p>
|
||||
@@ -213,10 +247,10 @@ export default class RichGridExample extends Component {
|
||||
All
|
||||
Rows
|
||||
(expand the Employee column to show the Country column first)</p>
|
||||
<p><span style={{fontWeight: 500}}>Toggle The Tool Panel</span>: Let your users Pivot,
|
||||
<p><span style={{fontWeight: 500}}>Toggle The Side Bar</span>: Let your users Pivot,
|
||||
Group
|
||||
and
|
||||
Aggregate using the Tool Panel</p>
|
||||
Aggregate using the Side Bar</p>
|
||||
<p><span style={{fontWeight: 500}}>Refresh Data</span>: Dynamically Update Grid Data</p>
|
||||
<p><span style={{fontWeight: 500}}>Quick Filter</span>: Perform Quick Grid Wide
|
||||
Filtering
|
||||
@@ -288,12 +322,11 @@ export default class RichGridExample extends Component {
|
||||
<div className="col-sm-4">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<h4 className="card-title">Tool Panel</h4>
|
||||
<h4 className="card-title">Side Bar</h4>
|
||||
<p className="card-text">Let your users Pivot, Group and Aggregate using the
|
||||
Tool
|
||||
Panel</p>
|
||||
<a target="_blank" href="https://www.ag-grid.com//javascript-grid-tool-panel/"
|
||||
className="btn btn-primary">Tool Panel</a>
|
||||
Side Bar</p>
|
||||
<a target="_blank" href="https://www.ag-grid.com//javascript-grid-side-bar/"
|
||||
className="btn btn-primary">Side Bar</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,13 @@
|
||||
import React, {Component} from "react";
|
||||
import * as PropTypes from "prop-types";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import {connect} from "react-redux";
|
||||
|
||||
import PriceRenderer from "./PriceRenderer";
|
||||
|
||||
const ThemeContext = React.createContext('light');
|
||||
|
||||
/*
|
||||
* This component serves to display the row data (provided by redux)
|
||||
*/
|
||||
@@ -14,8 +17,14 @@ class GridComponent extends Component {
|
||||
|
||||
this.state = {
|
||||
columnDefs: [
|
||||
{headerName: 'Symbol', field: 'symbol'},
|
||||
{headerName: 'Price', field: 'price', cellClass: 'align-right', cellRendererFramework: PriceRenderer}
|
||||
{
|
||||
field: 'symbol'
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
cellClass: 'align-right',
|
||||
cellRendererFramework: PriceRenderer
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -33,12 +42,15 @@ class GridComponent extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 400, width: 900, marginTop: 15}}
|
||||
className="ag-fresh">
|
||||
className="ag-theme-balham">
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.props.rowData}
|
||||
|
||||
reactNext={true}
|
||||
reduxStore={this.context.store} // must be supplied when using redux with reactNext
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
@@ -47,6 +59,10 @@ class GridComponent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
GridComponent.contextTypes = {
|
||||
store: PropTypes.object // must be supplied when using redux with reactNext
|
||||
};
|
||||
|
||||
// pull off row data changes
|
||||
export default connect(
|
||||
(state) => {
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, {Component} from "react";
|
||||
import {connect} from "react-redux";
|
||||
|
||||
import FontContext from './fontContext'
|
||||
|
||||
class PriceRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -18,7 +20,9 @@ class PriceRenderer extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>{this.props.currencySymbol}{this.state.convertedValue}</span>
|
||||
<FontContext.Consumer>
|
||||
{fontWeight => <span style={{fontWeight}}> {this.props.currencySymbol}{this.state.convertedValue}</span> }
|
||||
</FontContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,5 +37,8 @@ export default connect(
|
||||
currencySymbol: state.currencySymbol,
|
||||
exchangeRate: state.exchangeRate
|
||||
}
|
||||
}
|
||||
},
|
||||
null,
|
||||
null,
|
||||
{withRef: true} // must be supplied for react/redux when using GridOptions.reactNext
|
||||
)(PriceRenderer);
|
||||
@@ -9,6 +9,8 @@ import GridComponent from "./GridComponent";
|
||||
|
||||
import gridData from "./gridDataReducer";
|
||||
|
||||
import FontContext from './fontContext'
|
||||
|
||||
let store = createStore(gridData);
|
||||
|
||||
/*
|
||||
@@ -25,8 +27,10 @@ export default class SimpleReduxExample extends Component {
|
||||
<Provider store={store}>
|
||||
<div>
|
||||
<h1>Simple Redux Example using Connected React Components</h1>
|
||||
<HeaderComponent />
|
||||
<GridComponent />
|
||||
<HeaderComponent/>
|
||||
<FontContext.Provider value="bold">
|
||||
<GridComponent/>
|
||||
</FontContext.Provider>
|
||||
</div>
|
||||
</Provider>
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
import React from "react";
|
||||
|
||||
export default React.createContext('normal');
|
||||
@@ -4,6 +4,7 @@ export function updateRowData(rowData) {
|
||||
rowData
|
||||
}
|
||||
}
|
||||
|
||||
export function setCurrency(currencySymbol, exchangeRate) {
|
||||
return {
|
||||
type: 'CURRENCY_CHANGED',
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="dist/bundle.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="../dist/react-large.js" charset="utf-8"></script>
|
||||
<!-- Example uses font awesome icons -->
|
||||
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
</head>
|
||||
@@ -3,9 +3,9 @@
|
||||
import ReactDOM from 'react-dom';
|
||||
import React from 'react';
|
||||
import LargeGrid from './largeGrid.jsx';
|
||||
// is there a better way of doing this?
|
||||
import 'ag-grid-root/dist/styles/ag-grid.css';
|
||||
import 'ag-grid-root/dist/styles/theme-fresh.css';
|
||||
|
||||
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||
import 'ag-grid-community/dist/styles/ag-theme-fresh.css';
|
||||
|
||||
// waiting for dom to load before booting react. we could alternatively
|
||||
// put the index.js reference at the end fo the index.html, but i prefer this way.
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import {reactCellRendererFactory} from 'ag-grid-react';
|
||||
import React, {Component} from 'react';
|
||||
import SimpleCellRenderer from './simpleCellRenderer.jsx';
|
||||
|
||||
import {AgGridReact} from 'ag-grid-react';
|
||||
@@ -7,7 +6,7 @@ import {AgGridReact} from 'ag-grid-react';
|
||||
// put this line in to use ag-Grid enterprise
|
||||
// import 'ag-grid-enterprise';
|
||||
|
||||
export default class MyApp extends React.Component {
|
||||
export default class MyApp extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -22,22 +21,22 @@ export default class MyApp extends React.Component {
|
||||
|
||||
createColumnNames() {
|
||||
// creates column names by iterating the alphabet twice, eg {'aa','ab','ac',.....'zz'}
|
||||
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
||||
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
||||
this.columnNames = [];
|
||||
alphabet.forEach( letter1 => {
|
||||
alphabet.forEach( letter2 => {
|
||||
alphabet.forEach(letter1 => {
|
||||
alphabet.forEach(letter2 => {
|
||||
this.columnNames.push(letter1 + letter2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createRowData() {
|
||||
var rowData = [];
|
||||
const rowData = [];
|
||||
|
||||
for (var i = 0; i<1000; i++) {
|
||||
var item = {};
|
||||
this.columnNames.forEach( colName => {
|
||||
item[colName] = '('+colName.toUpperCase()+','+i+')'
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const item = {};
|
||||
this.columnNames.forEach(colName => {
|
||||
item[colName] = '(' + colName.toUpperCase() + ',' + i + ')'
|
||||
});
|
||||
rowData.push(item);
|
||||
}
|
||||
@@ -46,9 +45,9 @@ export default class MyApp extends React.Component {
|
||||
}
|
||||
|
||||
createColumnDefs() {
|
||||
var columnDefs = [];
|
||||
const columnDefs = [];
|
||||
|
||||
this.columnNames.forEach( colName => {
|
||||
this.columnNames.forEach(colName => {
|
||||
columnDefs.push({
|
||||
headerName: colName.toUpperCase(),
|
||||
field: colName,
|
||||
@@ -62,8 +61,8 @@ export default class MyApp extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: '100%'}} className="ag-fresh">
|
||||
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.rowData} />
|
||||
<div style={{height: '100%'}} className="ag-theme-fresh">
|
||||
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.rowData}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,9 +3,6 @@ import {connect} from "react-redux";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
|
||||
import assign from "lodash/assign";
|
||||
import uniq from "lodash/uniq";
|
||||
|
||||
class FxQuoteMatrix extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -60,7 +57,7 @@ class FxQuoteMatrix extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 410, width: 800}}
|
||||
className="ag-fresh">
|
||||
className="ag-theme-fresh">
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
|
||||
@@ -24,21 +24,21 @@ export default class extends Component {
|
||||
field: 'price',
|
||||
headerName: 'Price',
|
||||
valueFormatter: this.numberFormatter,
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellStyle: {'text-align': 'right'}
|
||||
},
|
||||
{
|
||||
field: 'bid',
|
||||
headerName: 'Bid',
|
||||
valueFormatter: this.numberFormatter,
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellStyle: {'text-align': 'right'}
|
||||
},
|
||||
{
|
||||
field: 'ask',
|
||||
headerName: 'Ask',
|
||||
valueFormatter: this.numberFormatter,
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellStyle: {'text-align': 'right'}
|
||||
}
|
||||
]
|
||||
@@ -151,7 +151,7 @@ export default class extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 410, width: 800}}
|
||||
className="ag-fresh">
|
||||
className="ag-theme-fresh">
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
|
||||
@@ -17,21 +17,21 @@ class TopMoversGrid extends Component {
|
||||
field: 'last',
|
||||
headerName: 'Last',
|
||||
headerClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClass: 'align-right'
|
||||
},
|
||||
{
|
||||
field: 'net',
|
||||
headerName: 'Net',
|
||||
headerClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClass: 'align-right'
|
||||
},
|
||||
{
|
||||
field: 'pct_net_change',
|
||||
headerName: '% NC',
|
||||
headerClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClass: 'align-right',
|
||||
sort: 'desc',
|
||||
valueFormatter(params) {
|
||||
@@ -62,7 +62,7 @@ class TopMoversGrid extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 410, width: 400}}
|
||||
className="ag-fresh">
|
||||
className="ag-theme-fresh">
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="dist/react-trader.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="../dist/react-trader.js" charset="utf-8"></script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
|
||||
@@ -5,8 +5,8 @@ import {render} from "react-dom";
|
||||
|
||||
import {Provider} from "react-redux";
|
||||
|
||||
import "ag-grid-root/dist/styles/ag-grid.css";
|
||||
import "ag-grid-root/dist/styles/theme-fresh.css";
|
||||
import "ag-grid-community/dist/styles/ag-grid.css";
|
||||
import "ag-grid-community/dist/styles/ag-theme-fresh.css";
|
||||
|
||||
import StoreService from './services/StoreService';
|
||||
import TraderDashboard from "./components/TraderDashboard.jsx";
|
||||
|
||||
@@ -120,7 +120,7 @@ const FX_DELTA_HEADERS = [
|
||||
field: 'last',
|
||||
headerName: 'Last',
|
||||
headerClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClass: 'align-right',
|
||||
width: 100
|
||||
},
|
||||
@@ -128,7 +128,7 @@ const FX_DELTA_HEADERS = [
|
||||
field: 'net',
|
||||
headerName: 'Net',
|
||||
headerClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClass: 'align-right',
|
||||
width: 90
|
||||
},
|
||||
@@ -145,7 +145,7 @@ const FX_DELTA_HEADERS = [
|
||||
headerName: symbol,
|
||||
width: 67,
|
||||
cellClass: 'align-right',
|
||||
cellRenderer: 'animateShowChange',
|
||||
cellRenderer: 'agAnimateShowChangeCellRenderer',
|
||||
cellClassRules: {
|
||||
'fx-positive': 'x > 0.8',
|
||||
'fx-null': 'x === null',
|
||||
|
||||
159
src/App.jsx
@@ -1,159 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
import {Redirect, Route, Switch} from "react-router-dom";
|
||||
|
||||
import NavItem from "./NavItem";
|
||||
|
||||
import DynamicComponentsExample from "./dynamicComponentExample/DynamicComponentsExample";
|
||||
import RichGridExample from "./richGridExample/RichGridExample";
|
||||
import RichComponentsExample from "./richComponentExample/RichComponentsExample";
|
||||
import EditorComponentsExample from "./editorComponentExample/EditorComponentsExample";
|
||||
import PinnedRowComponentExample from "./pinnedRowExample/PinnedRowComponentExample";
|
||||
import FullWidthComponentExample from "./fullWidthExample/FullWidthComponentExample";
|
||||
import GroupedRowInnerRendererComponentExample from "./groupedRowInnerRendererExample/GroupedRowInnerRendererComponentExample";
|
||||
import FilterComponentExample from "./filterComponentExample/FilterComponentExample";
|
||||
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
|
||||
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
|
||||
import FloatingFilterGridExample from "./floatingFilter/FloatingFilterGridExample";
|
||||
import SimpleReduxDynamicExample from "./simpleReduxDynamicComponentExample/SimpleReduxExample";
|
||||
|
||||
const SideBar = () => (
|
||||
<div style={{float: "left", width: 335, marginRight: 25}}>
|
||||
<ul className="nav nav-pills nav-stacked">
|
||||
<NavItem to='/rich-grid'>Rich Grid Example</NavItem>
|
||||
<NavItem to='/dynamic'>Dynamic React Component Example</NavItem>
|
||||
<NavItem to='/rich-dynamic'>Dynamic React Components - Richer Example</NavItem>
|
||||
<NavItem to='/editor'>Cell Editor Component Example</NavItem>
|
||||
<NavItem to='/floating-row'>Floating Row Renderer Example</NavItem>
|
||||
<NavItem to='/full-width'>Full Width Renderer Example</NavItem>
|
||||
<NavItem to='/group-row'>Grouped Row Inner Renderer Example</NavItem>
|
||||
<NavItem to='/filter'>Filters Component Example</NavItem>
|
||||
<NavItem to='/master-detail'>Master Detail Example</NavItem>
|
||||
<NavItem to='/floating-filter'>Floating Filters</NavItem>
|
||||
<NavItem to='/simple-redux'>Simple Redux Example</NavItem>
|
||||
<NavItem to='/simple-redux-dynamic'>Simple Redux Dynamic Component Example</NavItem>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<SideBar/>
|
||||
<div style={{float: "left"}}>
|
||||
<Switch>
|
||||
<Redirect from="/" exact to="/rich-grid"/>
|
||||
<Route exact path='/rich-grid' component={RichGridExample}/>
|
||||
<Route exact path='/dynamic' component={DynamicComponentsExample}/>
|
||||
<Route exact path='/rich-dynamic' component={RichComponentsExample}/>
|
||||
<Route exact path='/editor' component={EditorComponentsExample}/>
|
||||
<Route exact path='/floating-row' component={PinnedRowComponentExample}/>
|
||||
<Route exact path='/full-width' component={FullWidthComponentExample}/>
|
||||
<Route exact path='/group-row' component={GroupedRowInnerRendererComponentExample}/>
|
||||
<Route exact path='/filter' component={FilterComponentExample}/>
|
||||
<Route exact path='/master-detail' component={MasterDetailExample}/>
|
||||
<Route exact path='/floating-filter' component={FloatingFilterGridExample}/>
|
||||
<Route exact path='/simple-redux' component={SimpleReduxExample}/>
|
||||
<Route exact path='/simple-redux-dynamic' component={SimpleReduxDynamicExample}/>
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
/*
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
let searchParams = new URLSearchParams(window.location.search);
|
||||
let fromDocs = searchParams.has("fromDocs");
|
||||
let example = searchParams.has("example") ? searchParams.get("example") : 'rich-grid';
|
||||
|
||||
this.state = {
|
||||
example,
|
||||
fromDocs
|
||||
};
|
||||
|
||||
this.setExample = this.setExample.bind(this);
|
||||
}
|
||||
|
||||
setExample(example) {
|
||||
this.setState({
|
||||
example
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let header = null;
|
||||
if (!this.state.fromDocs) {
|
||||
header = (
|
||||
<ul className="nav nav-pills">
|
||||
<li role="presentation" className={this.state.example === 'rich-grid' ? 'active' : null} onClick={() => this.setExample("rich-grid")}><a href="#">Rich Grid 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 === 'editor' ? 'active' : null} onClick={() => this.setExample("editor")}><a href="#">Cell Editor Component 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 === '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 === '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 === '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>)
|
||||
}
|
||||
|
||||
let example = null;
|
||||
switch (this.state.example) {
|
||||
case 'dynamic':
|
||||
example = <DynamicComponentsExample/>;
|
||||
break;
|
||||
case 'rich-dynamic':
|
||||
example = <RichComponentsExample/>;
|
||||
break;
|
||||
case 'editor':
|
||||
example = <EditorComponentsExample/>;
|
||||
break;
|
||||
case 'pinned-row':
|
||||
example = <PinnedRowComponentExample/>;
|
||||
break;
|
||||
case 'full-width':
|
||||
example = <FullWidthComponentExample/>;
|
||||
break;
|
||||
case 'group-row':
|
||||
example = <GroupedRowInnerRendererComponentExample/>;
|
||||
break;
|
||||
case 'filter':
|
||||
example = <FilterComponentExample/>;
|
||||
break;
|
||||
case 'master-detail':
|
||||
example = <MasterDetailExample/>;
|
||||
break;
|
||||
case 'simple-redux':
|
||||
example = <SimpleReduxExample/>;
|
||||
break;
|
||||
case 'floating-filter':
|
||||
example = <FloatingFilterGridExample/>;
|
||||
break;
|
||||
case 'simple-redux-dynamic':
|
||||
example = <SimpleReduxDynamicExample/>;
|
||||
break;
|
||||
default:
|
||||
example = <RichGridExample/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{header}
|
||||
{example}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default App
|
||||
*/
|
||||
@@ -1,19 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class ChildMessageRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.invokeParentMethod = this.invokeParentMethod.bind(this);
|
||||
}
|
||||
|
||||
invokeParentMethod() {
|
||||
this.props.context.componentParent.methodFromParent(`Row: ${this.props.node.rowIndex}, Col: ${this.props.colDef.headerName}`)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span><button style={{height: 20, lineHeight: 0.5}} onClick={this.invokeParentMethod} className="btn btn-info">Invoke Parent</button></span>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class CubeRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: this.valueSquared()
|
||||
};
|
||||
}
|
||||
|
||||
valueSquared() {
|
||||
return this.props.value * this.props.value * this.props.value;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>{this.state.value}</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class CurrencyRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: props.value
|
||||
}
|
||||
}
|
||||
|
||||
formatValueToCurrency(currency, value) {
|
||||
return `${currency}${value}`
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
refresh(params) {
|
||||
if(params.value !== this.state.value) {
|
||||
this.setState({
|
||||
value: params.value.toFixed(2)
|
||||
})
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>{this.formatValueToCurrency('EUR', this.state.value)}</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,153 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import SquareRenderer from "./SquareRenderer";
|
||||
import CubeRenderer from "./CubeRenderer";
|
||||
import ParamsRenderer from "./ParamsRenderer";
|
||||
import CurrencyRenderer from "./CurrencyRenderer";
|
||||
import ChildMessageRenderer from "./ChildMessageRenderer";
|
||||
|
||||
export default class DynamicComponentsExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
gridOptions: {
|
||||
context: {
|
||||
componentParent: this
|
||||
}
|
||||
},
|
||||
|
||||
rowData: DynamicComponentsExample.createRowData(),
|
||||
|
||||
columnDefs: DynamicComponentsExample.createColumnDefs()
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
this.refreshEvenRowsCurrencyData = this.refreshEvenRowsCurrencyData.bind(this);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
methodFromParent(cell) {
|
||||
alert(`Parent Component Method from ${cell}!`);
|
||||
}
|
||||
|
||||
refreshEvenRowsCurrencyData() {
|
||||
this.gridApi.forEachNode(rowNode => {
|
||||
if (rowNode.data.value % 2 === 0) {
|
||||
rowNode.setDataValue('currency', rowNode.data.value + Number(Math.random().toFixed(2)))
|
||||
}
|
||||
});
|
||||
|
||||
this.gridApi.refreshCells({
|
||||
columns: ['currency']
|
||||
})
|
||||
}
|
||||
|
||||
static createColumnDefs() {
|
||||
return [
|
||||
{headerName: "Row", field: "row", width: 100},
|
||||
{
|
||||
headerName: "Square",
|
||||
field: "value",
|
||||
cellRendererFramework: SquareRenderer,
|
||||
editable: true,
|
||||
colId: "square",
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
headerName: "Cube",
|
||||
field: "value",
|
||||
cellRendererFramework: CubeRenderer,
|
||||
colId: "cube",
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
headerName: "Row Params",
|
||||
field: "row",
|
||||
cellRendererFramework: ParamsRenderer,
|
||||
colId: "params",
|
||||
width: 215
|
||||
},
|
||||
{
|
||||
headerName: "Currency",
|
||||
field: "currency",
|
||||
cellRendererFramework: CurrencyRenderer,
|
||||
colId: "currency",
|
||||
width: 135
|
||||
},
|
||||
{
|
||||
headerName: "Child/Parent",
|
||||
field: "value",
|
||||
cellRendererFramework: ChildMessageRenderer,
|
||||
colId: "params",
|
||||
width: 120
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
static createRowData() {
|
||||
let rowData = [];
|
||||
|
||||
for (let i = 0; i < 15; i++) {
|
||||
rowData.push({
|
||||
row: "Row " + i,
|
||||
value: i,
|
||||
currency: 1 + Number(Math.random()).toFixed(2)
|
||||
});
|
||||
}
|
||||
|
||||
return rowData;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 400, width: 900}}
|
||||
className="ag-fresh">
|
||||
<h1>Dynamic React Component Example</h1>
|
||||
<button onClick={this.refreshEvenRowsCurrencyData} style={{marginBottom: 10}} className="btn btn-primary">Refresh Even Row Currency Data</button>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
gridOptions={this.state.gridOptions}
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
<div className="row">
|
||||
<div className="col-sm-12"><h1>Dynamic React Component Example</h1></div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<h5>This example demonstrates Dynamic React Components with ag-Grid, Parent/Child Communication (cell component to parent grid component), as well as
|
||||
dynamic data updates of the <code>Currency</code> column.</h5>
|
||||
<p><span style={{fontWeight: "bold"}}>Square, Cube, Row Params, Currency and Child/Parent</span>: React Components within the Grid</p>
|
||||
<p><span style={{fontWeight: "bold"}}>Currency (Pipe)</span>: An React Component mimicking a Currency Pipe, dynamically updated with the button above.</p>
|
||||
<p><span style={{fontWeight: "bold"}}>Child/Parent</span>: Demonstrates the Child Cell Component communicating with the Parent Grid Component.</p>
|
||||
<p><span style={{fontWeight: "bold"}}>Refresh Even Row Currency Data</span>: Dynamically Updates Event Rows Currency Value. Only the Currency column will be re-rendered.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<h4 className="card-title">React Functionality</h4>
|
||||
<p className="card-text">Utilise React Components within ag-Grid</p>
|
||||
<a target="_blank" href="https://www.ag-grid.com/best-react-data-grid/?framework=react" className="btn btn-primary">React with ag-Grid</a>
|
||||
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-rendering-components/?framework=react" className="btn btn-primary">React Renderers</a>
|
||||
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-data-update/" className="btn btn-primary">Updating Data</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class ParamsRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>Field: {this.props.colDef.field}, Value: {this.props.value}</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class SquareRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: this.valueSquared()
|
||||
};
|
||||
}
|
||||
|
||||
valueSquared() {
|
||||
return this.props.value * this.props.value;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>{this.state.value}</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,132 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import MoodRenderer from "./MoodRenderer";
|
||||
import MoodEditor from "./MoodEditor";
|
||||
import NumericEditor from "./NumericEditor";
|
||||
|
||||
export default class EditorComponentsExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
rowData: EditorComponentsExample.createRowData(),
|
||||
columnDefs: EditorComponentsExample.createColumnDefs()
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
static createColumnDefs() {
|
||||
return [
|
||||
{
|
||||
headerName: "Name",
|
||||
field: "name",
|
||||
width: 300,
|
||||
editable: true,
|
||||
cellEditor: 'richSelect',
|
||||
cellEditorParams: {
|
||||
values: [
|
||||
"Bob",
|
||||
"Harry",
|
||||
"Sally",
|
||||
"Mary",
|
||||
"John",
|
||||
"Jack",
|
||||
"Sue",
|
||||
"Sean",
|
||||
"Niall",
|
||||
"Albert",
|
||||
"Fred",
|
||||
"Jenny",
|
||||
"Larry"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
headerName: "Mood",
|
||||
field: "mood",
|
||||
cellRendererFramework: MoodRenderer,
|
||||
cellEditorFramework: MoodEditor,
|
||||
editable: true,
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
headerName: "Numeric",
|
||||
field: "number",
|
||||
cellEditorFramework: NumericEditor,
|
||||
editable: true,
|
||||
width: 250
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
static createRowData() {
|
||||
return [
|
||||
{name: "Bob", mood: "Happy", number: 10},
|
||||
{name: "Harry", mood: "Sad", number: 3},
|
||||
{name: "Sally", mood: "Happy", number: 20},
|
||||
{name: "Mary", mood: "Sad", number: 5},
|
||||
{name: "John", mood: "Happy", number: 15},
|
||||
{name: "Jack", mood: "Happy", number: 25},
|
||||
{name: "Sue", mood: "Sad", number: 43},
|
||||
{name: "Sean", mood: "Sad", number: 1335},
|
||||
{name: "Niall", mood: "Happy", number: 2},
|
||||
{name: "Alberto", mood: "Happy", number: 123},
|
||||
{name: "Fred", mood: "Sad", number: 532},
|
||||
{name: "Jenny", mood: "Happy", number: 34},
|
||||
{name: "Larry", mood: "Happy", number: 13},
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 370, width: 900}}
|
||||
className="ag-fresh">
|
||||
<h1>Cell Editor Component Example</h1>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
<div className="row">
|
||||
<div className="col-sm-12"><h1>Cell Editor Component Example</h1></div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<h5>This example demonstrates React Editor Components within ag-Grid, as well as an example using the built in Rich Select editor.</h5>
|
||||
<p><span style={{fontWeight: "bold"}}>Name</span>: Utilises the built in <code>RichSelect</code> editor</p>
|
||||
<p><span style={{fontWeight: "bold"}}>Mood</span>: A Custom React Editor demonstrating popup functionality, with full keyboard control.</p>
|
||||
<p><span style={{fontWeight: "bold"}}>Numeric</span>: A Custom React Editor demonstrating pre & post validation. Only numeric characters are allowed,
|
||||
and numbers greater than 1000000 will be rejected.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<h4 className="card-title">React Functionality</h4>
|
||||
<p className="card-text">Utilise React Components within ag-Grid</p>
|
||||
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editing/?framework=react" className="btn btn-primary">Cell Editing</a>
|
||||
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editor/?framework=react" className="btn btn-primary">Editor Components</a>
|
||||
<a target="_blank" href="https://www.ag-grid.com/best-react-data-grid/?framework=react" className="btn btn-primary">React with ag-Grid</a>
|
||||
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editor/?framework=react#reactCellEditing" className="btn btn-primary">React Editor Components</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
export default class MoodEditor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.onHappyClick = this.onHappyClick.bind(this);
|
||||
this.onSadClick = this.onSadClick.bind(this);
|
||||
|
||||
this.state = {
|
||||
happy: false
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setHappy(this.props.value === "Happy");
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refs.container.addEventListener('keydown', this.checkAndToggleMoodIfLeftRight);
|
||||
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() {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
focus() {
|
||||
setTimeout(() => {
|
||||
let container = ReactDOM.findDOMNode(this.refs.container);
|
||||
if (container) {
|
||||
container.focus();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.state.happy ? "Happy" : "Sad";
|
||||
}
|
||||
|
||||
isPopup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
setHappy(happy) {
|
||||
this.setState({
|
||||
happy
|
||||
});
|
||||
}
|
||||
|
||||
onHappyClick() {
|
||||
this.setState({
|
||||
happy: true
|
||||
},
|
||||
() => this.props.api.stopEditing()
|
||||
);
|
||||
}
|
||||
|
||||
onSadClick() {
|
||||
this.setState({
|
||||
happy: false
|
||||
},
|
||||
() => this.props.api.stopEditing()
|
||||
);
|
||||
}
|
||||
|
||||
toggleMood() {
|
||||
this.setHappy(!this.state.happy);
|
||||
}
|
||||
|
||||
render() {
|
||||
let mood = {
|
||||
borderRadius: 15,
|
||||
border: "1px solid grey",
|
||||
background: "#e6e6e6",
|
||||
padding: 15,
|
||||
textAlign: "center",
|
||||
display: "inline-block"
|
||||
};
|
||||
|
||||
let unselected = {
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
border: "1px solid transparent",
|
||||
padding: 4
|
||||
};
|
||||
|
||||
let selected = {
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
border: "1px solid lightgreen",
|
||||
padding: 4
|
||||
};
|
||||
|
||||
let happyStyle = this.state.happy ? selected : unselected;
|
||||
let sadStyle = !this.state.happy ? selected : unselected;
|
||||
|
||||
return (
|
||||
<div ref="container"
|
||||
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-sad.png" onClick={this.onSadClick} style={sadStyle}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class MoodRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setMood(this.props.value)
|
||||
}
|
||||
|
||||
refresh(params) {
|
||||
this.setMood(params.value);
|
||||
}
|
||||
|
||||
setMood(mood) {
|
||||
this.setState({
|
||||
imgForMood: mood === 'Happy' ? 'images/smiley.png' : 'images/smiley-sad.png'
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<img width="20px" src={this.state.imgForMood}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class MoodEditor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.cancelBeforeStart = this.props.charPress && ('1234567890'.indexOf(this.props.charPress) < 0);
|
||||
|
||||
let value = this.props.value;
|
||||
if (!this.cancelBeforeStart && this.props.charPress) {
|
||||
value = value + this.props.charPress;
|
||||
}
|
||||
this.state = {
|
||||
value
|
||||
};
|
||||
|
||||
this.onKeyDown = this.onKeyDown.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refs.input.addEventListener('keydown', this.onKeyDown);
|
||||
this.focus();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.refs.input.removeEventListener('keydown', this.onKeyDown);
|
||||
}
|
||||
|
||||
focus() {
|
||||
setTimeout(() => {
|
||||
this.refs.input.focus();
|
||||
this.refs.input.setSelectionRange(this.state.value.length, this.state.value.length);
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.state.value;
|
||||
}
|
||||
|
||||
isCancelBeforeStart() {
|
||||
return this.cancelBeforeStart;
|
||||
}
|
||||
|
||||
// will reject the number if it greater than 1,000,000
|
||||
// not very practical, but demonstrates the method.
|
||||
isCancelAfterEnd() {
|
||||
return this.state.value > 1000000;
|
||||
};
|
||||
|
||||
onKeyDown(event) {
|
||||
if (this.isLeftOrRight(event)) {
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isKeyPressedNumeric(event)) {
|
||||
if (event.preventDefault) event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
isLeftOrRight(event) {
|
||||
return [37, 39].indexOf(event.keyCode) > -1;
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
this.setState({value: event.target.value});
|
||||
}
|
||||
|
||||
getCharCodeFromEvent(event) {
|
||||
event = event || window.event;
|
||||
return (typeof event.which === "undefined") ? event.keyCode : event.which;
|
||||
}
|
||||
|
||||
isCharNumeric(charStr) {
|
||||
return !!/\d/.test(charStr);
|
||||
}
|
||||
|
||||
isKeyPressedNumeric(event) {
|
||||
const charCode = this.getCharCodeFromEvent(event);
|
||||
const charStr = event.key ? event.key : String.fromCharCode(charCode);
|
||||
return this.isCharNumeric(charStr);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<input ref="input"
|
||||
value={this.state.value}
|
||||
onChange={this.handleChange}
|
||||
style={{width: "100%"}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
|
||||
import "ag-grid-enterprise";
|
||||
|
||||
import PartialMatchFilter from "./PartialMatchFilter";
|
||||
|
||||
export default class FilterComponentExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
gridOptions: {},
|
||||
|
||||
rowData: FilterComponentExample.createRowData(),
|
||||
columnDefs: FilterComponentExample.createColumnDefs(),
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
this.onClicked = this.onClicked.bind(this);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
onClicked() {
|
||||
this.gridApi.getFilterInstance("name").getFrameworkComponentInstance().componentMethod("Hello World!");
|
||||
}
|
||||
|
||||
static createColumnDefs() {
|
||||
return [
|
||||
{headerName: "Row", field: "row", width: 400},
|
||||
{
|
||||
headerName: "Filter Component",
|
||||
field: "name",
|
||||
filterFramework: PartialMatchFilter,
|
||||
width: 400,
|
||||
menuTabs:['filterMenuTab']
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
static createRowData() {
|
||||
return [
|
||||
{"row": "Row 1", "name": "Michael Phelps"},
|
||||
{"row": "Row 2", "name": "Natalie Coughlin"},
|
||||
{"row": "Row 3", "name": "Aleksey Nemov"},
|
||||
{"row": "Row 4", "name": "Alicia Coutts"},
|
||||
{"row": "Row 5", "name": "Missy Franklin"},
|
||||
{"row": "Row 6", "name": "Ryan Lochte"},
|
||||
{"row": "Row 7", "name": "Allison Schmitt"},
|
||||
{"row": "Row 8", "name": "Natalie Coughlin"},
|
||||
{"row": "Row 9", "name": "Ian Thorpe"},
|
||||
{"row": "Row 10", "name": "Bob Mill"},
|
||||
{"row": "Row 11", "name": "Willy Walsh"},
|
||||
{"row": "Row 12", "name": "Sarah McCoy"},
|
||||
{"row": "Row 13", "name": "Jane Jack"},
|
||||
{"row": "Row 14", "name": "Tina Wills"}
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 400, width: 900}}
|
||||
className="ag-fresh">
|
||||
<h1>Filter Component Example</h1>
|
||||
<button style={{marginBottom: 10}} onClick={this.onClicked} className="btn btn-primary">Filter Instance Method</button>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
enableFilter
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,80 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
export default class PartialMatchFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
text: ''
|
||||
};
|
||||
|
||||
this.valueGetter = this.props.valueGetter;
|
||||
|
||||
this.onChange = this.onChange.bind(this);
|
||||
}
|
||||
|
||||
isFilterActive() {
|
||||
return this.state.text !== null && this.state.text !== undefined && this.state.text !== '';
|
||||
}
|
||||
|
||||
doesFilterPass(params) {
|
||||
return this.state.text.toLowerCase()
|
||||
.split(" ")
|
||||
.every((filterWord) => {
|
||||
return this.valueGetter(params.node).toString().toLowerCase().indexOf(filterWord) >= 0;
|
||||
});
|
||||
}
|
||||
|
||||
getModel() {
|
||||
return {value: this.state.text};
|
||||
}
|
||||
|
||||
setModel(model) {
|
||||
this.state.text = model ? model.value : '';
|
||||
}
|
||||
|
||||
afterGuiAttached(params) {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
focus() {
|
||||
setTimeout(() => {
|
||||
let container = ReactDOM.findDOMNode(this.refs.input);
|
||||
if (container) {
|
||||
container.focus();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
componentMethod(message) {
|
||||
alert(`Alert from PartialMatchFilterComponent ${message}`);
|
||||
}
|
||||
|
||||
onChange(event) {
|
||||
let newValue = event.target.value;
|
||||
if (this.state.text !== newValue) {
|
||||
this.setState({
|
||||
text: newValue
|
||||
}, () => {
|
||||
this.props.filterChangedCallback();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let style = {
|
||||
border: "2px solid #22ff22",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "#bbffbb",
|
||||
width: "200px",
|
||||
height: "50px"
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={style}>Filter: <input style={{height: "20px"}} ref="input" value={this.state.text}
|
||||
onChange={this.onChange} className="form-control"/></div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import FloatingFilter from "./floatingFilter";
|
||||
import overrideStyle from "./floatingFilter.css";
|
||||
|
||||
export default class FloatingFilterGridExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
columnDefs: this.createColumnDefs(),
|
||||
rowData: this.createRowData()
|
||||
}
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
createColumnDefs() {
|
||||
return [
|
||||
{
|
||||
headerName: "Make",
|
||||
field: "make",
|
||||
floatingFilterComponentFramework: FloatingFilter,
|
||||
filter: 'set'
|
||||
},
|
||||
{headerName: "Model", field: "model"},
|
||||
{headerName: "Price", field: "price"}
|
||||
];
|
||||
}
|
||||
|
||||
createRowData() {
|
||||
return [
|
||||
{make: "Toyota", model: "Celica", price: 35000},
|
||||
{make: "Ford", model: "Mondeo", price: 32000},
|
||||
{make: "Porsche", model: "Boxter", price: 72000}
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
let divStyle = {
|
||||
height: 400,
|
||||
width: 900
|
||||
};
|
||||
|
||||
// combine the styles
|
||||
const style = Object.assign({}, divStyle, overrideStyle);
|
||||
|
||||
return (
|
||||
<div style={style} className="ag-fresh">
|
||||
<h1>Floating Filter Example</h1>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
floatingFilter={true}
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
.ag-floating-filter-button button {
|
||||
margin: 0
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class FloatingFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
parentModel: null
|
||||
}
|
||||
}
|
||||
|
||||
// when does this get called? how to test this?
|
||||
onParentModelChanged(parentModel) {
|
||||
this.setState({
|
||||
parentModel: parentModel
|
||||
})
|
||||
}
|
||||
|
||||
remove(item) {
|
||||
this.props.onFloatingFilterChanged({
|
||||
model: this.state.parentModel.filter(it => it !== item)
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.state.parentModel) return null;
|
||||
|
||||
// as the backing filter is a set filter what we're doing here is rendering the list in the set
|
||||
// and when the [x] removing the selected item, thereby effectively hiding it
|
||||
let options = this.state.parentModel.map((item, i) => {
|
||||
let removeMeListener = () => {
|
||||
this.remove(item)
|
||||
};
|
||||
let removeMeElement = <a onClick={removeMeListener}>[x]</a>;
|
||||
return <span key={i}>{item}{removeMeElement}</span>;
|
||||
});
|
||||
|
||||
return <div>{options}</div>;
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import NameAndAgeRenderer from "./NameAndAgeRenderer";
|
||||
|
||||
export default class FullWidthComponentExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
gridOptions: {},
|
||||
|
||||
rowData: FullWidthComponentExample.createRowData(),
|
||||
columnDefs: FullWidthComponentExample.createColumnDefs()
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
isFullWidthCell(rowNode) {
|
||||
return (rowNode.id === "0") || (parseInt(rowNode.id) % 2 === 0);
|
||||
}
|
||||
|
||||
static createColumnDefs() {
|
||||
return [
|
||||
{
|
||||
headerName: "Name",
|
||||
field: "name",
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
headerName: "Age",
|
||||
field: "age",
|
||||
width: 399
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
static createRowData() {
|
||||
return [
|
||||
{name: "Bob", age: 10},
|
||||
{name: "Harry", age: 3},
|
||||
{name: "Sally", age: 20},
|
||||
{name: "Mary", age: 5},
|
||||
{name: "John", age: 15},
|
||||
{name: "Bob", age: 10},
|
||||
{name: "Harry", age: 3},
|
||||
{name: "Sally", age: 20},
|
||||
{name: "Mary", age: 5},
|
||||
{name: "John", age: 15},
|
||||
{name: "Jack", age: 25},
|
||||
{name: "Sue", age: 43},
|
||||
{name: "Sean", age: 44},
|
||||
{name: "Niall", age: 2},
|
||||
{name: "Alberto", age: 32},
|
||||
{name: "Fred", age: 53},
|
||||
{name: "Jenny", age: 34},
|
||||
{name: "Larry", age: 13},
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 400, width: 900}}
|
||||
className="ag-fresh">
|
||||
<h1>Full Width Renderer Example</h1>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
isFullWidthCell={this.isFullWidthCell}
|
||||
fullWidthCellRendererFramework={NameAndAgeRenderer}
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class NameAndAgeRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.values = `Name: ${this.props.data.name}, Age: ${this.props.data.age}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
let style = {
|
||||
border: "2px solid #22ff22",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "#bbffbb"
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={style}>Full Width Column! { this.values }</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,126 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
import {AgGridReact} from "ag-grid-react";
|
||||
import MedalRenderer from "./MedalRenderer";
|
||||
|
||||
import "ag-grid-enterprise";
|
||||
|
||||
export default class GroupedRowInnerRendererComponentExample extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
gridOptions: {},
|
||||
|
||||
rowData: this.createRowData(),
|
||||
columnDefs: this.createColumnDefs(),
|
||||
};
|
||||
|
||||
this.onGridReady = this.onGridReady.bind(this);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
}
|
||||
|
||||
createColumnDefs() {
|
||||
return [
|
||||
{
|
||||
headerName: "Country",
|
||||
field: "country",
|
||||
width: 100,
|
||||
rowGroupIndex: 0
|
||||
},
|
||||
{
|
||||
headerName: "Name",
|
||||
field: "name",
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
headerName: "Gold",
|
||||
field: "gold",
|
||||
width: 100,
|
||||
aggFunc: 'sum'
|
||||
},
|
||||
{
|
||||
headerName: "Silver",
|
||||
field: "silver",
|
||||
width: 100,
|
||||
aggFunc: 'sum'
|
||||
},
|
||||
{
|
||||
headerName: "Bronze",
|
||||
field: "bronze",
|
||||
width: 100,
|
||||
aggFunc: 'sum'
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
createRowData() {
|
||||
return [
|
||||
{country: "United States", name: "Bob", gold: 1, silver: 0, bronze: 0},
|
||||
{country: "United States", name: "Jack", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "United States", name: "Sue", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "United Kingdom", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "United Kingdom", name: "Tess", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "United Kingdom", name: "John", gold: 0, silver: 2, bronze: 1},
|
||||
{country: "Jamaica", name: "Bob", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Jamaica", name: "Jack", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Jamaica", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "South Africa", name: "Bob", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "South Africa", name: "Jack", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "South Africa", name: "Mary", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "South Africa", name: "John", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "New Zealand", name: "Bob", gold: 1, silver: 0, bronze: 0},
|
||||
{country: "New Zealand", name: "Jack", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "New Zealand", name: "Sue", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Australia", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Australia", name: "Tess", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "Australia", name: "John", gold: 0, silver: 2, bronze: 1},
|
||||
{country: "Canada", name: "Bob", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Canada", name: "Jack", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Canada", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Switzerland", name: "Bob", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Switzerland", name: "Jack", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Switzerland", name: "Mary", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Switzerland", name: "John", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Spain", name: "Bob", gold: 1, silver: 0, bronze: 0},
|
||||
{country: "Spain", name: "Jack", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "Spain", name: "Sue", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Portugal", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Portugal", name: "Tess", gold: 0, silver: 1, bronze: 1},
|
||||
{country: "Portugal", name: "John", gold: 0, silver: 2, bronze: 1},
|
||||
{country: "Zimbabwe", name: "Bob", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Zimbabwe", name: "Jack", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Zimbabwe", name: "Mary", gold: 1, silver: 1, bronze: 0},
|
||||
{country: "Brazil", name: "Bob", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Brazil", name: "Jack", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Brazil", name: "Mary", gold: 1, silver: 0, bronze: 1},
|
||||
{country: "Brazil", name: "John", gold: 1, silver: 0, bronze: 1}
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{height: 400, width: 900}}
|
||||
className="ag-fresh">
|
||||
<h1>Group Row Renderer Example</h1>
|
||||
<AgGridReact
|
||||
// properties
|
||||
columnDefs={this.state.columnDefs}
|
||||
rowData={this.state.rowData}
|
||||
|
||||
groupUseEntireRow
|
||||
groupRowInnerRendererFramework={MedalRenderer}
|
||||
|
||||
// events
|
||||
onGridReady={this.onGridReady}>
|
||||
</AgGridReact>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import React, {Component} from "react";
|
||||
|
||||
export default class MedalRenderer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.country = this.props.node.key;
|
||||
this.gold = this.props.node.aggData.gold;
|
||||
this.silver = this.props.node.aggData.silver;
|
||||
this.bronze = this.props.node.aggData.bronze;
|
||||
|
||||
// override the containing div so that the +/- and label are inline
|
||||
this.props.reactContainer.style.display = "inline-block";
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span>{this.country} Gold: {this.gold}, Silver: {this.silver}, Bronze: {this.bronze}</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 256 B |