FormBuilder

API / @publicodes/forms / FormBuilder

Defined in: formBuilder.ts:96

Creates and manages multi-page forms based on Publicodes rules.

FormBuilder provides a complete solution for building dynamic, multi-step forms that adapt to user input. It handles:

  • Form state management
  • Page navigation and pagination
  • Field validation and dependencies
  • Progressive disclosure of relevant fields

Example

// Create a form builder
const engine = new Engine(rules)
const formBuilder = new FormBuilder({ engine })

// Initialize form state
let state = FormBuilder.newState()
state = formBuilder.start(state, 'target . rule')

// Handle user input
state = formBuilder.handleInputChange(state, 'user . age', 25)

// Navigate between pages
state = formBuilder.goToNextPage(state)

Type Parameters

Type ParameterDescription
RuleName extends stringThe type of rule names used in the form

Constructors

new FormBuilder()

new FormBuilder<RuleName>(__namedParameters): FormBuilder<RuleName>

Defined in: formBuilder.ts:100

Parameters

ParameterType
__namedParameters{ engine: Engine<RuleName>; pageBuilder: PageBuilder<RuleName>; }
__namedParameters.engineEngine<RuleName>
__namedParameters.pageBuilder?PageBuilder<RuleName>

Returns

FormBuilder<RuleName>

Methods

currentPage()

currentPage(formState): EvaluatedFormElement & FormPageElementProp[]

Defined in: formBuilder.ts:215

Retrieves the current form page with UI properties for rendering.

This method processes the current page of form fields and enhances them with UI-specific properties like visibility, focus state, and validation status. It’s typically used when rendering the form in your UI.

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form

Returns

EvaluatedFormElement & FormPageElementProp[]

An array of form elements with UI properties and validation state

Example

// In a React component
const formElements = formBuilder.currentPage(formState)
return (
  <form>
    {formElements.map(element => (
      <FormField
        key={element.id}
        {...element}
        onChange={value => handleChange(element.id, value)}
      />
    ))}
  </form>
)

evaluate()

evaluate(formState, ruleName): EvaluatedNode<
  | "arrondi"
  | "barème"
  | "condition"
  | "constant"
  | "contexte"
  | "durée"
  | "est non applicable"
  | "est non défini"
  | "grille"
  | "inversion"
  | "operation"
  | "reference"
  | "replacementRule"
  | "résoudre référence circulaire"
  | "rule"
  | "simplifier unité"
  | "taux progressif"
  | "texte"
  | "une possibilité"
  | "unité"
  | "variable manquante"
  | "variations"
| "logarithme", EvaluatedValueTypes>

Defined in: formBuilder.ts:252

Wrapper around engine.evaluate that ensures proper reactivity in signal-based systems.

This method ensures the engine’s situation is up-to-date before evaluating a rule, making it suitable for use in reactive frameworks that track dependencies (like Svelte, Vue, Solid.js, or other signal-based systems).

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form
ruleNameRuleNameThe name of the rule to evaluate

Returns

EvaluatedNode< | "arrondi" | "barème" | "condition" | "constant" | "contexte" | "durée" | "est non applicable" | "est non défini" | "grille" | "inversion" | "operation" | "reference" | "replacementRule" | "résoudre référence circulaire" | "rule" | "simplifier unité" | "taux progressif" | "texte" | "une possibilité" | "unité" | "variable manquante" | "variations" | "logarithme", EvaluatedValueTypes>

The evaluation result from the engine

Example

// In a reactive framework
const result = formBuilder.evaluate(formState, 'total . amount')
// The framework will track this dependency and re-run when formState changes

goToNextPage()

goToNextPage(formState): FormState<RuleName>

Defined in: formBuilder.ts:323

Advances the form to the next page in the sequence.

This method handles navigation to the next page, including:

  • Moving to the next page if one exists in the current pages array
  • Loading a new page from the nextPages queue if needed
  • Returning the original state if there are no more pages

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form

Returns

FormState<RuleName>

A new form state positioned at the next page, or the original state if at the last page

Example

// Handle "Next" button click
function handleNext() {
  const nextState = formBuilder.goToNextPage(formState)
  setFormState(nextState)

  // Check if we actually moved to a new page
  if (nextState.currentPageIndex !== formState.currentPageIndex) {
    // Scroll to top or perform other navigation-related actions
    window.scrollTo(0, 0)
  }
}

goToPreviousPage()

goToPreviousPage(formState): FormState<RuleName>

