JFaster Cheatsheet
Complete reference for building JFaster applications. Copy this file to your project for Claude Code context.
What is JFaster?
JFaster is a rapid application development framework that generates complete web applications from declarative .txt source files:
- Database tables (Hibernate/JPA)
- CRUD forms and listings
- REST API endpoints
- Java services and DAOs
- Navigation menus
Entity Definition
EntityName @MenuName
propertyName type modifiers
Entity Modifiers
| Syntax | Meaning |
|---|---|
@MenuName | Place in menu (underscores → spaces: @My_Menu → "My Menu") |
@ | No menu (hidden entity, accessed via relationships) |
&LabelText | Custom label (underscores → spaces) |
transient="transient" | Not persisted to database |
order="field asc" | Default sort order |
noadd="noadd" | Hide "Add" button |
noremove="noremove" | Hide "Remove" button |
Examples
Person @CRM
name d r
Company @CRM &Companies order="name asc"
name d r
OrderLine @
order Order
quantity integer r
SendEmail @ transient="transient"
recipient r
subject r
body text
Properties
Basic Syntax
propertyName [type] [entity] [modifiers] [attributes]
Property Types
| Type | Widget | Example |
|---|---|---|
| (default) | Text input | name |
integer | Number input | age integer |
long | Number input | total long |
double | Decimal input | price double |
boolean | Checkbox | active boolean |
date | Date picker | birthDate date |
datetime | DateTime picker | createdAt datetime |
time | Time picker | startTime time |
text | Textarea | notes text |
longtext | Large textarea | content longtext |
email | Email input | email email |
password | Password input | password password |
file | File upload | attachment file |
image | Image upload | photo image |
enum | Dropdown | status enum enumset="Status" |
Property Modifiers (Shorthand)
| Shorthand | Expands To | Meaning |
|---|---|---|
d | display="primary" | Show in listings, used as entity label |
ds | display="secondary" | Show in listings only |
r | required="required" | Mandatory field |
fixed | fixed="fixed" | Display as text (not editable) |
hidden | hidden="hidden" | Hidden from form |
disabled | disabled="disabled" | Disabled input |
readonly | readonly="readonly" | Read-only input |
transient | transient="transient" | Not saved to database |
Relationships
company Company <!-- Many-to-one (dropdown) -->
company Company subset="active" <!-- Filtered dropdown -->
addresses Address set <!-- One-to-many (separate listing) -->
lines OrderLine set ei x childproperty="order" <!-- Embedded editable table -->
| Modifier | Meaning |
|---|---|
set | Collection (Set) |
list | Collection (List, ordered) |
ei | Embedded inline (show in same form) |
x | Extendable (can add/remove rows) |
childproperty="field" | Back-reference field in child |
Common Attributes
propertyName type default="value" <!-- Default value -->
propertyName type widget="widgetName" <!-- Custom widget -->
propertyName type placeholder="Enter..." <!-- Placeholder text -->
propertyName type style="width:200px" <!-- Inline CSS -->
propertyName type class="custom-class" <!-- CSS class -->
propertyName type "Custom Label" <!-- Override label: quoted string, NOT label="..." (duplicates the attribute and breaks the generate, see how-to/txt-label-de-property.md) -->
Property Examples
Person @CRM
firstName d r
lastName d r
email email
phone
birthDate date widget="jdatepicker"
salary double
active boolean default="true"
notes text
photo image
company Company subset="active"
country Country
addresses Address set ei x childproperty="person"
status enum enumset="PersonStatus"
Subsets (Predefined Filters)
Filter records by conditions. Used in listings (tabs) and relationship dropdowns.
Simple Subset
<subset name="active">
<condition field="active" value="true" />
</subset>
Parameterized Subset
<subset name="forCompany">
<param name="company" entity="Company" />
<condition field="company" value="company" />
</subset>
Condition Operators
| Attribute | SQL Equivalent |
|---|---|
value="x" | = x |
ne="x" | <> x |
gt="x" | > x |
ge="x" | >= x |
lt="x" | < x |
le="x" | <= x |
like="x" | LIKE x |
isnull="isnull" | IS NULL |
isnotnull="isnotnull" | IS NOT NULL |
Complex Conditions
<!-- OR logic -->
<subset name="adminsOrManagers">
<or>
<condition field="role" value="'admin'" />
<condition field="role" value="'manager'" />
</or>
</subset>
<!-- AND logic (default) -->
<subset name="activeAdmins">
<and>
<condition field="active" value="true" />
<condition field="role" value="'admin'" />
</and>
</subset>
<!-- HQL restriction for complex queries -->
<subset name="withOrders">
<restriction expr="EXISTS (FROM Order o WHERE o.customer = me)"/>
</subset>
<!-- Restriction with parameters -->
<subset name="emailContains">
<param name="domain" type="string" />
<restriction expr="email LIKE CONCAT('%', ?, '%')">
<param value="domain" />
</restriction>
</subset>
Listings and Tabs
Basic Listing with Tabs
<listing name="main">
<tab name="all" label="All" />
<tab name="active" label="Active" subset="active" />
<tab name="inactive" label="Inactive" subset="inactive" />
</listing>
Listing with Actions
<listing name="main" displayactions="export,delete" displayactiongroups="batch">
<tab name="all" label="All" />
</listing>
Tab Attributes
| Attribute | Description |
|---|---|
name | Identifier |
label | Display text |
subset | Filter subset |
displayactions | Actions for this tab |
displayproperties | Columns to show |
Filters (User Search)
Simple Property Filter
<filter name="company" property="company" entity="Company" label="Company" display="primary" />
Text Search Filter
<filter name="search" label="Search" display="primary">
<or>
<condition field="firstName" like="concat('%', concat(search, '%'))" />
<condition field="lastName" like="concat('%', concat(search, '%'))" />
</or>
</filter>
Date Range Filter
<filter name="dateFrom" type="date" label="From" display="primary" widget="jdatepicker">
<condition field="createdAt" ge="dateFrom" />
</filter>
<filter name="dateTo" type="date" label="To" display="primary" widget="jdatepicker">
<condition field="createdAt" le="dateTo" />
</filter>
Enum Filter
<filter name="status" property="status" label="Status" display="primary" enumset="Status" />
Filter Display
| Value | Meaning |
|---|---|
display="primary" | Always visible |
display="secondary" | In "Advanced Filters" |
Actions
Action Types
| Type | Description | Required Attributes |
|---|---|---|
javascript | Call JS function | function |
relatedentity | Open entity form | entity, optionally defaultset |
openentity | Open existing entity | entity |
report | Generate report | report |
Action Locations
| Location | Where it appears |
|---|---|
form | Form button bar |
listing | Listing action bar (for selected items) |
local | Per-row in listing |
JavaScript Action
<action name="print" label="Print" type="javascript"
function="printRecord" location="form" icon="f02f" />
Related Entity Action
<action name="sendEmail" label="Send Email" type="relatedentity"
entity="SendEmail" defaultset="forPerson" location="form" />
Batch Action (Multiple Selection)
<action name="deactivate" label="Deactivate Selected" type="relatedentity"
entity="DeactivatePeople" defaultset="forPeople"
location="listing" multiple="true" />
Note: Listing actions must be declared in the listing:
<listing name="main" displayactions="deactivate">
Action Groups (Dropdown Menus)
<actiongroup name="more" label="More Actions" location="form">
<action name="duplicate" label="Duplicate" type="relatedentity"
entity="DuplicatePerson" defaultset="forPerson" />
<action name="archive" label="Archive" type="javascript"
function="archivePerson" />
</actiongroup>
Note: For listing, declare in listing element:
<listing name="main" displayactiongroups="batch">
Defaultsets (Pre-fill Forms)
Pre-populate fields when creating records from a related context.
Simple Parameter
<defaultset name="forCompany">
<param name="company" entity="Company" />
<default name="company" value="company" />
</defaultset>
Derived Values
<defaultset name="forCompanyWithCountry">
<param name="company" entity="Company" />
<default name="company" value="company" />
<default name="country" value="company.country" />
</defaultset>
Literal Values
<defaultset name="newExpense">
<default name="status" value="'pending'" />
<default name="date" value="now" />
<default name="approved" value="false" />
</defaultset>
Collection Parameter (Batch Operations)
<!-- For transient entity receiving multiple records -->
<defaultset name="forPeople">
<param name="people" entity="Person" collection="set" />
<default name="people" value="people" />
</defaultset>
Built-in Variables
| Variable | Value |
|---|---|
now | Current date/time |
Transient Entities
Entities that exist only for operations (not stored in database).
SendEmail @ transient="transient"
recipient Person fixed
subject r
body text r
<defaultset name="forPerson">
<param name="person" entity="Person" />
<default name="recipient" value="person" />
</defaultset>
Common Uses
- Confirmation dialogs with reason/notes
- Batch operations on multiple records
- Data import/export forms
- Multi-step wizards
Enumsets
Define at app level in Main.xml (NOT inside entity):
<!-- In Main.xml <config> section -->
<enumset name="ExpenseStatus">
<enum value="draft">Draft</enum>
<enum value="submitted">Submitted</enum>
<enum value="approved">Approved</enum>
<enum value="rejected">Rejected</enum>
<enum value="paid">Paid</enum>
</enumset>
Use in property:
status enum enumset="ExpenseStatus" default="'draft'"
Form Layout
Tabs
Person @CRM
#tab Personal
firstName d r
lastName d r
birthDate date
#tab Contact
email email
phone
address text
#tab Employment
company Company
position
startDate date
Boxes (Columns)
#box cols
#box
firstName d r
lastName d r
#box
email
phone
Section Titles
!Personal Information
firstName d r
lastName d r
!Contact Details
email email
phone
Embedded Listings
Show related records inside a form:
<embeddedlisting name="expenses" entity="Expense"
subset="forEmployee" subsetparams="."
defaultset="forEmployee" defaultsetparams="." />
| Attribute | Description |
|---|---|
entity | Related entity |
subset | Filter for records |
subsetparams="." | Pass current entity as param |
defaultset | For new records |
defaultsetparams="." | Pass current entity as param |
Comments
Use XML comments (NOT //):
<!-- This is a comment -->
Person @CRM
<!-- Personal info -->
firstName d r
lastName d r
Common Gotchas
1. EL Expression Syntax
Wrong:
concat('%', search, '%')
Right:
concat('%', concat(search, '%'))
Or use HQL directly:
<restriction expr="name LIKE CONCAT('%', ?, '%')">
<param value="search" />
</restriction>
2. Built-in Variables
Wrong: value="now()" (function call) Right: value="now" (variable)
3. Enumset Location
Wrong: Inside entity Right: In Main.xml at app/config level
4. Listing Actions Must Be Declared
<listing name="main" displayactions="export,delete">
5. Collection Defaultsets
Collection params (collection="set") are for transient entities receiving multiple records, not regular entities.
6. Comments Syntax
Wrong: // comment (creates invalid entity) Right: <!-- comment -->
Complete Example: Expense Tracker
<!-- Main.xml enumsets -->
<enumset name="ExpenseStatus">
<enum value="draft">Draft</enum>
<enum value="submitted">Submitted</enum>
<enum value="approved">Approved</enum>
<enum value="rejected">Rejected</enum>
</enumset>
<enumset name="ExpenseCategory">
<enum value="travel">Travel</enum>
<enum value="meals">Meals</enum>
<enum value="lodging">Lodging</enum>
<enum value="transport">Transport</enum>
<enum value="other">Other</enum>
</enumset>
<!-- Entities -->
Employee @Staff
firstName d r
lastName d r
email email r
department Department
manager Employee
active boolean default="true"
<subset name="active">
<condition field="active" value="true" />
</subset>
Department @Staff
name d r
code d r
Expense @Expenses
employee Employee d r fixed
date date d r
category enum enumset="ExpenseCategory" r
description d r
amount double r
receipt image
status enum enumset="ExpenseStatus" default="'draft'"
approvedBy Employee
approvedAt datetime
notes text
<listing name="main" displayactions="submit,approve,reject">
<tab name="all" label="All" />
<tab name="pending" label="Pending" subset="pending" />
<tab name="approved" label="Approved" subset="approved" />
</listing>
<filter name="employee" property="employee" entity="Employee"
label="Employee" display="primary" />
<filter name="category" property="category" enumset="ExpenseCategory"
label="Category" display="primary" />
<filter name="dateFrom" type="date" label="From" display="primary">
<condition field="date" ge="dateFrom" />
</filter>
<subset name="pending">
<condition field="status" value="'submitted'" />
</subset>
<subset name="approved">
<condition field="status" value="'approved'" />
</subset>
<subset name="forEmployee">
<param name="employee" entity="Employee" />
<condition field="employee" value="employee" />
</subset>
<defaultset name="forEmployee">
<param name="employee" entity="Employee" />
<default name="employee" value="employee" />
<default name="date" value="now" />
<default name="status" value="'draft'" />
</defaultset>
<action name="submit" label="Submit" type="relatedentity"
entity="SubmitExpense" defaultset="forExpense" location="form" />
<action name="approve" label="Approve" type="relatedentity"
entity="ApproveExpense" defaultset="forExpense" location="form,listing" />
<action name="reject" label="Reject" type="relatedentity"
entity="RejectExpense" defaultset="forExpense" location="form,listing" />
<!-- Transient entities for actions -->
SubmitExpense @ transient="transient"
expense Expense fixed
<defaultset name="forExpense">
<param name="expense" entity="Expense" />
<default name="expense" value="expense" />
</defaultset>
ApproveExpense @ transient="transient"
expense Expense fixed
notes text
<defaultset name="forExpense">
<param name="expense" entity="Expense" />
<default name="expense" value="expense" />
</defaultset>
RejectExpense @ transient="transient"
expense Expense fixed
reason text r
<defaultset name="forExpense">
<param name="expense" entity="Expense" />
<default name="expense" value="expense" />
</defaultset>
File Structure
project/
├── Main.xml # App config, enumsets, widgets
├── Main.txt # Entity definitions (preprocessed to XML)
├── src/
│ └── main/
│ └── webapp/
│ └── js/
│ └── Main.js # Custom JavaScript functions
└── CLAUDE.md # Project context for Claude Code
Quick Reference Card
Entity: Name @Menu &Label modifiers
Property: name [type] [Entity] [d|ds] [r] [modifiers] ["Label"] [attrs]
Types: integer long double boolean date datetime time
text longtext email password file image enum
Modifiers: d=display r=required fixed hidden disabled
set list ei=embedded x=extendable
Subset: <subset name="x"><condition field="f" value="v"/></subset>
Filter: <filter name="x" property="p" display="primary"/>
Action: <action name="x" type="relatedentity" entity="E" location="form"/>
Defaultset: <defaultset name="x"><param/><default/></defaultset>
Built-ins: now (current datetime)
Comments: <!-- comment -->
Further Reading
Complete Reference
- Index.md - Full element reference with all attributes
Detailed Element Guides
- subset.md - Subsets, conditions, restrictions
- listing.md - Listing configuration
- tab.md - Tab configuration
- filter.md - Filter types and conditions
- action.md - Action types and locations
- actiongroup.md - Grouping actions in dropdowns
- defaultset.md - Pre-filling forms
- condition.md - Condition operators
- restriction.md - HQL restrictions
- param.md - Parameter definitions
- or.md / and.md - Logical operators
Tutorials
- Getting Started - Beginner tutorial with UI examples
Legacy Documentation
- JFaster.html - Original comprehensive documentation
Tip: When working on a new project, copy this cheatsheet and adjust the paths: ``
bash cp /path/to/jfaster-docs/tutorials/cheatsheet.md ./JFASTER.md`Or start Claude Code with the docs directory:`bash claude --add-dir /path/to/jfaster-docs``