Closed hhumphrey84 closed 8 years ago
Should be something like this:
var FormView = React.createClass({
getInitialState: function () {
return {
value: {
name: 'Foobar',
players: [0,1,2] // your enum key values
}
};
},
render: function () {
// set the initial values on the form
return(<div><Form value={this.state.value} /></div>);
}
});
Sorry for the delay in getting back to you. This put me on the right track, and I was able to set my default list quite easily in the end.
A further issue has arisen with validating my list of enums as this list is populated after an API call:
newOptions = t.update(this.state.options, {
fields: {
players: {
item: { options: { '$set': allPlayers } }
}
}
});
this.setState({ options: newOptions });
allPlayers being the return value from the API call. This works fine, I have my multi select with my select dropdown populated with the names of all the potential players.
However if I click submit the tcomb validation is checking if the values selected match the values in the original enum object....which if course was an empty object waiting to be populated:
Enums.is = function (x) {
return map.hasOwnProperty(x);
};
Any idea what I'm doing wrong? Apologies again!
If I understand, a simple solution would be to just use a list of strings (since you populate the options it's not possible to get type errors):
const Type = t.struct({
name: t.String,
players: t.list(t.String) // <= just a list of strings
});
const initialPlayers = [
{value: 'A', text: 'Player A'},
{value: 'B', text: 'Player B'},
{value: 'C', text: 'Player C'},
{value: 'D', text: 'Player D'}
];
const allPlayers = [
{value: 'A', text: 'Player A'},
{value: 'B', text: 'Player B'},
{value: 'C', text: 'Player C'},
{value: 'D', text: 'Player D'},
{value: 'E', text: 'Player E'},
{value: 'F', text: 'Player F'},
{value: 'G', text: 'Player G'},
{value: 'H', text: 'Player H'},
{value: 'I', text: 'Player I'},
{value: 'L', text: 'Player L'}
];
var App = React.createClass({
getInitialState() {
return {
value: {
name: 'Foo',
players: ['A', 'C']
},
options: {
fields: {
players: {
item: {
factory: t.form.Select,
options: initialPlayers
}
}
}
}
};
},
componentDidMount() {
// fake API call, will change the options of all the selects
setTimeout(() => {
this.setState({
options: t.update(this.state.options, {
fields: {
players: {
item: {
options: {$set: allPlayers}
}
}
}
})
});
}, 2000);
},
onSubmit(evt) {
evt.preventDefault();
var value = this.refs.form.getValue();
if (value) {
console.log(value);
}
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={Type}
options={this.state.options}
value={this.state.value}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
);
}
});
If you really want to use an enums and to update the type after the API call you could store the current type in the state:
function getEnumsFromOptions(options) {
return t.enums.of(options.map((option) => option.value));
}
const initialPlayers = [
{value: 'A', text: 'Player A'},
{value: 'B', text: 'Player B'},
{value: 'C', text: 'Player C'},
{value: 'D', text: 'Player D'}
];
const allPlayers = [
{value: 'A', text: 'Player A'},
{value: 'B', text: 'Player B'},
{value: 'C', text: 'Player C'},
{value: 'D', text: 'Player D'},
{value: 'E', text: 'Player E'},
{value: 'F', text: 'Player F'},
{value: 'G', text: 'Player G'},
{value: 'H', text: 'Player H'},
{value: 'I', text: 'Player I'},
{value: 'L', text: 'Player L'}
];
var App = React.createClass({
getInitialState() {
return {
type: t.struct({ // <= store the type in the state
name: t.String,
players: t.list(getEnumsFromOptions(initialPlayers))
}),
value: {
name: 'Foo',
players: ['A', 'C']
},
options: {
fields: {
players: {
item: {
factory: t.form.Select,
options: initialPlayers
}
}
}
}
};
},
componentDidMount() {
setTimeout(() => {
this.setState({
type: t.struct({ // <= update also the type
name: t.String,
players: t.list(getEnumsFromOptions(allPlayers))
}),
options: t.update(this.state.options, {
fields: {
players: {
item: {
options: {$set: allPlayers}
}
}
}
})
});
}, 2000);
},
onSubmit(evt) {
evt.preventDefault();
var value = this.refs.form.getValue();
if (value) {
console.log(value);
}
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={this.state.type}
options={this.state.options}
value={this.state.value}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
);
}
});
Brilliant, thanks for your help. I've been able to get what I needed up and running using the information above.
:+1:
I'm a bit stuck. I'm creating a list of enums as so:
I'm populating this list with my dropdown but my question is, how would I pre-populate this with players already in the team?
Sorry....I'm sure the answer is really simple!
Thanks, Helen