tcomb-form
tcomb-form copied to clipboard
onChange reporting incorrect input id with dynamically generated options created using textbox.clone
I am replacing the default textbox so I that I can apply custom styling.
In example #1 below, I use textbox.clone to manually assign customTextBox to both "style" and "color" input fields. Then, when onChange gets called, event.target.id correctly reports either the "style" or "color" id.
However, when I attempt to build the options programatically (see example #2), onChange always gets called with the "color" id, even when it is the "style" input field that is changed. I am creating dynamic forms, so I need to figure out how to get example #2 working properly.
Please let me know if I'm approaching this the wrong way.
EXAMPLE #1
'use strict';
import React, {Component} from 'react';
import t from 'tcomb-form';
const Form = t.form.Form;
const styles = {
input: {
width: "227px",
fontSize: "1rem",
fontFamily: "Palatino-Linotype"
}
};
export default class ItemDescription extends Component {
render() {
var item = {description: {style: "modern", color: "reds"}};
return(
<ItemDescription2
item={item}
/>
);
}
}
class ItemDescription2 extends Component {
constructor(props) {
super(props);
this.getType = this.getType.bind(this);
this.getOptions = this.getOptions.bind(this);
this.getTemplate = this.getTemplate.bind(this);
this.onChange = this.onChange.bind(this);
this.onSave = this.onSave.bind(this);
this.state = {
type: this.getType(null),
options: this.getOptions(null),
value: {}
};
}
componentWillReceiveProps( nextProps ) {
this.setState({
value: Object.assign({}, nextProps.item.description),
type: this.getType(nextProps.item),
options: this.getOptions(nextProps.item)
});
}
getType(item) {
var descriptionType = {};
if (item) {
var itemDescriptor = item.description;
for (var property in itemDescriptor ) {
descriptionType[property] = t.String;
}
}
return(
t.struct(descriptionType)
);
}
getTemplate(item) {
var that = this;
return function ( locals) {
var lineItems = null;
if (item) {
var itemDescriptor = item.description;
lineItems = Object.keys(itemDescriptor).map(function(key) {
return(
<div key={key}>
{key}
{locals.inputs[key]}
</div>
);
});
}
return(
<div style={styles.description}>
{lineItems}
</div>
);
}
}
getOptions(item) {
var options = {
auto: 'placeholders',
fields: {},
template: null
}
if (item) {
var customTextBoxStyle = t.form.Form.templates.textbox.clone({
renderInput: (locals) => {
return <input id={'style'} onChange={this.onChange} style={styles.input} value={locals.value} />
}
});
var customTextBoxColor = t.form.Form.templates.textbox.clone({
renderInput: (locals) => {
return <input id={'color'} onChange={this.onChange} style={styles.input} value={locals.value} />
}
});
options.fields = {
style: {
template: customTextBoxStyle
},
color: {
template: customTextBoxColor
}
};
options.template = this.getTemplate(item);
}
return options;
}
onChange(event) {
var value = event.target.value;
var key = event.target.id;
var update = {};
update[key] = value;
this.setState({value: Object.assign({}, this.state.value, update) });
}
onSave(e) {
e.preventDefault();
var value = this.state.value;
console.log(value);
}
render() {
return (
<form onSubmit={this.onSave}>
<Form ref="form"
autocomplete={"off"}
type={this.state.type}
options={this.state.options}
value={this.state.value}
onChange={this.onChange}
/>
<button style={styles.button} type="submit">Save</button>
</form>
);
}
}
EXAMPLE #2
Only getOptions has changed...
getOptions(item) {
var options = {
auto: 'placeholders',
fields: {},
template: null
}
if (item) {
var itemDescriptor = item.description;
var customTextBox = {};
var templates = {};
for (var property in itemDescriptor ) {
options.fields[property] = {
template: t.form.Form.templates.textbox.clone({
// override just the input default implementation (labels, help, error will be preserved)
renderInput: (locals) => {
return <input id={property} onChange={this.onChange} style={styles.input} value={locals.value} />
}
})
}
}
options.template = this.getTemplate(item);
}
return options;
}
Environment:
- tcomb-form v0.9.10
- react v15.0.2