Closed patgod85 closed 8 years ago
Hi,
you can use the config
option (https://github.com/gcanti/tcomb-form/blob/master/GUIDE.md#templates)
class BirthDateFactory extends t.form.Textbox {
getTemplate() {
return (locals) => {
// I have to prepare min and max here using of person.tariff
console.log(locals.config); // => your custom configuration: {a: 1}
return (
<div>
<DateTimePicker
min={min}
max={max}
...
/>
</div>
);
};
}
}
...
var options = {
item: {
fields: {
birthDate: {
factory: BirthDateFactory,
config: { // <= your custom configuration
a: 1
}
}
}
}
};
If I have values like so:
var values = [
{
name: 'Mark',
tariff: 'adult'
},
{
name: 'Jacob',
tariff: 'child'
}
];
If I use config I can pass either whole array or other static value.
But I need to pass the tariff of current model. I need to get data of the item's layer from the input's layer. I want to see something like that:
var options = {
item: {
fields: {
birthDate: {
factory: BirthDateFactory,
config: function(locals, item){ // <= Function instead of const value
locals.config.tariff = item.value.tariff;
}
}
}
}
};
And then access to tariff in factory via locals.factory
I hope it makes sense
You could store the options in the component state:
var Person = t.struct({
name: t.String,
tariff: t.String,
birthDate: t.String
});
function birthDateTemplate(locals) {
console.log(locals.config);
return t.form.Form.templates.textbox(locals);
}
const App = React.createClass({
getInitialState() {
return {
value: {},
options: {
fields: {
birthDate: {
template: birthDateTemplate,
config: {}
}
}
}
};
},
onSubmit(evt) {
evt.preventDefault();
var value = this.refs.form.getValue();
if (value) {
console.log(value);
}
},
onChange(value) {
const options = t.update(this.state.options, {
fields: {
birthDate: {
config: {
tariff: { $set: value.tariff } // <= send the current tariff value to your custom template
}
}
}
});
this.setState({value, options});
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={Person}
options={this.state.options}
value={this.state.value}
onChange={this.onChange}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
);
}
});
I'm not sure that understood you correct.
I update my state this way:
const options = t.update(
this.state.options,
{
item: {
fields: {
birthDate: {
config: {
tariff: {$set: value[path[0]].tariff}
}
}
}
}
}
);
this.setState({options});
In this case for both of my people in config I see the same value.
Onload I see in console:
Object { tariff: "" }
Object { tariff: "" }
After any field of Person 1 change:
Object { tariff: "adult" }
Object { tariff: "adult" }
After any field of Person 2 change:
Object { tariff: "child" }
Object { tariff: "child" }
What I do wrong?
Sorry I didn't notice you have to handle a list of Person
s.
Updated example:
var Person = t.struct({
name: t.String,
tariff: t.String,
birthDate: t.String
});
var Passengers = t.list(Person);
// your custom template
function birthDateTemplate(locals) {
// get the current value of tariff for this item...
const value = locals.config.value || [];
const path = locals.path;
const person = value[path[0]] || {};
console.log(path.join(', '), person.tariff);
return t.form.Form.templates.textbox(locals);
}
const App = React.createClass({
getInitialState() {
return {
value: [],
options: {
item: {
fields: {
birthDate: {
template: birthDateTemplate,
config: {}
}
}
}
}
};
},
onSubmit(evt) {
evt.preventDefault();
var value = this.refs.form.getValue();
if (value) {
console.log(value);
}
},
onChange(value, path) {
const options = t.update(this.state.options, {
item: {
fields: {
birthDate: {
config: {
value: { $set: value },
path: { $set: path }
}
}
}
}
});
this.setState({value, options});
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={Passengers}
options={this.state.options}
value={this.state.value}
onChange={this.onChange}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
);
}
});
Thank you for your help and quick answers!
And what is the correct way to set the config with value and path onLoad?
Sorry, have you seen my last comment?
And what is the correct way to set the config with value and path onLoad?
What about this?
var Person = t.struct({
tariff: t.String,
birthDate: t.String
});
var Passengers = t.list(Person);
var initialValue = [
{
tariff: 'a',
birthDate: 'b'
},
{
tariff: 'c',
birthDate: 'd'
}
];
function birthDateTemplate(locals) {
const value = locals.config.value;
const index = locals.path[0];
const person = value[index] || {};
console.log(index, person.tariff);
return t.form.Form.templates.textbox(locals);
}
const App = React.createClass({
getInitialState() {
return {
value: initialValue,
options: {
item: {
fields: {
birthDate: {
template: birthDateTemplate,
config: {
value: initialValue // <= updated
}
}
}
}
}
};
},
onSubmit(evt) {
evt.preventDefault();
var value = this.refs.form.getValue();
if (value) {
console.log(value);
}
},
onChange(value, path) {
const options = t.update(this.state.options, {
item: {
fields: {
birthDate: {
config: {
value: { $set: value } // <= updated
}
}
}
}
});
this.setState({value, options});
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={Passengers}
options={this.state.options}
value={this.state.value}
onChange={this.onChange}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
);
}
});
May be this way is easier?
...
componentDidMount() {
this.onChange(this.state.value);
},
...
Nope. You need a valid value
also during the first rendering. Setting the value in getInitialState
seems more neat.
Ok. Thank you
Hi, I'm very inspired by your component.
At the moment I can't realize how to solve the problem
I have the a list:
And I don't know how to pass the tariff into the BirthDateFactory.
I need to set bounds of datepicker depends of tariff.
Can you help me?
Thanks