Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2b92b4c9a | ||
|
|
c8267730bf | ||
|
|
3992e3e928 | ||
|
|
8409183d6b | ||
|
|
7075f57d88 | ||
|
|
ad6bc068b2 | ||
|
|
c4310c2768 | ||
|
|
2228a8d0c9 | ||
|
|
966fa0fe69 | ||
|
|
9528d5a5bc | ||
|
|
3b5eaac21a | ||
|
|
73cc989512 | ||
|
|
5a45846cb7 | ||
|
|
2d8d5b125e |
@@ -25,5 +25,5 @@ Building
|
|||||||
To build:
|
To build:
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `npm install webpack -g`
|
- `npm install webpack -g`
|
||||||
- `npm run example`, `npm run large` or `npm run trader`
|
- `npm run examples`, `npm run large` or `npm run trader`
|
||||||
- navigate to localhost:8080
|
- navigate to localhost:8080
|
||||||
11
package.json
11
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ag-grid-react-example",
|
"name": "ag-grid-react-example",
|
||||||
"version": "13.0.0",
|
"version": "13.3.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": {
|
||||||
@@ -58,6 +58,9 @@
|
|||||||
"typescript": "2.3.x"
|
"typescript": "2.3.x"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ag-grid": "13.3.x",
|
||||||
|
"ag-grid-enterprise": "13.3.x",
|
||||||
|
"ag-grid-react": "13.3.x",
|
||||||
"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",
|
||||||
@@ -66,10 +69,8 @@
|
|||||||
"react-dom": "15.6.x",
|
"react-dom": "15.6.x",
|
||||||
"react-dom-factories": "1.0.0",
|
"react-dom-factories": "1.0.0",
|
||||||
"react-redux": "5.0.x",
|
"react-redux": "5.0.x",
|
||||||
|
"react-router-dom": "4.2.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": "13.0.x",
|
|
||||||
"ag-grid-enterprise": "13.0.x",
|
|
||||||
"ag-grid-react": "13.0.x"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class TopMoversGrid extends Component {
|
|||||||
cellRenderer: 'animateShowChange',
|
cellRenderer: 'animateShowChange',
|
||||||
cellClass: 'align-right',
|
cellClass: 'align-right',
|
||||||
sort: 'desc',
|
sort: 'desc',
|
||||||
cellFormatter(params) {
|
valueFormatter(params) {
|
||||||
return params.value.toFixed(2)
|
return params.value.toFixed(2)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ import * as PropTypes from 'prop-types';
|
|||||||
|
|
||||||
export default class HorizontalBarComponent extends Component {
|
export default class HorizontalBarComponent extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
value: this.props.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let positiveChange = {
|
let positiveChange = {
|
||||||
fill: "green"
|
fill: "green"
|
||||||
@@ -19,7 +27,7 @@ export default class HorizontalBarComponent extends Component {
|
|||||||
textAlign: "right"
|
textAlign: "right"
|
||||||
};
|
};
|
||||||
|
|
||||||
let pctNetChange = this.props.value;
|
let pctNetChange = this.state.value;
|
||||||
let pctNetChangeBar = Math.min(Math.abs(pctNetChange) * 100, 100) / 2;
|
let pctNetChangeBar = Math.min(Math.abs(pctNetChange) * 100, 100) / 2;
|
||||||
|
|
||||||
let barWidth = `${pctNetChangeBar}%`;
|
let barWidth = `${pctNetChangeBar}%`;
|
||||||
@@ -36,6 +44,13 @@ export default class HorizontalBarComponent extends Component {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refresh(params) {
|
||||||
|
this.setState({
|
||||||
|
value: params.value
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalBarComponent.propTypes = {
|
HorizontalBarComponent.propTypes = {
|
||||||
|
|||||||
58
src/App.jsx
58
src/App.jsx
@@ -1,6 +1,7 @@
|
|||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
|
import {Redirect, Route, Switch} from "react-router-dom";
|
||||||
|
|
||||||
import "url-search-params-polyfill";
|
import NavItem from "./NavItem";
|
||||||
|
|
||||||
import DynamicComponentsExample from "./dynamicComponentExample/DynamicComponentsExample";
|
import DynamicComponentsExample from "./dynamicComponentExample/DynamicComponentsExample";
|
||||||
import RichGridExample from "./richGridExample/RichGridExample";
|
import RichGridExample from "./richGridExample/RichGridExample";
|
||||||
@@ -13,7 +14,57 @@ import FilterComponentExample from "./filterComponentExample/FilterComponentExam
|
|||||||
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
|
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
|
||||||
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
|
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
|
||||||
import FloatingFilterGridExample from "./floatingFilter/FloatingFilterGridExample";
|
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 {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -52,6 +103,7 @@ class App extends Component {
|
|||||||
<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>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +139,9 @@ class App extends Component {
|
|||||||
case 'floating-filter':
|
case 'floating-filter':
|
||||||
example = <FloatingFilterGridExample/>;
|
example = <FloatingFilterGridExample/>;
|
||||||
break;
|
break;
|
||||||
|
case 'simple-redux-dynamic':
|
||||||
|
example = <SimpleReduxDynamicExample/>;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
example = <RichGridExample/>;
|
example = <RichGridExample/>;
|
||||||
}
|
}
|
||||||
@@ -101,3 +156,4 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
*/
|
||||||
|
|||||||
19
src/NavItem.jsx
Normal file
19
src/NavItem.jsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import React, {PropTypes} from 'react'
|
||||||
|
import {Route, Link} 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>
|
||||||
|
)}/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
NavItem.propTypes = {
|
||||||
|
to: PropTypes.string.isRequired,
|
||||||
|
exact: PropTypes.bool,
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
};
|
||||||
@@ -13,7 +13,7 @@ export default class ChildMessageRenderer extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span><button style={{height: 20}} onClick={this.invokeParentMethod}>Invoke Parent</button></span>
|
<span><button style={{height: 20, lineHeight: 0.5}} onClick={this.invokeParentMethod} className="btn btn-info">Invoke Parent</button></span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,15 +3,29 @@ import React, {Component} from "react";
|
|||||||
export default class CurrencyRenderer extends Component {
|
export default class CurrencyRenderer extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
value: props.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formatValueToCurrency(currency, value) {
|
formatValueToCurrency(currency, value) {
|
||||||
return `${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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span>{this.formatValueToCurrency('EUR', this.props.value)}</span>
|
<span>{this.formatValueToCurrency('EUR', this.state.value)}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
rowData: this.createRowData(),
|
rowData: DynamicComponentsExample.createRowData(),
|
||||||
|
|
||||||
columnDefs: this.createColumnDefs()
|
columnDefs: DynamicComponentsExample.createColumnDefs()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
this.refreshRowData = this.refreshRowData.bind(this);
|
this.refreshEvenRowsCurrencyData = this.refreshEvenRowsCurrencyData.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onGridReady(params) {
|
onGridReady(params) {
|
||||||
@@ -34,15 +34,23 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
this.gridApi.sizeColumnsToFit();
|
this.gridApi.sizeColumnsToFit();
|
||||||
}
|
}
|
||||||
|
|
||||||
onCellValueChanged($event) {
|
|
||||||
this.gridApi.refreshCells([$event.node],["cube"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
methodFromParent(cell) {
|
methodFromParent(cell) {
|
||||||
alert(`Parent Component Method from ${cell}!`);
|
alert(`Parent Component Method from ${cell}!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnDefs() {
|
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 [
|
return [
|
||||||
{headerName: "Row", field: "row", width: 100},
|
{headerName: "Row", field: "row", width: 100},
|
||||||
{
|
{
|
||||||
@@ -71,7 +79,7 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
headerName: "Currency",
|
headerName: "Currency",
|
||||||
field: "currency",
|
field: "currency",
|
||||||
cellRendererFramework: CurrencyRenderer,
|
cellRendererFramework: CurrencyRenderer,
|
||||||
colId: "params",
|
colId: "currency",
|
||||||
width: 135
|
width: 135
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,12 +92,7 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshRowData() {
|
static createRowData() {
|
||||||
let rowData = this.createRowData();
|
|
||||||
this.gridApi.setRowData(rowData);
|
|
||||||
}
|
|
||||||
|
|
||||||
createRowData() {
|
|
||||||
let rowData = [];
|
let rowData = [];
|
||||||
|
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 15; i++) {
|
||||||
@@ -102,12 +105,13 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
|
|
||||||
return rowData;
|
return rowData;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Dynamic React Component Example</h1>
|
<h1>Dynamic React Component Example</h1>
|
||||||
<button onClick={this.refreshRowData}>Refresh Data</button>
|
<button onClick={this.refreshEvenRowsCurrencyData} style={{marginBottom: 10}} className="btn btn-primary">Refresh Even Row Currency Data</button>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
// properties
|
// properties
|
||||||
columnDefs={this.state.columnDefs}
|
columnDefs={this.state.columnDefs}
|
||||||
@@ -117,6 +121,32 @@ export default class DynamicComponentsExample extends Component {
|
|||||||
// events
|
// events
|
||||||
onGridReady={this.onGridReady}>
|
onGridReady={this.onGridReady}>
|
||||||
</AgGridReact>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export default class EditorComponentsExample extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
rowData: this.createRowData(),
|
rowData: EditorComponentsExample.createRowData(),
|
||||||
columnDefs: this.createColumnDefs()
|
columnDefs: EditorComponentsExample.createColumnDefs()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
@@ -24,9 +24,32 @@ export default class EditorComponentsExample extends Component {
|
|||||||
this.gridApi.sizeColumnsToFit();
|
this.gridApi.sizeColumnsToFit();
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnDefs() {
|
static createColumnDefs() {
|
||||||
return [
|
return [
|
||||||
{headerName: "Name", field: "name", width: 300},
|
{
|
||||||
|
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",
|
headerName: "Mood",
|
||||||
field: "mood",
|
field: "mood",
|
||||||
@@ -45,7 +68,7 @@ export default class EditorComponentsExample extends Component {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
createRowData() {
|
static createRowData() {
|
||||||
return [
|
return [
|
||||||
{name: "Bob", mood: "Happy", number: 10},
|
{name: "Bob", mood: "Happy", number: 10},
|
||||||
{name: "Harry", mood: "Sad", number: 3},
|
{name: "Harry", mood: "Sad", number: 3},
|
||||||
@@ -65,7 +88,7 @@ export default class EditorComponentsExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 370, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Cell Editor Component Example</h1>
|
<h1>Cell Editor Component Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
@@ -76,7 +99,34 @@ export default class EditorComponentsExample extends Component {
|
|||||||
// events
|
// events
|
||||||
onGridReady={this.onGridReady}>
|
onGridReady={this.onGridReady}>
|
||||||
</AgGridReact>
|
</AgGridReact>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-12"><h1>Cell Editor Component Example</h1></div>
|
||||||
</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,16 +1,19 @@
|
|||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
export default class MoodEditor extends Component {
|
export default class MoodEditor extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
|
||||||
value: this.props.value
|
|
||||||
};
|
|
||||||
|
|
||||||
this.cancelBeforeStart = this.props.charPress && ('1234567890'.indexOf(this.props.charPress) < 0);
|
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.onKeyDown = this.onKeyDown.bind(this);
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
}
|
}
|
||||||
@@ -30,10 +33,9 @@ export default class MoodEditor extends Component {
|
|||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let container = ReactDOM.findDOMNode(this.refs.input);
|
this.refs.input.focus();
|
||||||
if (container) {
|
this.refs.input.setSelectionRange(this.state.value.length, this.state.value.length);
|
||||||
container.focus();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +92,7 @@ export default class MoodEditor extends Component {
|
|||||||
<input ref="input"
|
<input ref="input"
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
|
style={{width: "100%"}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ export default class FilterComponentExample extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
gridOptions: {},
|
gridOptions: {},
|
||||||
|
|
||||||
rowData: this.createRowData(),
|
rowData: FilterComponentExample.createRowData(),
|
||||||
columnDefs: this.createColumnDefs(),
|
columnDefs: FilterComponentExample.createColumnDefs(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
@@ -32,7 +32,7 @@ export default class FilterComponentExample extends Component {
|
|||||||
this.gridApi.getFilterInstance("name").getFrameworkComponentInstance().componentMethod("Hello World!");
|
this.gridApi.getFilterInstance("name").getFrameworkComponentInstance().componentMethod("Hello World!");
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnDefs() {
|
static createColumnDefs() {
|
||||||
return [
|
return [
|
||||||
{headerName: "Row", field: "row", width: 400},
|
{headerName: "Row", field: "row", width: 400},
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ export default class FilterComponentExample extends Component {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
createRowData() {
|
static createRowData() {
|
||||||
return [
|
return [
|
||||||
{"row": "Row 1", "name": "Michael Phelps"},
|
{"row": "Row 1", "name": "Michael Phelps"},
|
||||||
{"row": "Row 2", "name": "Natalie Coughlin"},
|
{"row": "Row 2", "name": "Natalie Coughlin"},
|
||||||
@@ -66,10 +66,10 @@ export default class FilterComponentExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Filter Component Example</h1>
|
<h1>Filter Component Example</h1>
|
||||||
<button style={{marginBottom: 10}} onClick={this.onClicked}>Filter Instance Method</button>
|
<button style={{marginBottom: 10}} onClick={this.onClicked} className="btn btn-primary">Filter Instance Method</button>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
// properties
|
// properties
|
||||||
columnDefs={this.state.columnDefs}
|
columnDefs={this.state.columnDefs}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default class PartialMatchFilter extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
text: ''
|
text: ''
|
||||||
}
|
};
|
||||||
|
|
||||||
this.valueGetter = this.props.valueGetter;
|
this.valueGetter = this.props.valueGetter;
|
||||||
|
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
@@ -63,8 +64,17 @@ export default class PartialMatchFilter extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let style = {
|
||||||
|
border: "2px solid #22ff22",
|
||||||
|
borderRadius: "5px",
|
||||||
|
backgroundColor: "#bbffbb",
|
||||||
|
width: "200px",
|
||||||
|
height: "50px"
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>Filter: <input style={{height: "20px"}} ref="input" value={this.state.text} onChange={this.onChange}/></span>
|
<div style={style}>Filter: <input style={{height: "20px"}} ref="input" value={this.state.text}
|
||||||
|
onChange={this.onChange} className="form-control"/></div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default class FloatingFilterGridExample extends Component {
|
|||||||
render() {
|
render() {
|
||||||
let divStyle = {
|
let divStyle = {
|
||||||
height: 400,
|
height: 400,
|
||||||
width: 945
|
width: 900
|
||||||
};
|
};
|
||||||
|
|
||||||
// combine the styles
|
// combine the styles
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export default class FullWidthComponentExample extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
gridOptions: {},
|
gridOptions: {},
|
||||||
|
|
||||||
rowData: this.createRowData(),
|
rowData: FullWidthComponentExample.createRowData(),
|
||||||
columnDefs: this.createColumnDefs()
|
columnDefs: FullWidthComponentExample.createColumnDefs()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
@@ -28,7 +28,7 @@ export default class FullWidthComponentExample extends Component {
|
|||||||
return (rowNode.id === "0") || (parseInt(rowNode.id) % 2 === 0);
|
return (rowNode.id === "0") || (parseInt(rowNode.id) % 2 === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnDefs() {
|
static createColumnDefs() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
headerName: "Name",
|
headerName: "Name",
|
||||||
@@ -43,7 +43,7 @@ export default class FullWidthComponentExample extends Component {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
createRowData() {
|
static createRowData() {
|
||||||
return [
|
return [
|
||||||
{name: "Bob", age: 10},
|
{name: "Bob", age: 10},
|
||||||
{name: "Harry", age: 3},
|
{name: "Harry", age: 3},
|
||||||
@@ -68,7 +68,7 @@ export default class FullWidthComponentExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Full Width Renderer Example</h1>
|
<h1>Full Width Renderer Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ export default class NameAndAgeRenderer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let style = {
|
||||||
|
border: "2px solid #22ff22",
|
||||||
|
borderRadius: "5px",
|
||||||
|
backgroundColor: "#bbffbb"
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>Full Width Column! { this.values }</span>
|
<div style={style}>Full Width Column! { this.values }</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ export default class GroupedRowInnerRendererComponentExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Group Row Renderer Example</h1>
|
<h1>Group Row Renderer Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
|||||||
@@ -12,40 +12,51 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
div.card-body > a {
|
||||||
|
margin-top: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
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 +69,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {render} from "react-dom";
|
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/ag-grid.css";
|
||||||
import "ag-grid-root/dist/styles/theme-fresh.css";
|
import "ag-grid-root/dist/styles/theme-fresh.css";
|
||||||
@@ -15,7 +16,9 @@ import App from "./App";
|
|||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
render(
|
render(
|
||||||
<App/>,
|
<BrowserRouter>
|
||||||
|
<App/>
|
||||||
|
</BrowserRouter>,
|
||||||
document.querySelector('#app')
|
document.querySelector('#app')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default class MasterDetailExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Master-Detail Example</h1>
|
<h1>Master-Detail Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export default class PinnedRowComponentExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 400, width: 900}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<h1>Pinned Row Renderer Example</h1>
|
<h1>Pinned Row Renderer Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default class ClickableRenderer extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<button style={{height: 21}} onClick={this.clicked} >Click Me</button>
|
<button style={{lineHeight: 0.5, width: "98%"}} onClick={this.clicked} className="btn btn-info">Click Me</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,8 +9,8 @@ export default class RichComponentsExample extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
rowData: this.createRowData(),
|
rowData: RichComponentsExample.createRowData(),
|
||||||
columnDefs: this.createColumnDefs()
|
columnDefs: RichComponentsExample.createColumnDefs()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
@@ -23,9 +23,13 @@ export default class RichComponentsExample extends Component {
|
|||||||
this.gridApi.sizeColumnsToFit();
|
this.gridApi.sizeColumnsToFit();
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnDefs() {
|
static createColumnDefs() {
|
||||||
return [
|
return [
|
||||||
{headerName: "Name", field: "name", width: 200},
|
{
|
||||||
|
headerName: "Name",
|
||||||
|
field: "name",
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
{
|
{
|
||||||
headerName: "Ratio Component",
|
headerName: "Ratio Component",
|
||||||
field: "ratios",
|
field: "ratios",
|
||||||
@@ -40,7 +44,7 @@ export default class RichComponentsExample extends Component {
|
|||||||
}
|
}
|
||||||
]; }
|
]; }
|
||||||
|
|
||||||
createRowData() {
|
static createRowData() {
|
||||||
return [
|
return [
|
||||||
{name: 'Homer Simpson', ratios: {top: 0.25, bottom: 0.75}},
|
{name: 'Homer Simpson', ratios: {top: 0.25, bottom: 0.75}},
|
||||||
{name: 'Marge Simpson', ratios: {top: 0.67, bottom: 0.39}},
|
{name: 'Marge Simpson', ratios: {top: 0.67, bottom: 0.39}},
|
||||||
@@ -60,8 +64,7 @@ export default class RichComponentsExample extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945}}
|
<div style={{height: 370, width: 900}} className="ag-fresh">
|
||||||
className="ag-fresh">
|
|
||||||
<h1>Dynamic React Components - Richer Example</h1>
|
<h1>Dynamic React Components - Richer Example</h1>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
// properties
|
// properties
|
||||||
@@ -72,6 +75,24 @@ export default class RichComponentsExample extends Component {
|
|||||||
// events
|
// events
|
||||||
onGridReady={this.onGridReady}>
|
onGridReady={this.onGridReady}>
|
||||||
</AgGridReact>
|
</AgGridReact>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-12">
|
||||||
|
<h5>This example demonstrates Dynamic React Components with ag-Grid. Functionally similar
|
||||||
|
to the <a href="/dynamic">Dynamic React Components Example</a> but with slightly richer components.</h5>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,8 @@ export default class ColDefFactory {
|
|||||||
checkboxSelection: true,
|
checkboxSelection: true,
|
||||||
suppressSorting: true,
|
suppressSorting: true,
|
||||||
suppressMenu: true,
|
suppressMenu: true,
|
||||||
pinned: true,
|
suppressFilter: true,
|
||||||
icons: {
|
pinned: true
|
||||||
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',
|
||||||
@@ -37,7 +33,8 @@ export default class ColDefFactory {
|
|||||||
editable: true,
|
editable: true,
|
||||||
// use a React cellEditor
|
// use a React cellEditor
|
||||||
cellEditorFramework: NameCellEditor
|
cellEditorFramework: NameCellEditor
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
headerName: "Country",
|
headerName: "Country",
|
||||||
field: "country",
|
field: "country",
|
||||||
width: 150,
|
width: 150,
|
||||||
@@ -49,9 +46,9 @@ export default class ColDefFactory {
|
|||||||
filterParams: {
|
filterParams: {
|
||||||
cellRenderer: countryCellRenderer,
|
cellRenderer: countryCellRenderer,
|
||||||
cellHeight: 20
|
cellHeight: 20
|
||||||
|
}
|
||||||
},
|
},
|
||||||
columnGroupShow: 'open'
|
{
|
||||||
}, {
|
|
||||||
headerName: "DOB",
|
headerName: "DOB",
|
||||||
field: "dob",
|
field: "dob",
|
||||||
width: 110,
|
width: 110,
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ export default class HeaderGroupComponent extends React.Component {
|
|||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<div className="customHeaderLabel"> {this.props.displayName}</div>
|
<div className="customHeaderLabel"> {this.props.displayName}</div>
|
||||||
<div onClick={this.expandOrCollapse.bind(this)} className={arrowClassName}><i className="fa fa-arrow-right" /></div>
|
<div onClick={this.expandOrCollapse.bind(this)} className={arrowClassName}><i
|
||||||
|
className="fa fa-arrow-right"/></div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import RefData from './RefData';
|
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
|
|
||||||
var KEY_BACKSPACE = 8;
|
const KEY_BACKSPACE = 8;
|
||||||
var KEY_DELETE = 46;
|
const KEY_DELETE = 46;
|
||||||
var KEY_F2 = 113;
|
const KEY_F2 = 113;
|
||||||
|
|
||||||
// cell renderer for the proficiency column. this is a very basic cell editor,
|
// cell renderer for the proficiency column. this is a very basic cell editor,
|
||||||
export default class NameCellEditor extends React.Component {
|
export default class NameCellEditor extends React.Component {
|
||||||
@@ -20,9 +19,9 @@ export default class NameCellEditor extends React.Component {
|
|||||||
// experience is similar to Excel
|
// experience is similar to Excel
|
||||||
createInitialState(props) {
|
createInitialState(props) {
|
||||||
|
|
||||||
var startValue;
|
let startValue;
|
||||||
var putCursorAtEndOnFocus = false;
|
const putCursorAtEndOnFocus = false;
|
||||||
var highlightAllOnFocus = false;
|
const highlightAllOnFocus = false;
|
||||||
|
|
||||||
if (props.keyPress === KEY_BACKSPACE || props.keyPress === KEY_DELETE) {
|
if (props.keyPress === KEY_BACKSPACE || props.keyPress === KEY_DELETE) {
|
||||||
// if backspace or delete pressed, we clear the cell
|
// if backspace or delete pressed, we clear the cell
|
||||||
@@ -56,7 +55,7 @@ export default class NameCellEditor extends React.Component {
|
|||||||
onChangeListener(event) {
|
onChangeListener(event) {
|
||||||
// if doing React, you will probably be using a library for managing immutable
|
// if doing React, you will probably be using a library for managing immutable
|
||||||
// objects better. to keep this example simple, we don't use one.
|
// objects better. to keep this example simple, we don't use one.
|
||||||
var newState = {
|
const newState = {
|
||||||
value: event.target.value,
|
value: event.target.value,
|
||||||
putCursorAtEndOnFocus: this.state.putCursorAtEndOnFocus,
|
putCursorAtEndOnFocus: this.state.putCursorAtEndOnFocus,
|
||||||
highlightAllOnFocus: this.state.highlightAllOnFocus
|
highlightAllOnFocus: this.state.highlightAllOnFocus
|
||||||
@@ -73,7 +72,7 @@ export default class NameCellEditor extends React.Component {
|
|||||||
// view, it may not yet be in the browser (put in by ag-Grid) so focus will not work
|
// view, it may not yet be in the browser (put in by ag-Grid) so focus will not work
|
||||||
afterGuiAttached() {
|
afterGuiAttached() {
|
||||||
// get ref from React component
|
// get ref from React component
|
||||||
var eInput = this.refs.textField;
|
const eInput = this.refs.textField;
|
||||||
eInput.focus();
|
eInput.focus();
|
||||||
if (this.highlightAllOnFocus) {
|
if (this.highlightAllOnFocus) {
|
||||||
eInput.select();
|
eInput.select();
|
||||||
@@ -82,7 +81,7 @@ export default class NameCellEditor extends React.Component {
|
|||||||
// this comes into play in two scenarios: a) when user hits F2 and b)
|
// this comes into play in two scenarios: a) when user hits F2 and b)
|
||||||
// when user hits a printable character, then on IE (and only IE) the carot
|
// when user hits a printable character, then on IE (and only IE) the carot
|
||||||
// was placed after the first character, thus 'apply' would end up as 'pplea'
|
// was placed after the first character, thus 'apply' would end up as 'pplea'
|
||||||
var length = eInput.value ? eInput.value.length : 0;
|
const length = eInput.value ? eInput.value.length : 0;
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
eInput.setSelectionRange(length, length);
|
eInput.setSelectionRange(length, length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import RefData from './RefData';
|
|
||||||
|
|
||||||
// cell renderer for the proficiency column. this is a very basic cell renderer,
|
// cell renderer for the proficiency column. this is a very basic cell renderer,
|
||||||
// it is arguable that we should not of used React and just returned a string of
|
// it is arguable that we should not of used React and just returned a string of
|
||||||
@@ -7,7 +6,7 @@ import RefData from './RefData';
|
|||||||
export default class ProficiencyCellRenderer extends React.Component {
|
export default class ProficiencyCellRenderer extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var backgroundColor;
|
let backgroundColor;
|
||||||
if (this.props.value < 20) {
|
if (this.props.value < 20) {
|
||||||
backgroundColor = 'red';
|
backgroundColor = 'red';
|
||||||
} else if (this.props.value < 60) {
|
} else if (this.props.value < 60) {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
var PROFICIENCY_NAMES = ['No Filter', 'Above 40%', 'Above 60%', 'Above 80%'];
|
const PROFICIENCY_NAMES = ['No Filter', 'Above 40%', 'Above 60%', 'Above 80%'];
|
||||||
|
|
||||||
// the proficiency filter component. this demonstrates how to integrate
|
// the proficiency filter component. this demonstrates how to integrate
|
||||||
// a React filter component with ag-Grid.
|
// a React filter component with ag-Grid.
|
||||||
export default class ProficiencyFilter extends React.Component {
|
export default class ProficiencyFilter extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super();
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
selected: PROFICIENCY_NAMES[0]
|
selected: PROFICIENCY_NAMES[0]
|
||||||
};
|
};
|
||||||
@@ -15,14 +15,18 @@ export default class ProficiencyFilter extends React.Component {
|
|||||||
|
|
||||||
// called by agGrid
|
// called by agGrid
|
||||||
doesFilterPass(params) {
|
doesFilterPass(params) {
|
||||||
var value = this.props.valueGetter(params);
|
const value = this.props.valueGetter(params);
|
||||||
var valueAsNumber = parseFloat(value);
|
const valueAsNumber = parseFloat(value);
|
||||||
|
|
||||||
switch (this.state.selected) {
|
switch (this.state.selected) {
|
||||||
case PROFICIENCY_NAMES[1] : return valueAsNumber >= 40;
|
case PROFICIENCY_NAMES[1] :
|
||||||
case PROFICIENCY_NAMES[2] : return valueAsNumber >= 60;
|
return valueAsNumber >= 40;
|
||||||
case PROFICIENCY_NAMES[3] : return valueAsNumber >= 80;
|
case PROFICIENCY_NAMES[2] :
|
||||||
default : return true;
|
return valueAsNumber >= 60;
|
||||||
|
case PROFICIENCY_NAMES[3] :
|
||||||
|
return valueAsNumber >= 80;
|
||||||
|
default :
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -32,19 +36,24 @@ export default class ProficiencyFilter extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onButtonPressed(name) {
|
onButtonPressed(name) {
|
||||||
var newState = {selected: name};
|
const newState = {selected: name};
|
||||||
// set the state, and once it is done, then call filterChangedCallback
|
// set the state, and once it is done, then call filterChangedCallback
|
||||||
this.setState(newState, this.props.filterChangedCallback);
|
this.setState(newState, this.props.filterChangedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var rows = [];
|
const rows = [];
|
||||||
PROFICIENCY_NAMES.forEach((name) => {
|
PROFICIENCY_NAMES.forEach((name) => {
|
||||||
var selected = this.state.selected === name;
|
const selected = this.state.selected === name;
|
||||||
rows.push(
|
rows.push(
|
||||||
<div key={name}>
|
<div key={name}>
|
||||||
<label style={{paddingLeft: 4}}>
|
<label style={{paddingLeft: 4}}>
|
||||||
<input type="radio" checked={selected} name={Math.random()} onChange={this.onButtonPressed.bind(this, name)}/>
|
<input type="radio" checked={selected} name={Math.random()}
|
||||||
|
onChange={this.onButtonPressed.bind(this, name)}/>
|
||||||
{name}
|
{name}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,7 +62,13 @@ export default class ProficiencyFilter extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div style={{textAlign: 'center', background: 'lightgray', width: '100%', display: 'block', borderBottom: '1px solid grey'}}>
|
<div style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
background: 'lightgray',
|
||||||
|
width: '100%',
|
||||||
|
display: 'block',
|
||||||
|
borderBottom: '1px solid grey'
|
||||||
|
}}>
|
||||||
<b>Custom Proficiency Filter</b>
|
<b>Custom Proficiency Filter</b>
|
||||||
</div>
|
</div>
|
||||||
{rows}
|
{rows}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export default class RefData {}
|
export default class RefData {
|
||||||
|
}
|
||||||
|
|
||||||
RefData.FIRST_NAMES = [
|
RefData.FIRST_NAMES = [
|
||||||
"Sophie", "Isabelle", "Emily", "Olivia", "Lily", "Chloe", "Isabella",
|
"Sophie", "Isabelle", "Emily", "Olivia", "Lily", "Chloe", "Isabella",
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import DateComponent from "./DateComponent.jsx";
|
|||||||
import SortableHeaderComponent from "./SortableHeaderComponent";
|
import SortableHeaderComponent from "./SortableHeaderComponent";
|
||||||
|
|
||||||
import "./RichGridExample.css";
|
import "./RichGridExample.css";
|
||||||
|
|
||||||
// take this line out if you do not want to use ag-Grid-Enterprise
|
// take this line out if you do not want to use ag-Grid-Enterprise
|
||||||
import "ag-grid-enterprise";
|
import "ag-grid-enterprise";
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ export default class RichGridExample extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
quickFilterText: null,
|
quickFilterText: null,
|
||||||
showGrid: true,
|
|
||||||
showToolPanel: false,
|
showToolPanel: false,
|
||||||
columnDefs: new ColDefFactory().createColDefs(),
|
columnDefs: new ColDefFactory().createColDefs(),
|
||||||
rowData: new RowDataFactory().createRowData(),
|
rowData: new RowDataFactory().createRowData(),
|
||||||
@@ -53,7 +51,8 @@ export default class RichGridExample extends Component {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// this is a simple property
|
// this is a simple property
|
||||||
rowBuffer: 10 // no need to set this, the default is fine for almost all scenarios
|
rowBuffer: 10, // no need to set this, the default is fine for almost all scenarios,
|
||||||
|
floatingFilter: true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onGridReady = this.onGridReady.bind(this);
|
this.onGridReady = this.onGridReady.bind(this);
|
||||||
@@ -61,12 +60,6 @@ export default class RichGridExample extends Component {
|
|||||||
this.onCellClicked = this.onCellClicked.bind(this);
|
this.onCellClicked = this.onCellClicked.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowGrid(show) {
|
|
||||||
this.setState({
|
|
||||||
showGrid: show
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleToolPanel(event) {
|
onToggleToolPanel(event) {
|
||||||
this.setState({showToolPanel: event.target.checked});
|
this.setState({showToolPanel: event.target.checked});
|
||||||
}
|
}
|
||||||
@@ -123,65 +116,57 @@ export default class RichGridExample extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let gridTemplate;
|
return (
|
||||||
let bottomHeaderTemplate;
|
<div style={{width: '900px'}}>
|
||||||
let topHeaderTemplate;
|
<h1>Rich Grid Example</h1>
|
||||||
|
<div style={{display: "inline-block", width: "100%"}}>
|
||||||
topHeaderTemplate = (
|
<div style={{float: "left"}}>
|
||||||
<div>
|
|
||||||
<div style={{float: 'right'}}>
|
|
||||||
<input type="text" onChange={this.onQuickFilterText.bind(this)}
|
|
||||||
placeholder="Type text to filter..."/>
|
|
||||||
<button id="btDestroyGrid" disabled={!this.state.showGrid}
|
|
||||||
onClick={this.onShowGrid.bind(this, false)}>Destroy Grid
|
|
||||||
</button>
|
|
||||||
<button id="btCreateGrid" disabled={this.state.showGrid} onClick={this.onShowGrid.bind(this, true)}>
|
|
||||||
Create Grid
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style={{padding: '4px'}}>
|
|
||||||
<b>Employees Skills and Contact Details</b><span id="rowCount"/>
|
<b>Employees Skills and Contact Details</b><span id="rowCount"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
<div style={{marginTop: 10}}>
|
||||||
|
|
||||||
// showing the bottom header and grid is optional, so we put in a switch
|
|
||||||
if (this.state.showGrid) {
|
|
||||||
bottomHeaderTemplate = (
|
|
||||||
<div>
|
<div>
|
||||||
<div style={{padding: 4}} className={'toolbar'}>
|
|
||||||
<span>
|
<span>
|
||||||
Grid API:
|
Grid API:
|
||||||
{/* use ref to access the api in selectAll */}
|
<button onClick={() => {
|
||||||
<button onClick={() => { this.refs.myGrid.api.selectAll() }}>Select All</button>
|
this.refs.myGrid.api.selectAll()
|
||||||
<button onClick={this.deselectAll.bind(this)}>Clear Selection</button>
|
}} className="btn btn-primary">Select All</button>
|
||||||
|
<button onClick={this.deselectAll.bind(this)}
|
||||||
|
className="btn btn-primary">Clear Selection</button>
|
||||||
</span>
|
</span>
|
||||||
<span style={{marginLeft: 20}}>
|
<span style={{float: "right"}}>
|
||||||
Column API:
|
Column API:
|
||||||
<button onClick={this.setCountryVisible.bind(this, false)}>Hide Country Column</button>
|
<button onClick={this.setCountryVisible.bind(this, false)} className="btn btn-primary">Hide Country Column</button>
|
||||||
<button onClick={this.setCountryVisible.bind(this, true)}>Show Country Column</button>
|
<button onClick={this.setCountryVisible.bind(this, true)} className="btn btn-primary">Show Country Column</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div style={{clear: 'both'}}></div>
|
<div style={{display: "inline-block", width: "100%", marginTop: 10, marginBottom: 10}}>
|
||||||
<div style={{padding: 4}} className={'toolbar'}>
|
<div style={{float: "left"}}>
|
||||||
<span>
|
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" onChange={this.onToggleToolPanel.bind(this)}/>
|
<input type="checkbox" onChange={this.onToggleToolPanel.bind(this)}
|
||||||
|
style={{marginRight: 5}}/>
|
||||||
Show Tool Panel
|
Show Tool Panel
|
||||||
</label>
|
</label>
|
||||||
<button onClick={this.onRefreshData.bind(this)}>Refresh Data</button>
|
</div>
|
||||||
</span>
|
<div style={{float: "left", marginLeft: 20}}>
|
||||||
<span style={{marginLeft: 20}}>
|
<button onClick={this.onRefreshData.bind(this)} 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..."/>
|
||||||
|
</div>
|
||||||
|
<div style={{float: "right"}}>
|
||||||
Filter API:
|
Filter API:
|
||||||
<button onClick={this.invokeSkillsFilterMethod.bind(this, false)}>Invoke Skills Filter Method</button>
|
<button onClick={this.invokeSkillsFilterMethod.bind(this, false)}
|
||||||
<button onClick={this.dobFilter.bind(this)}>DOB equals to 01/01/2000</button>
|
className="btn btn-primary">Invoke Skills Filter Method
|
||||||
</span>
|
</button>
|
||||||
|
<button onClick={this.dobFilter.bind(this)} className="btn btn-primary">DOB equals to
|
||||||
|
01/01/2000
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div style={{clear: 'both'}}></div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<div style={{height: 400, width: 900}} className="ag-fresh">
|
||||||
gridTemplate = (
|
|
||||||
<div style={{height: 400, width: 945}} className="ag-fresh">
|
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
ref="myGrid"
|
ref="myGrid"
|
||||||
// gridOptions is optional - it's possible to provide
|
// gridOptions is optional - it's possible to provide
|
||||||
@@ -214,16 +199,132 @@ export default class RichGridExample extends Component {
|
|||||||
rowHeight="22"
|
rowHeight="22"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-12"><h1>Rich Grid Example</h1></div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-12">
|
||||||
|
<h5>This example demonstrates many features of ag-Grid.</h5>
|
||||||
|
<p><span style={{fontWeight: 500}}>Select All/Clear Selection</span>: Select or Deselect
|
||||||
|
All
|
||||||
|
Rows</p>
|
||||||
|
<p><span style={{fontWeight: 500}}>Hide/Show Country Column</span>: Select or Deselect
|
||||||
|
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,
|
||||||
|
Group
|
||||||
|
and
|
||||||
|
Aggregate using the Tool Panel</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
|
||||||
|
with
|
||||||
|
the Quick Filter</p>
|
||||||
|
<p><span style={{fontWeight: 500}}>DOB Filter</span>: Set the DOB filter to 01/01/2000
|
||||||
|
using
|
||||||
|
the
|
||||||
|
Filter API (expand the Employee column to show the DOB column)</p>
|
||||||
|
<p><span style={{fontWeight: 500}}>Custom Headers</span>: Sort, Filter and Render
|
||||||
|
Headers
|
||||||
|
using
|
||||||
|
Header Components</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-4">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h4 className="card-title">Grid & Column API</h4>
|
||||||
|
<p className="card-text">Utilise Grid Features Programmatically Using the APIs
|
||||||
|
Available</p>
|
||||||
|
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-api/"
|
||||||
|
className="btn btn-primary">Grid API</a>
|
||||||
|
<a target="_blank" href="https://www.ag-grid.com//javascript-grid-column-api/"
|
||||||
|
className="btn btn-primary">Column API</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-4">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h4 className="card-title">Header Components</h4>
|
||||||
|
<p className="card-text">Customer the Header with React Components</p>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-header-rendering/#headerComponent"
|
||||||
|
className="btn btn-primary">Header Component</a>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-header-rendering/#headerGroupComponent"
|
||||||
|
className="btn btn-primary">Header Group Component</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-4">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h4 className="card-title">Filters</h4>
|
||||||
|
<p className="card-text">Filter with Quick Filters, Floating Filters, Built In
|
||||||
|
Filters
|
||||||
|
or Using the
|
||||||
|
Filter API</p>
|
||||||
|
<a target="_blank" href="https://www.ag-grid.com//javascript-grid-filter-quick/"
|
||||||
|
className="btn btn-primary">Quick
|
||||||
|
Filter</a>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-floating-filter-component/"
|
||||||
|
className="btn btn-primary">Floating Filters</a>
|
||||||
|
<a target="_blank" href="https://www.ag-grid.com//javascript-grid-filtering/"
|
||||||
|
className="btn btn-primary">Built in
|
||||||
|
Filters</a>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-filtering/#accessing-filter-component-instances"
|
||||||
|
className="btn btn-primary">Filter API</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-sm-4">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h4 className="card-title">Tool Panel</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-8">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h4 className="card-title">The Rest</h4>
|
||||||
|
<p className="card-text">Pinned Columns, Checkbox Selection, Customer Renderers,
|
||||||
|
Data
|
||||||
|
Updates</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-pinning/"
|
||||||
|
className="btn btn-primary">Pinned Column</a>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-selection/#checkboxSelection"
|
||||||
|
className="btn btn-primary">Checkbox Selection</a>
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://www.ag-grid.com//javascript-grid-cell-rendering/"
|
||||||
|
className="btn btn-primary">Cell
|
||||||
|
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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div style={{width: '950px'}}>
|
|
||||||
<div style={{padding: '4px'}}>
|
|
||||||
{topHeaderTemplate}
|
|
||||||
{bottomHeaderTemplate}
|
|
||||||
{gridTemplate}
|
|
||||||
</div>
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import RefData from './RefData';
|
|||||||
export default class RowDataFactory {
|
export default class RowDataFactory {
|
||||||
|
|
||||||
createRowData() {
|
createRowData() {
|
||||||
var rowData = [];
|
const rowData = [];
|
||||||
|
|
||||||
for (var i = 0; i < 200; i++) {
|
for (let i = 0; i < 200; i++) {
|
||||||
var countryData = RefData.COUNTRIES[i % RefData.COUNTRIES.length];
|
const countryData = RefData.COUNTRIES[i % RefData.COUNTRIES.length];
|
||||||
rowData.push({
|
rowData.push({
|
||||||
name: RefData.FIRST_NAMES[i % RefData.FIRST_NAMES.length] + ' ' + RefData.LAST_NAMES[i % RefData.LAST_NAMES.length],
|
name: RefData.FIRST_NAMES[i % RefData.FIRST_NAMES.length] + ' ' + RefData.LAST_NAMES[i % RefData.LAST_NAMES.length],
|
||||||
skills: {
|
skills: {
|
||||||
@@ -32,8 +32,8 @@ export default class RowDataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createRandomPhoneNumber() {
|
createRandomPhoneNumber() {
|
||||||
var result = '+';
|
let result = '+';
|
||||||
for (var i = 0; i < 12; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
result += Math.round(Math.random() * 10);
|
result += Math.round(Math.random() * 10);
|
||||||
if (i === 2 || i === 5 || i === 8) {
|
if (i === 2 || i === 5 || i === 8) {
|
||||||
result += ' ';
|
result += ' ';
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import RefData from './RefData';
|
|||||||
export default class SkillsCellRenderer extends React.Component {
|
export default class SkillsCellRenderer extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var skills = [];
|
const skills = [];
|
||||||
var rowData = this.props.data;
|
const rowData = this.props.data;
|
||||||
RefData.IT_SKILLS.forEach((skill) => {
|
RefData.IT_SKILLS.forEach((skill) => {
|
||||||
if (rowData && rowData.skills && rowData.skills[skill]) {
|
if (rowData && rowData.skills && rowData.skills[skill]) {
|
||||||
skills.push(<img key={skill} src={'images/skills/' + skill + '.png'} width={16} title={skill}/>);
|
skills.push(<img key={skill} src={'images/skills/' + skill + '.png'} width={16} title={skill}/>);
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ export default class SkillsFilter extends React.Component {
|
|||||||
// called by agGrid
|
// called by agGrid
|
||||||
doesFilterPass(params) {
|
doesFilterPass(params) {
|
||||||
|
|
||||||
var rowSkills = params.data.skills;
|
const rowSkills = params.data.skills;
|
||||||
var passed = true;
|
let passed = true;
|
||||||
|
|
||||||
RefData.IT_SKILLS.forEach((skill) => {
|
RefData.IT_SKILLS.forEach((skill) => {
|
||||||
if (this.state[skill]) {
|
if (this.state[skill]) {
|
||||||
@@ -56,16 +56,20 @@ export default class SkillsFilter extends React.Component {
|
|||||||
return passed;
|
return passed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
// called by agGrid
|
// called by agGrid
|
||||||
isFilterActive() {
|
isFilterActive() {
|
||||||
var somethingSelected = this.state.android || this.state.css ||
|
const somethingSelected = this.state.android || this.state.css ||
|
||||||
this.state.html5 || this.state.mac || this.state.windows;
|
this.state.html5 || this.state.mac || this.state.windows;
|
||||||
return somethingSelected;
|
return somethingSelected;
|
||||||
};
|
};
|
||||||
|
|
||||||
onSkillChanged(skill, event) {
|
onSkillChanged(skill, event) {
|
||||||
var newValue = event.target.checked;
|
const newValue = event.target.checked;
|
||||||
var newModel = {};
|
const newModel = {};
|
||||||
newModel[skill] = newValue;
|
newModel[skill] = newValue;
|
||||||
// set the state, and once it is done, then call filterChangedCallback
|
// set the state, and once it is done, then call filterChangedCallback
|
||||||
this.setState(newModel, this.props.filterChangedCallback);
|
this.setState(newModel, this.props.filterChangedCallback);
|
||||||
@@ -77,12 +81,13 @@ export default class SkillsFilter extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
var skillsTemplates = [];
|
const skillsTemplates = [];
|
||||||
RefData.IT_SKILLS.forEach((skill, index) => {
|
RefData.IT_SKILLS.forEach((skill, index) => {
|
||||||
|
|
||||||
var skillName = RefData.IT_SKILLS_NAMES[index];
|
const skillName = RefData.IT_SKILLS_NAMES[index];
|
||||||
var template = (
|
const template = (
|
||||||
<label key={skill} style={{border: '1px solid lightgrey', margin: 4, padding: 4, display: 'inline-block'}}>
|
<label key={skill}
|
||||||
|
style={{border: '1px solid lightgrey', margin: 4, padding: 4, display: 'inline-block'}}>
|
||||||
<span>
|
<span>
|
||||||
<div style={{textAlign: 'center'}}>{skillName}</div>
|
<div style={{textAlign: 'center'}}>{skillName}</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -98,7 +103,13 @@ export default class SkillsFilter extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{width: 380}}>
|
<div style={{width: 380}}>
|
||||||
<div style={{textAlign: 'center', background: 'lightgray', width: '100%', display: 'block', borderBottom: '1px solid grey'}}>
|
<div style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
background: 'lightgray',
|
||||||
|
width: '100%',
|
||||||
|
display: 'block',
|
||||||
|
borderBottom: '1px solid grey'
|
||||||
|
}}>
|
||||||
<b>Custom Skills Filter</b>
|
<b>Custom Skills Filter</b>
|
||||||
</div>
|
</div>
|
||||||
{skillsTemplates}
|
{skillsTemplates}
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ export default class SortableHeaderComponent extends React.Component {
|
|||||||
let upArrowClass = "customSortUpLabel " + (this.state.sorted === 'asc' ? " active" : "");
|
let upArrowClass = "customSortUpLabel " + (this.state.sorted === 'asc' ? " active" : "");
|
||||||
let removeArrowClass = "customSortRemoveLabel " + (this.state.sorted === '' ? " active" : "");
|
let removeArrowClass = "customSortRemoveLabel " + (this.state.sorted === '' ? " active" : "");
|
||||||
|
|
||||||
sortElements.push(<div key={`up${this.props.displayName}`} className={downArrowClass} onClick={this.onSortRequested.bind(this, 'desc')}><i
|
sortElements.push(<div key={`up${this.props.displayName}`} className={downArrowClass}
|
||||||
className="fa fa-long-arrow-down"/></div>)
|
onClick={this.onSortRequested.bind(this, 'desc')}><i
|
||||||
sortElements.push(<div key={`down${this.props.displayName}`} className={upArrowClass} onClick={this.onSortRequested.bind(this, 'asc')}><i
|
className="fa fa-long-arrow-down"/></div>);
|
||||||
className="fa fa-long-arrow-up"/></div>)
|
sortElements.push(<div key={`down${this.props.displayName}`} className={upArrowClass}
|
||||||
sortElements.push(<div key={`minus${this.props.displayName}`} className={removeArrowClass} onClick={this.onSortRequested.bind(this, '')}><i
|
onClick={this.onSortRequested.bind(this, 'asc')}><i
|
||||||
|
className="fa fa-long-arrow-up"/></div>);
|
||||||
|
sortElements.push(<div key={`minus${this.props.displayName}`} className={removeArrowClass}
|
||||||
|
onClick={this.onSortRequested.bind(this, '')}><i
|
||||||
className="fa fa-times"/></div>)
|
className="fa fa-times"/></div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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: 900, 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -62,7 +62,7 @@ class GridComponent extends Component {
|
|||||||
// this requires each row to have a uniquely identifying property - in this case the row data "symbol" (see getRowNodeId)
|
// this requires each row to have a uniquely identifying property - in this case the row data "symbol" (see getRowNodeId)
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{height: 400, width: 945, marginTop: 15}}
|
<div style={{height: 400, width: 900, marginTop: 15}}
|
||||||
className="ag-fresh">
|
className="ag-fresh">
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
// properties
|
// properties
|
||||||
|
|||||||
Reference in New Issue
Block a user