Written for AI agents. Human? Read the human version →
jfaster.ai / docsView raw Markdown

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:


Entity Definition

EntityName @MenuName
    propertyName type modifiers

Entity Modifiers

SyntaxMeaning
@MenuNamePlace in menu (underscores → spaces: @My_Menu → "My Menu")
@No menu (hidden entity, accessed via relationships)
&LabelTextCustom 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

TypeWidgetExample
(default)Text inputname
integerNumber inputage integer
longNumber inputtotal long
doubleDecimal inputprice double
booleanCheckboxactive boolean
dateDate pickerbirthDate date
datetimeDateTime pickercreatedAt datetime
timeTime pickerstartTime time
textTextareanotes text
longtextLarge textareacontent longtext
emailEmail inputemail email
passwordPassword inputpassword password
fileFile uploadattachment file
imageImage uploadphoto image
enumDropdownstatus enum enumset="Status"

Property Modifiers (Shorthand)

ShorthandExpands ToMeaning
ddisplay="primary"Show in listings, used as entity label
dsdisplay="secondary"Show in listings only
rrequired="required"Mandatory field
fixedfixed="fixed"Display as text (not editable)
hiddenhidden="hidden"Hidden from form
disableddisabled="disabled"Disabled input
readonlyreadonly="readonly"Read-only input
transienttransient="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 -->
ModifierMeaning
setCollection (Set)
listCollection (List, ordered)
eiEmbedded inline (show in same form)
xExtendable (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

AttributeSQL 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

AttributeDescription
nameIdentifier
labelDisplay text
subsetFilter subset
displayactionsActions for this tab
displaypropertiesColumns to show

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

ValueMeaning
display="primary"Always visible
display="secondary"In "Advanced Filters"

Actions

Action Types

TypeDescriptionRequired Attributes
javascriptCall JS functionfunction
relatedentityOpen entity formentity, optionally defaultset
openentityOpen existing entityentity
reportGenerate reportreport

Action Locations

LocationWhere it appears
formForm button bar
listingListing action bar (for selected items)
localPer-row in listing

JavaScript Action

<action name="print" label="Print" type="javascript"
        function="printRecord" location="form" icon="f02f" />
<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

VariableValue
nowCurrent 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


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="." />
AttributeDescription
entityRelated entity
subsetFilter for records
subsetparams="."Pass current entity as param
defaultsetFor 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

Detailed Element Guides

Tutorials

Legacy 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 ``