iteration

This commit is contained in:
Ceolter
2016-01-24 12:32:09 +00:00
parent 2283363c38
commit c53f9e4896
5 changed files with 259 additions and 8 deletions

View File

@@ -1,16 +1,63 @@
import ReactDOM from 'react-dom';
import React from 'react';
import AgGrid from 'ag-grid';
import ComponentUtil from './ComponentUtil';
export class AgGridReact extends React.Component {
export default class AgGridReact extends React.Component {
componentDidMount() {
var domNode = ReactDOM.findDOMNode(this);
AgGrid(domNode, this.props.gridOptions);
this.gridOptions = ComponentUtil.copyAttributesToGridOptions(this.props.gridOptions, this.props);
AgGrid(domNode, this.gridOptions);
this.api = this.gridOptions.api;
this.columnApi = this.gridOptions.columnApi;
this.api.addGlobalListener(this.globalEventListener.bind(this));
}
// this method is duplicated, taken from gridOptionsWrapper
getCallbackForEvent(eventName) {
if (!eventName || eventName.length < 2) {
return eventName;
} else {
return 'on' + eventName[0].toUpperCase() + eventName.substr(1);
}
}
// duplicated, taken from gridOptionsWrapper
globalEventListener(eventName, event) {
var callbackMethodName = this.getCallbackForEvent(eventName);
var callbackFromProps = this.props[callbackMethodName];
if (callbackFromProps) {
callbackFromProps(event);
}
}
shouldComponentUpdate () {
// we want full control of the dom, as ag-Grid doesn't use React internally,
// so for performance reasons we tell React we don't need render called after
// property changes.
return false;
}
componentWillReceiveProps(nextProps) {
// keeping consistent with web components, put changing
// values in currentValue and previousValue pairs and
// not include items that have not changed.
var changes = {};
ComponentUtil.ALL_PROPERTIES.forEach( (propKey)=> {
if (this.props[propKey]!==nextProps[propKey]) {
changes[propKey] = {
previousValue: this.props[propKey],
currentValue: nextProps[propKey]
};
}
});
ComponentUtil.processOnChange(changes, this.gridOptions, this.api, this.columnApi);
}
componentWillUnmount() {
//console.log('componentWillUnmount');
this.api.destroy();
}
render() {
@@ -19,7 +66,33 @@ export class AgGridReact extends React.Component {
}
AgGridReact.propTypes = {
'style': React.PropTypes.object,
'className': React.PropTypes.string,
'gridOptions': React.PropTypes.object
style: React.PropTypes.object,
className: React.PropTypes.string,
gridOptions: React.PropTypes.object
// we should iterate through all the properties and add them here
//onRowSelected: React.PropTypes.func,
//showToolPanel: React.PropTypes.bool
};
ComponentUtil.SIMPLE_BOOLEAN_PROPERTIES
.concat(ComponentUtil.WITH_IMPACT_BOOLEAN_PROPERTIES)
.forEach( (propKey)=> {
AgGridReact.propTypes[propKey] = React.PropTypes.bool;
});
//ComponentUtil.SIMPLE_PROPERTIES
// .concat(ComponentUtil.WITH_IMPACT_STRING_PROPERTIES)
// .forEach( (propKey)=> {
// AgGridReact.propTypes[propKey] = React.PropTypes.bool;
// });
//.concat(ComponentUtil.)
//.concat(ComponentUtil.SIMPLE_NUMBER_PROPERTIES)
//.concat(ComponentUtil.WITH_IMPACT_OTHER_PROPERTIES)
//.concat(ComponentUtil.WITH_IMPACT_NUMBER_PROPERTIES)
//.concat(ComponentUtil.CALLBACKS),
var i = new AgGridReact();
console.log(i);

154
src/ComponentUtil.js Normal file
View File

@@ -0,0 +1,154 @@
export default class ComponentUtil {}
ComponentUtil.SIMPLE_PROPERTIES = [
'sortingOrder',
'icons','localeText','localeTextFunc',
'groupColumnDef','context','rowStyle','rowClass','headerCellRenderer',
'groupDefaultExpanded','slaveGrids','rowSelection',
'overlayLoadingTemplate','overlayNoRowsTemplate',
'headerCellTemplate'
];
ComponentUtil.SIMPLE_NUMBER_PROPERTIES = [
'rowHeight','rowBuffer','colWidth'
];
ComponentUtil.SIMPLE_BOOLEAN_PROPERTIES = [
'virtualPaging','toolPanelSuppressGroups','toolPanelSuppressValues','rowsAlreadyGrouped',
'suppressRowClickSelection','suppressCellSelection','suppressHorizontalScroll','debug',
'enableColResize','enableCellExpressions','enableSorting','enableServerSideSorting',
'enableFilter','enableServerSideFilter','angularCompileRows','angularCompileFilters',
'angularCompileHeaders','groupSuppressAutoColumn','groupSelectsChildren','groupHideGroupColumns',
'groupIncludeFooter','groupUseEntireRow','groupSuppressRow','groupSuppressBlankHeader','forPrint',
'suppressMenuHide','rowDeselection','unSortIcon','suppressMultiSort','suppressScrollLag',
'singleClickEdit','suppressLoadingOverlay','suppressNoRowsOverlay','suppressAutoSize',
'suppressParentsInRowNodes'
];
ComponentUtil.WITH_IMPACT_STRING_PROPERTIES = ['quickFilterText'];
ComponentUtil.WITH_IMPACT_NUMBER_PROPERTIES = ['headerHeight'];
ComponentUtil.WITH_IMPACT_BOOLEAN_PROPERTIES = ['showToolPanel'];
ComponentUtil.WITH_IMPACT_OTHER_PROPERTIES = [
'rowData','floatingTopRowData','floatingBottomRowData',
'columnDefs','datasource'];
ComponentUtil.CALLBACKS = ['groupRowInnerRenderer', 'groupRowRenderer', 'groupAggFunction',
'isScrollLag','isExternalFilterPresent','doesExternalFilterPass','getRowClass','getRowStyle',
'headerCellRenderer','getHeaderCellTemplate'];
ComponentUtil.ALL_PROPERTIES = ComponentUtil.SIMPLE_PROPERTIES
.concat(ComponentUtil.SIMPLE_NUMBER_PROPERTIES)
.concat(ComponentUtil.SIMPLE_BOOLEAN_PROPERTIES)
.concat(ComponentUtil.WITH_IMPACT_NUMBER_PROPERTIES)
.concat(ComponentUtil.WITH_IMPACT_BOOLEAN_PROPERTIES)
.concat(ComponentUtil.WITH_IMPACT_OTHER_PROPERTIES);
ComponentUtil.copyAttributesToGridOptions = function(gridOptions, component) {
// create empty grid options if none were passed
if (typeof gridOptions !== 'object') {
gridOptions = {};
}
// to allow array style lookup in TypeScript, take type away from 'this' and 'gridOptions'
var pGridOptions = gridOptions;
// add in all the simple properties
ComponentUtil.SIMPLE_PROPERTIES.concat(ComponentUtil.WITH_IMPACT_OTHER_PROPERTIES).forEach( (key)=> {
if (typeof (component)[key] !== 'undefined') {
pGridOptions[key] = component[key];
}
});
ComponentUtil.SIMPLE_BOOLEAN_PROPERTIES.concat(ComponentUtil.WITH_IMPACT_BOOLEAN_PROPERTIES).forEach( (key)=> {
if (typeof (component)[key] !== 'undefined') {
pGridOptions[key] = ComponentUtil.toBoolean(component[key]);
}
});
ComponentUtil.SIMPLE_NUMBER_PROPERTIES.concat(ComponentUtil.WITH_IMPACT_NUMBER_PROPERTIES).forEach( (key)=> {
if (typeof (component)[key] !== 'undefined') {
pGridOptions[key] = ComponentUtil.toNumber(component[key]);
}
});
return gridOptions;
};
ComponentUtil.processOnChange = function(changes, gridOptions, api) {
// to allow array style lookup in TypeScript, take type away from 'this' and 'gridOptions'
var pGridOptions = gridOptions;
// check if any change for the simple types, and if so, then just copy in the new value
ComponentUtil.SIMPLE_PROPERTIES.forEach( (key)=> {
if (changes[key]) {
pGridOptions[key] = changes[key].currentValue;
}
});
ComponentUtil.SIMPLE_BOOLEAN_PROPERTIES.forEach( (key)=> {
if (changes[key]) {
pGridOptions[key] = ComponentUtil.toBoolean(changes[key].currentValue);
}
});
ComponentUtil.SIMPLE_NUMBER_PROPERTIES.forEach( (key)=> {
if (changes[key]) {
pGridOptions[key] = ComponentUtil.toNumber(changes[key].currentValue);
}
});
if (changes.showToolPanel) {
api.showToolPanel(changes.showToolPanel.currentValue);
}
if (changes.quickFilterText) {
api.setQuickFilter(changes.quickFilterText.currentValue);
}
if (changes.rowData) {
api.setRowData(changes.rowData.currentValue);
}
if (changes.floatingTopRowData) {
api.setFloatingTopRowData(changes.floatingTopRowData.currentValue);
}
if (changes.floatingBottomRowData) {
api.setFloatingBottomRowData(changes.floatingBottomRowData.currentValue);
}
if (changes.columnDefs) {
api.setColumnDefs(changes.columnDefs.currentValue);
}
if (changes.datasource) {
api.setDatasource(changes.datasource.currentValue);
}
if (changes.headerHeight) {
api.setHeaderHeight(changes.headerHeight.currentValue);
}
// need to review this, it is not impacting anything, they should
// call something on the API to update the grid
if (changes.groupAggFunction) {
gridOptions.groupAggFunction = changes.groupAggFunction;
}
};
ComponentUtil.toBoolean = function(value) {
if (typeof value === 'boolean') {
return value;
} else if (typeof value === 'string') {
// for boolean, compare to empty String to allow attributes appearing with
// not value to be treated as 'true'
return value.toUpperCase() === 'TRUE' || value=='';
} else {
return false;
}
};
ComponentUtil.toNumber = function(value) {
if (typeof value === 'number') {
return value;
} else if (typeof value === 'string') {
return Number(value);
} else {
return undefined;
}
};

View File

@@ -1,4 +1,4 @@
export class RefData {}
export default class RefData {}
RefData.FIRST_NAMES = [
"Sophie", "Isabelle", "Emily", "Olivia", "Lily", "Chloe", "Isabella",

View File

@@ -0,0 +1,21 @@
import React from 'react';
import RefData from './RefData';
export default class SkillsCellRenderer extends React.Component {
render() {
var skills = [];
RefData.IT_SKILLS.forEach( (skill) => {
if (this.props.skills[skill]) {
skills.push(<img key={skill} src={'images/skills/' + skill + '.png'} width={16} title={skill} />);
}
});
return <span>{skills}</span>;
}
}
SkillsCellRenderer.propTypes = {
skills: React.PropTypes.object
};

View File

@@ -2,10 +2,13 @@
import ReactDOM from 'react-dom';
import React from 'react';
import {MyApp} from './myApp.jsx';
import MyApp from './MyApp.jsx';
// is there a better way of doing this?
import 'ag-grid-root/ag-grid.css';
import 'ag-grid-root/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.
document.addEventListener('DOMContentLoaded', ()=> {
var container = document.getElementById('myAppContainer');
ReactDOM.render(