In Previous chapter we created User.oss
file which is our object stylesheet to drive our user interface. The same way you would use your .css
cascading style sheet to adjust your UI.
Let's look little bit close on this file:
Defines basic object styles for Domain class Userclass=User {field=uniqueName {label:"Id";}field=name {label:"Name";}field=description {trait:longtext;}zNone => *;zLeft => uniqueName => name => description => created;}/*Sample definition for operations edit and create*/class=User {operation=(edit, create) {zNone => *;zLeft => name => description;}operation=(create) {zNone => *;zLeft => name => description => created;}}
The rule format is inspired by CSS and just like CSS it can be additive where more common rules can be overriden by more specific fules but extended to support nesting (just like .sass
) and chaining and tweaked to deal with identified containing the .
(e.g. field path user.address.city
).
Both have selectors
and properties.
CSS examplediv#toc a {text-decoration:underline;}
If an a
tag appears in a div
named toc set property text-decoration:underline
MetaUI OSS exampleclass=User field=firstName {hint:"Your email";}
If the field name email
appears in the class named User
set property hint:"You email address
".
These are equivalent:
class=User {field=firstName {editing=true {visible:true;}}
class=User field=firstName editing { visible:true; }
class=User field=firstName {editing { visible:true; }}
As you go over different rules files (.oss
), you could see there is no'='
inside the selector (field=firstName), but there is just field {.. } or editing { ... }.
It same as as writing field=*: This applies to all the field (common rule)
For editing (boolean value) , its the same as editing=true
Properties can work with types such as Boolean, Integer, String, List, Map and Expression.
field=password {// booleaneditable:true;//String literal quotedtoolTip:"This is required";// This is how specify list of valuestrait:required, secret;choices:['Extra cheese', 'Mushroom'];// String literal (unquoted)component:AWPasswordField;// Mapbindings: {size:20;};// Expressionvalid: ${ value.length > 5 }}
Traits is MetaUI feature which is simlar to mixins
in the SASS. It can help us reuse some of the functionality.
For example trait longtext
is just another rule that expands defined properties into current place.
field=description {trait:longtext;}
Such trait can look like this
@trait=longtext {after:zBottom;editable {component:TextAreaComponent;}}
It moves description to the bottom of our Form Layout and if we are editing (Create or Edit operation), then we set TextAreaComponent
as current rendering component.
Not always we render fields from our domain class sometimes in the enterprise we want to have some ad-hoc fields some calculated fields that are created in runtime such as:
class=User {@field=fullName {value:${object.firstName + " " + object.lastName};}}
Here the @
, creates new field and sets the value that can be combination of multiple fields like in above example. The @
means create (declare). This is the reason why we used above the @
when defining new trait.
These are equivalent
field=firstName {trait:required;}
field=firstName#required {}
To apply layout rules to position field in the page. These are equivalent
field=firstName {after:zLeft;trait:required;}field=lastName {after:firstName;trait:required;}field=password {after:lastName;trait:required,secret;}
zLeft => firstName#required => lastName#required => password#required,secret
Expressions are wrapped in ${…}
and use the JS syntax and are executed using eval
function.
field=budget{valid: ${value >= 0 ? true : "Budget must be non-negative" }}
By default when working with rules you have access to two implicit properties the object
and value.