Defined in: formBuilder.ts:365

Navigates to the previous page in the form.

This method decrements the current page index if possible, allowing users to go back to review or change their previous answers.

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form

Returns

FormState<RuleName>

A new form state positioned at the previous page, or the original state if already at the first page

Example

// Handle "Previous" button click
function handlePrevious() {
  const prevState = formBuilder.goToPreviousPage(formState)
  setFormState(prevState)

  // Optionally scroll to top when navigating
  window.scrollTo(0, 0)
}

handleInputChange()

handleInputChange(
   formState, 
   id, 
value): FormState<RuleName>

Defined in: formBuilder.ts:400

Updates the form state when a user changes an input value.

This method:

  1. Records which field was last answered
  2. Updates the engine’s situation with the new value
  3. Recalculates which fields are needed next based on the new value
  4. Updates the form state with the new situation and next pages

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form
idRuleNameThe rule name identifier of the field being updated
valueundefined | string | number | booleanThe new value for the field (string, number, boolean, or undefined to clear)

Returns

FormState<RuleName>

A new form state with updated values and potentially new pages

Example

// In a React component
function handleChange(id, value) {
  const newState = formBuilder.handleInputChange(formState, id, value)
  setFormState(newState)

  // The form may have new pages based on this input
  console.log(`Next pages count: ${newState.nextPages.length}`)
}

pagination()

pagination(formState): object

Defined in: formBuilder.ts:286

Retrieves pagination information for building navigation controls.

This method calculates the current page position and total page count, along with boolean flags that can be used to enable/disable navigation buttons.

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current state of the form

Returns

object

An object containing pagination details:

  • current - Current page number (1-based)
  • pageCount - Total number of pages (known + upcoming)
  • hasNextPage - Whether there is a next page available
  • hasPreviousPage - Whether there is a previous page available
NameTypeDefined in
currentnumberformBuilder.ts:290
hasNextPagebooleanformBuilder.ts:292
hasPreviousPagebooleanformBuilder.ts:293
pageCountnumberformBuilder.ts:291

Example

// In a React component
const { current, pageCount, hasNextPage, hasPreviousPage } = formBuilder.pagination(formState)

return (
  <div className="pagination">
    <span>Page {current} of {pageCount}</span>
    <button disabled={!hasPreviousPage} onClick={handlePrevious}>Previous</button>
    <button disabled={!hasNextPage} onClick={handleNext}>Next</button>
  </div>
)

start()

start(formState, ...targets): FormState<RuleName>

Defined in: formBuilder.ts:170

Initializes a form with specified target rules and moves to the first page.

This method sets up a form by:

  1. Registering the target rules that the form aims to compute
  2. Determining which input fields are needed based on these targets
  3. Organizing these fields into pages using the configured page builder
  4. Moving to the first page of questions

Parameters

ParameterTypeDescription
formStateFormState<RuleName>The current form state to initialize
targetsRuleName[]One or more target rule names that the form will compute

Returns

FormState<RuleName>

A new form state initialized with the first page of questions

Throws

Error if no targets are provided

Example

// Initialize a form with a single target
let state = FormBuilder.newState()
state = formBuilder.start(state, 'eligibility . result')

// Or with multiple targets
state = formBuilder.start(state, 'tax . amount', 'benefits . eligible')

newState()

static newState<RuleName>(situation): FormState<RuleName>

Defined in: formBuilder.ts:133

Creates a new, empty form state object.

This static method initializes a blank form state that can be used as the starting point for a new form. The state includes an optional initial situation (user answers).

Type Parameters

Type ParameterDefault typeDescription
RuleName extends stringstringThe type of rule names used in the form

Parameters

ParameterTypeDescription
situationPartial<Record<RuleName, | PublicodesExpression | ASTNode< | "arrondi" | "barème" | "condition" | "constant" | "contexte" | "durée" | "est non applicable" | "est non défini" | "grille" | "inversion" | "operation" | "reference" | "replacementRule" | "résoudre référence circulaire" | "rule" | "simplifier unité" | "taux progressif" | "texte" | "une possibilité" | "unité" | "variable manquante" | "variations" | "logarithme">>>Optional initial situation with pre-filled values

Returns

FormState<RuleName>

A new form state object ready to be used with start()

Example

// Create an empty form state
const state = FormBuilder.newState()

// Create a form state with initial values
const stateWithValues = FormBuilder.newState({
  'user . age': 30,
  'user . income': 50000
})