Closed simonpure closed 8 years ago
Hi @simonpure,
I think that the easiest way to add support for has-success
class would be cloning the default templates:
import React from 'react'
import t from 'tcomb-form'
// clone the default templates and add support for has-success class
// this example overrides the default textbox template
const originalRenderFormGroup = t.form.Form.templates.textbox.renderFormGroup
t.form.Form.templates.textbox = t.form.Form.templates.textbox.clone({
// overrides how the default template renders the form-group container
renderFormGroup: function renderFormGroup(children, locals) {
return (
<div className={!locals.hasError ? 'has-success' : null}>
{originalRenderFormGroup(children, locals)}
</div>
)
}
})
const Type = t.struct({
name: t.String,
surname: t.String
})
const App = React.createClass({
getInitialState() {
return {}
},
onSubmit(evt) {
evt.preventDefault()
const v = this.refs.form.getValue()
if (v) {
console.log(v)
}
},
onChange(value, path) {
// validate on each changes
this.refs.form.getComponent(path).validate()
},
render() {
return (
<form onSubmit={this.onSubmit}>
<t.form.Form
ref="form"
type={Type}
value={this.state.value}
onChange={this.onChange}
/>
<div className="form-group">
<button type="submit" className="btn btn-primary">Save</button>
</div>
</form>
)
}
})
The problem I encountered is how to tell the template to not render has-success
on first rendering.
Thanks for the quick response and the sample code @gcanti!
The way it's currently implemented is to trigger validation on keydown and blur individually for each field.
I don't think the same behavior can be achieved without introducing an additional state besides hasError. The way I'm thinking about it is to mark a field as dirty once it has focus and conditionally apply the has-success class (open to alternative suggestions).
Follow up question -
What's the best way to add an additional state to a component?
Thanks!
I don't think the same behavior can be achieved without introducing an additional state besides hasError
I agree. Yesterday I released v0.8.2 in which, among other things, I added a isPristine
boolean (default true
) that is turned to false
after the first change, so now you can write:
const originalRenderFormGroup = t.form.Form.templates.textbox.renderFormGroup
t.form.Form.templates.textbox = t.form.Form.templates.textbox.clone({
renderFormGroup: function renderFormGroup(children, locals) {
const hasSuccess = !locals.isPristine && !locals.hasError
return (
<div className={hasSuccess ? 'has-success' : null}>
{originalRenderFormGroup(children, locals)}
</div>
)
}
})
Awesome! Just tried it out and it works as expected.
Thanks for the quick addition - much appreciated.
I'm going to close this issue.
I'm just playing with this very promising library to see how easy it would be to port some Bootstrap/jQuery forms over.
One of the things I'd like to do is adding the has-success style on successful field validation.
What would be the recommended way of extending tcomb-form and/or the bootstrap templates to accomplish this?
Thanks for any pointers!