uniform-ng2 v0.1.2
Uni Form
Uniform is a HTML5 form layout builder
Configuration
Uniform is based on a JSON configuration. This configuration is an array of fields. To build configurations you can use the layout builder.
// example
constructor(builder: LayoutBuilder) {
// Definition in uniform/interfaces.ts
let field: UniField = new FieldLayout();
field.Property = 'Info.PersonalInfo.Name';
field.Section = 1;
field.SectionHeader = 'Title of the header';
field.LineBreak = true; // next field will be moved to the next line
field.ReadOnly = false;
field.Placement = 1; // Order of the field;
field.Placeholder = 'Insert your name in this input';
field.Label = 'Name';
field.FieldType = CONTROLS_ENUM.Multivalue
//...
this.builder.createNewLayout()
.addField(field) // add a FieldLayout directly
.addField(
// create a unifield with basic properties
'property.of.the.model', //should be unique
'Label to show in the form',
// all types in uniform/controls/index.ts
CONTROLS_ENUM.AUTOCOMPLETE
FieldSize.Normal, // Normal, Double, Quarter, Full.
false, //Hide or show the label of the form
0, // section of the field
'Section Header'
{}, // specific options for each field
);
this.layout = this.builder.getLayout();
}
Use uniform in a component
Import uniform and builder from the module
import {UniForm, LayoutBuilder} from 'uniform-ng2/main';
add builder to your component:
@Component({
selector: 'my-component'
templateUrl: './my-component.html'
})
export MyComponent {
public model: Person;
public layout: UniFieldLayout;
public config: UniFormConfig = {
autofocus: true; //focus first element by default
sections: { id: 1, isOpen: true} // section 1 is open on start
}
constructor(builder: LayoutBuilder) {
this.layout = builder.createNewLayout()
.addField(...)
.addField(...)
.getLayout();
}
}
template:
<uni-form
[layout]="layout"
[config]="config"
[model]="model"
(submitEvent)="onSubmit($event)"
(changeEvent)="onChange($event)"
(inputEvent)="oninput($event)"
(readyEvent)="onReady($event)"
(focusEvent)="onFocus($event)"
>
</uni-form>
access to the component:
// define a property to store the form
@ViewChild(UniForm)
public form: UniForm;
// at this stage (hook) html element is available
public ngAfterViewInit() {
//Access to focused component
this.form.currentComponent.then(field => this.doMyStuff(field));
//how to access fields
this.form.field('Property').then(field => this.doOtherStuff(field));
this.form.section(index)
.then(section => section.field('property'))
.then(field => this.moreStuff(field))
}
Use Observables as inputs
Uniform support Observables as inputs
Events (Outputs)
submitEvent
It is triggered when the form is submited
changeEvent
It is triggered when the user emits a complete change to the form. A complete change is triggered when blur event is emited by an input.
inputEvent
It is triggered when there is a change in inputs when a key is pressed. In complex inputs like autocomplete or multivalue it is emited at the same time that changeEvent.
readyEvent
It is triggered when all input components have run ngAfterViewInit. That means all components have html elements in place and you can start form manipulation
focusEvent
It is triggered when a form element is focused
Refresh uniform data
Uniform uses OnPush strategies. That means that mutation of objects doesn't trigger OnChange events and refreshing of items will not be showed in the screen.
To perform a refresh you have 2 ways:
You are using plain objects:
public ngOnInit() { getLayoutFromServer().then(layout => { layout.Fields[0].Options = createOptions(); this.layout = layout; // first time you update layout }); } public onChange(changes: SimpleChanges) { if (changes['Info.Personal.Name']) { let field = this.layout.find(x => x.Property === 'Info.Personal.Name'); checkName(field).then(result => { field.ReadOnly = result; this.layout = _.cloneDeep(this.layout) // creates a new reference that triggers ngOnChanges // inside uniform }) } }
You are using observables
public ngOnInit() { getLayoutFromServer().then(layout => { layout.Fields[0].Options = createOptions(); this.layout.next(layout); // first time you update layout }); } public onChange(changes: SimpleChanges) { if (changes['Info.Personal.Name']) { let field = this.layout.find(x => x.Property === 'Info.Personal.Name'); checkName(field).then(result => { field.ReadOnly = result; this.layout.next(this.layout); // cloneDeep will run inside uniform and // creates a new reference inside uniform }); } }
You have to do the same if you update the config or the model.
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago