Visibility, Editability & Validity

Visibility

Let's continue by adding some advanced rules. We want to hide the description field when we are not editing (View mode) and isAngularDeveloper is false with the visibility property. Plus we will simplify the rule and we remove specific selectors for each operation (view, edit and create). All will be the same (zLeft only).

New rule
Complete rule file
New rule
field=description {
trait:longtext;
editing=false {
visible: ${object.isAngularDeveloper};
}
}
Complete rule file
class=User {
field=uniqueName {
label:"Id";
}
field=description {
trait:longtext;
editing=false {
visible: ${object.isAngularDeveloper};
}
}
field=age editable=false {
component:AgeRatingComponent;
bindings: {
value:$value;
};
}
zNone => *;
zLeft => uniqueName => name => created => age => isAngularDeveloper => description;
}

If you look closer we have simplified the rule to work only with one colum layout zLeft. You can always apply specific rule for a operation

which creates this rule:

If selectors [class=User, field=description, editing=false]
match the current context values,
then apply the properties
[visible:${object.isAngularDeveloper}]

Expressions are wrapped in ${...} and when used in property value, the "this" is the Context object - key paths reference assignments in context

The context also has special keys for the following:

  • object: The current object instance set on the context by the object context key

  • value: The field value from evaluating the current field on the current object in the context

  • properties: The current property map access as properties.get('<property name>')

Remember turn run npm run compile:oss after you change rule fules. Or you can start npm run watch:oss to start automatic compilation.

Validation

Next we validate the created field to ensure our date is not in the future. We will add also helper method to our domain class.

New rule
Complete rule file
New rule
field=created {
valid:${ object.isValidCreateDate() ? true : "The date cannot be in the future" };
}
Complete rule file
class=User {
field=uniqueName {
label:"Id";
}
field=description {
trait:longtext;
editing=false {
visible: ${object.isAngularDeveloper};
}
}
field=created {
valid:${ object.isValidCreateDate() ? true : "The date cannot be in the future" };
}
field=age editable=false {
component:AgeRatingComponent;
bindings: {
value:$value;
};
}
zNone => *;
zLeft => uniqueName => name => created => age => isAngularDeveloper => description;
}

and let's add our validation method to domain class user.ts:

Added method
src/app/model/user.ts
Added method
isValidCreateDate(): boolean {
const dateNow = new Date();
return (this.created && this.created < dateNow);
}
src/app/model/user.ts
export class User implements Entity {
constructor(public uniqueName?: string,
@Property.Properties('label:"Full Name"')
@Trait.Traits(['required'])
public name?: string,
public description?: string, public created?: Date,
public age?: number, public isAngularDeveloper: boolean = false) {
}
identity(): string {
return this.uniqueName;
}
getTypes(): any {
return {
uniqueName: String,
name: String,
description: String,
created: Date,
age: Number,
isAngularDeveloper: Boolean
};
}
isValidCreateDate(): boolean {
const dateNow = new Date();
return (this.created && this.created < dateNow);
}
/**
* Used by MetaUI to identify the name of the class once everything is minified
*/
className(): string {
return 'User';
}
toString(): string {
return this.name;
}
}

which creates this rule:

If selectors [class=user, field=created]
match the current context values,
then apply the properties
[valid:${object.isValidCreateDate()}]

When you select future date our custom error message appears.

Editibility

Let's add a rule to prevent the editing the name field if the value isAngularDeveloper is not true.

New rule
Complete rule file
New rule
field=name {
label:"Full name";
trait:required;
editable: ${object.isAngularDeveloper};
}
Complete rule file
class=User {
field=uniqueName {
label:"Id";
}
field=name {
label:"Full name";
trait:required;
editable: ${object.isAngularDeveloper};
}
field=description {
trait:longtext;
editing=false {
visible: ${object.isAngularDeveloper};
}
}
field=created {
valid:${ object.isValidCreateDate() ? true : "The date cannot be in the future" };
}
field=age editable=false {
component:AgeRatingComponent;
bindings: {
value:$value;
};
}
zNone => *;
zLeft => uniqueName => name#required => created => age => isAngularDeveloper => description;
}

which creates this rule:

If selectors [class=User, field=name]
match the current context values,
then apply the properties
[editable:${object.isAngularDeveloper}]

Switch to create operation and uncheck isAngularDeveloper and we see that it the name (Full name) is not editable. Now check isAngularDeveloperback switch to edit and field is editable again.

Current limited implementation of the read-only field does not broadcast any changes to parent form-field so it does not switch back to text field.