In this example, we use UIKernel.Form
to create a simple form for editing grid records.
To initialize a form, we use initForm
function and pass it a settings object with fields
and model
props as an argument.
A settings object can also have other props.
To update field values, you can use either updateField
or validateField
.
validateField
not only updates a field, but also validates it.
getValidationError
returns validation errors for a specific field.
getData
returns form data.
submit
is used to submit a form.
FormComponent.js
class Form extends React.Component {
constructor(props) {
super(props);
this.form = new UIKernel.Form();
this.onFormChange = this.onFormChange.bind(this);
}
componentDidMount() {
this.form.init({
fields: ['name', 'age'], // Fields we need
model: new UIKernel.Adapters.Grid.ToFormUpdate(model, 2), // We're going to change record with ID = 2
});
this.form.addChangeListener(this.onFormChange);
}
componentWillUnmount() {
this.form.removeChangeListener(this.onFormChange);
}
onFormChange(newFormState) {
if (!_.isEqual(this.props.state.fields, newFormState.fields)) {
this.form.submit()
.catch((err) => {
if (err && !(err instanceof UIKernel.ValidationErrors)) { // If error is not a validation one
alert('Error');
}
});
}
this.props.onChange(newFormState);
}
render() {
if (!this.props.state.isLoaded) {
return <span>Loading...</span>;
}
return (
<div className="form">
<div className="header panel-heading">
<h4 className="title">Edit record number 2</h4>
</div>
<div className="body">
<form className="form-horizontal change-second-field-form">
<div className={'form-group' + (this.props.state.fields.name.errors ? ' error' : '')}>
<label className="col-sm-2 control-label">Name</label>
<div className="col-sm-6">
<input
type="text"
className="form-control"
onChange={this.form.updateField.bind(this.form, 'name')}
value={this.props.state.fields.name.value}
/>
</div>
<div className="col-sm-3">
<div className="validation-error">{this.props.state.fields.name.errors}</div>
</div>
</div>
<div className={'form-group' + (this.props.state.fields.age.errors ? ' error' : '')}>
<label className="col-sm-2 control-label">Age</label>
<div className="col-sm-6">
{/* we use UIKernel.Editors.Number instead of <input type =" number "/> */}
{/* because UIKernel.Editors.Number returns a numeric value instead of a string. */}
<UIKernel.Editors.Number
className="form-control"
onChange={this.form.updateField.bind(this.form, 'age')}
value={this.props.state.fields.age.value}
/>
</div>
<div className="col-sm-3">
<div className="validation-error">{this.props.state.fields.age.errors}</div>
</div>
</div>
</form>
</div>
</div>
);
}
}
We use UIKernel.createValidator
to create a validator and call field
function to define validation rules for our form.
validation.js
const Validator = UIKernel.createValidator()
.field('name', UIKernel.Validators.regExp.notNull(/^\w{2,30}$/, 'Invalid first name.'))
.field('age', UIKernel.Validators.number.notNull(15, 90, 'Age must be between 15 and 90'));
We pass validation to the grid model.
model.js
const model = new UIKernel.Models.Grid.Collection({
data: [
[1, {'id': 1, 'name': 'Stacey', 'age': 22}],
[2, {'id': 2, 'name': 'Adam', 'age': 43}],
[3, {'id': 3, 'name': 'Deanna', 'age': 21}]
],
validator
});
columns.js
const columns = {
id: {
name : 'ID',
width: '40',
sortCycle: ['asc', 'desc'],
editor: function () {
return <input type="text" {...this.props}/>;
},
render: ['id', record => record.id]
},
name: {
name: 'Name', // columns title
sortCycle: ['asc', 'desc', 'default'], // sort cycle
editor: function () {
return <input type="text" {...this.props}/>;
},
render: ['name', record => record.name]
},
age: {
name: 'Age',
sortCycle: ['asc', 'desc', 'default'],
editor: function () {
return <input type="text" {...this.props}/>;
},
render: ['age', record => record.age]
}
};
MainComponent.js
class MainComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
form: {}
};
this.updateFormState =this.updateFormState.bind(this);
}
updateFormState(newFormState) {
this.setState({form: newFormState});
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-sm-12">
<div className="panel panel-info">
<div className="panel-heading">
<h3 className="panel-title">Records</h3>
</div>
<div className="panel-body padding0">
<UIKernel.Grid
ref={(grid) => this.grid = grid}
model={model}
cols={columns}
autoSubmit={true}
/>
<Form
state={this.state.form}
onChange={this.updateFormState}
/>
</div>
</div>
</div>
</div>
</div>
);
}
}
main.js
:
React.render(<MainComponent/>, document.getElementById("example"));