Skip to content
Steve Oney edited this page Sep 26, 2026 · 12 revisions

Many applications are state-oriented — appearing and behaving differently in different states. ConstraintJS includes a syntax for creating finite-state machines (FSMs) to make creating these applications easier. cjs.fsm(...state_names) creates a new FSM:

var my_fsm = cjs.fsm();

Adding States

.addState(state_name) adds a state to the FSM:

my_fsm.addState("idle");

.addState returns the original FSM (my_fsm in the above example). .startsAt(state_name) specifies the initial state of the FSM.

my_fsm.startsAt("idle");
Transition Events

Transition events — or events on which transitions occur — are created with the cjs.on(event_name, dom_element) function. event_name is a standard JavaScript DOM event and dom_element is the DOM element to which that event is occurring. For example:

cjs.on("mousedown", my_div)
Guards

.guard(condition_func) specifies the conditions on which the transition event may occur. For example: cjs.on("mousedown", my_div).guard(function(event) { return false; }) would never fire because the guard always returns false.

Instead of a transition event, a transition can be given a function that accepts a parameter to perform the transition, allowing custom transition events to be created. For example, cjs.on("mousedown", my_div) works like:

function(do_transition) {
    my_div.addEventListener("mousedown", do_transition);
}

Switching States & Adding Transitions

FSMs switch between states with transitions — pre-defined state changes that take place after some event. fsm.addTransition(to_state, event) adds a transition from the last state added to to_state (string) when the event transition event (described above) occurs:

var my_fsm = cjs.fsm()
                .addState("idle");

my_fsm.addTransition("myhover", cjs.on("mouseover", block_a));

.addTransition returns the original FSM (my_fsm in the above example). .addTransition(from_state, to_state, event) adds a transition between any two states, and .addTransition(from_state, to_state) (without an event) returns a function that runs the transition when it's called.

Chaining

ConstraintJS's FSM syntax is designed to support "chaining," a convention in JavaScript where an object property performs an operation on that object and returns the object back. For instance:

var my_fsm = cjs.fsm()
                .addState("idle")
                .addTransition("myhover", cjs.on("mouseover", block_a))
                .addState("myhover")
                .addTransition("idle", cjs.on("mouseout", block_a))
                .startsAt("idle");

FSM Constraints

Constraint variables may depend on FSMs. To create an FSM-dependent constraint, pass the FSM as the first parameter to cjs.inFSM(fsm, values) and an object with states and their values as the second parameter:

var color = cjs.inFSM(my_fsm, {
           idle:    "black",
           myhover: "yellow"
        });

Next: Templates

Previous: Array & Map Constraints

Clone this wiki locally