Created
January 7, 2014 08:18
-
-
Save rmoch/8296176 to your computer and use it in GitHub Desktop.
React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @jsx React.DOM */ | |
// base on http://jsfiddle.net/spicyj/M6h22/ | |
function copy(obj) { | |
var newObj = {}; | |
for (var key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
newObj[key] = obj[key]; | |
} | |
} | |
return newObj; | |
} | |
var ConditionFieldMixin = { | |
propTypes: { | |
data: React.PropTypes.string.isRequired, | |
// Will be called with the new value for the cell | |
onChange: React.PropTypes.func.isRequired | |
}, | |
handleChange: function(evt) { | |
this.props.onChange(evt.target.value); | |
} | |
} | |
var ConditionField = React.createClass({ | |
mixins: [ConditionFieldMixin], | |
render: function() { | |
return ( | |
<select value={this.props.data} onChange={this.handleChange}> | |
<option value="">Selectionnez un champ</option> | |
<option value="FIELD1">Champ 1</option> | |
<option value="FIELD2">Champ 2</option> | |
</select> | |
); | |
} | |
}); | |
var ConditionOperator = React.createClass({ | |
mixins: [ConditionFieldMixin], | |
render: function() { | |
return ( | |
<select value={this.props.data} onChange={this.handleChange}> | |
<option value="">Selectionnez un opérateur</option> | |
<option value="EQUAL">Egal à</option> | |
<option value="GT">Plus grand que</option> | |
</select> | |
); | |
} | |
}); | |
var ConditionValue = React.createClass({ | |
mixins: [ConditionFieldMixin], | |
render: function() { | |
return <input value={this.props.data} onChange={this.handleChange}/>; | |
} | |
}); | |
var Condition = React.createClass({ | |
propTypes: { | |
data: React.PropTypes.object.isRequired, | |
// Will be called with a cell's name and its new value | |
// onFieldChange: React.PropTypes.func.isRequired | |
}, | |
handleChange: function(prop, val) { | |
// (Since this function simply calls this.props.onFieldChange, we could | |
// instead refer to the callback directly below.) | |
this.props.onFieldChange(prop, val); | |
}, | |
render: function() { | |
return <span> | |
<ConditionField data={this.props.data.field} | |
onChange={this.handleChange.bind(null, "field")} /> | |
<ConditionOperator data={this.props.data.operator} | |
onChange={this.handleChange.bind(null, "operator")} /> | |
<ConditionValue data={this.props.data.value} | |
onChange={this.handleChange.bind(null, "value")} /> | |
</span>; | |
} | |
}); | |
var ConditionBlock = React.createClass({ | |
propTypes: { | |
data: React.PropTypes.array.isRequired, | |
// Will be called with a cell's row index, name, and new value | |
}, | |
deleteCondition: function(idx) { | |
this.props.data.splice(idx, 1); | |
this.forceUpdate(); | |
}, | |
addCondition: function() { | |
this.props.data.push({'id': this.props.data.length + 1, 'field': '', operator: '', value: ''}) | |
this.forceUpdate(); | |
}, | |
render: function() { | |
var conditions = this.props.data.map(function(rowData, index) { | |
return <div> | |
<Condition key={index} data={rowData} /> | |
<button type="button" onClick={this.deleteCondition.bind(null, index)}>Delete</button> | |
</div> | |
}, this); | |
return <div className="">{conditions} | |
<button type="button" onClick={this.addCondition}>Add Condition</button> | |
</div>; | |
} | |
}); | |
var Rule = React.createClass({ | |
deleteConditionBlock: function(idx) { | |
this.props.data.blocks.splice(idx, 1); | |
this.forceUpdate(); | |
}, | |
addConditionBlock: function() { | |
this.props.data.blocks.push([{'id': this.props.data.length + 1, 'field': '', operator: '', value: ''}]) | |
this.forceUpdate(); | |
}, | |
render: function() { | |
var conditions = this.props.data.blocks.map(function(rowData, index) { | |
return <div> | |
<ConditionBlock key={index} data={rowData} /> | |
<button type="button" onClick={this.deleteConditionBlock.bind(null, index)}>Delete condition block</button> | |
</div> | |
}, this); | |
return <div className="">{conditions} | |
<button type="button" onClick={this.addConditionBlock}>Add Condition block</button> | |
</div>; | |
} | |
}); | |
var Selector = React.createClass({ | |
getInitialState: function() { | |
return {data: this.props.initialData}; | |
}, | |
handleCellChange: function(rowIdx, prop, val) { | |
// If we were lazy here, we would simply write | |
// this.state.data[rowIdx][prop] = val; | |
// this.forceUpdate(); | |
// but mutating in this way can be confusing and prevents performance | |
// optimizations later, so we instead treat the current data as | |
// immutable and copy it when modifying: | |
var row = copy(this.state.data[rowIdx]); | |
row[prop] = val; | |
var rows = this.state.data.slice(); | |
rows[rowIdx] = row; | |
this.setState({data: rows}); | |
}, | |
flushButtonClick: function(evt) { | |
console.log(this.state.data); | |
}, | |
render: function() { | |
var rules = this.state.data.rules.map(function(ruleData, index) { | |
return <span> | |
<Rule data={ruleData} onFieldChange={this.handleCellChange} /> | |
</span>; | |
}, this); | |
return <span>{rules} | |
<button type="button" onClick={this.flushButtonClick}>Flush Data</button> | |
</span>; | |
} | |
}); | |
var selector = { | |
"type": "text_message", | |
"value": ["this is the message", "this is the rich message"], | |
"name": "text message selector", | |
"rules": [{ | |
"value": ["an other message", "an other rich message"], | |
"blocks": [ | |
[ | |
{ | |
"field": "FIELD1", | |
"operator": "EQUAL", | |
"value": "10" | |
}, | |
{ | |
"field": "FIELD2", | |
"operator": "EQUAL", | |
"value": "42" | |
} | |
],[ | |
{ | |
"field": "FIELD1", | |
"operator": "EQUAL", | |
"value": "0" | |
} | |
] | |
] | |
}, | |
{ | |
"value": ["yet an other message", "yet an other rich message"], | |
"blocks": [ | |
[ | |
{ | |
"field": "floor", | |
"operator": "==", | |
"value": "2" | |
} | |
] | |
] | |
}] | |
} | |
React.renderComponent( | |
<Selector initialData={selector} />, document.getElementById('target2') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment