Tripbooks design system / lab 08 / forms and validation

Lab 08 / archetype three, and the topic you named at the start

Two thresholds, one form.

New Enquiry is the right place to settle validation, because it carries a problem most forms do not have. It can be saved twice, at two different standards. A draft needs a customer and a title. A real enquiry needs a customer, a title, a source, a destination, at least one adult, an agent, no blacklist, and a billing address on the account.

So the form cannot simply be valid or invalid. It has to say, at every moment, which of the two things you can do right now and exactly what is standing between you and the other one. Everything else in the validation contract falls out of getting that right.

CRM · Enquiries · New enquirySearch or jump to a reference⌘KSM

New enquiry

DRAFT · NOT SAVED Discard Save as draft

Customer

the whole chain hangs off it, so it locks once saved
Customer
Marchetti GroupCCN-1055
Contact person optional
Search this account's contacts
Billing currency
USD
Account managers
Sarah Mitchell · Huda Aziz
Lifetime
18 · 14 · 11
Billing address
Missing

Enquiry

Title
Kyoto incentive, autumn board offsite
Source
Choose a source
An enquiry cannot be saved without a source. Referral, Recommendation, Event, Social Media, Word of Mouth, Campaign, Website Chat, Web Search, Friends and Family or Phone Call.
Type
StandardMICE · group or tour
Preferred channel optional
Email
Priority
Auto · Highoverride
Auto reads party size, budget and departure date.

Trip

Departure
Multiple
Destinations
Kyoto, JPOsaka, JP+ add
Date flexibility optional
Exact dates
Departure date
14 Sep 2026
Return date
21 Sep 20267 nights
Adults
24+
Children · infants
0+

Travellers

18 of 24 linked
Marco MarchettiReadypassport valid to 2031
Giulia FerraraReadypassport valid to 2029
Andrea BassiPassport expiredexpired 04 Mar 2026
15 more linkedReadyall documents current
6 travellers short You can save and send this enquiry now. Nothing can be issued for a traveller without a profile, so this becomes blocking at the booking, not here.

Budget and preferences

Budget optional
USD 200,000.00
Basis
Whole trip
Accommodation optional
5 star
Meal plan optional
Not specified
Requirements optional
Anything the customer said in their own words

Management

Agent
Sarah Mitchellfrom the account
Entity
Northline Travel LLC · USD
Set by the entity you are working in and it cannot be changed here.
SLA
7 days idle
5 of 7 conditions met Two conditions short of a full enquiry: a source, and a billing address on Marchetti Group. Add both and this button becomes Save enquiry. Save as draft
The rule that makes this work

The disabled button never explains itself in a tooltip. The reason sits permanently beside it, in words, naming every outstanding condition rather than only the first, because a person who fixes one thing and finds the button still dead learns to distrust the form. The seven segment bar is the same idea in a glance: five solid, two open, and the two open ones are named in the sentence next to it.

02 / the field, in every state it has

Nine states, one field.

Every input on the platform is built from this. The border carries the state, the message carries the reason, and the label never moves.

Rest

Source
Choose a source

Placeholder is an instruction, never an example value that could be mistaken for content.

Focus

Title
Kyoto incentive, autumn board

The ours blue, the same hue that marks the active nav item. Focus is always something you are doing.

Filled

Departure date
14 Sep 2026

Dates, money and quantities are mono the moment they are entered, so a filled field looks like data.

Error

Return date
11 Sep 2026
The return is before the departure. Pick a date after 14 Sep 2026.

Names what is wrong and what to do, with the value it needs. Never "invalid date".

Warning, not blocking

Budget
USD 4,000.00
That is well under this account's average of USD 41,300.00 for 24 people. Save it anyway if it is right.

The platform's opinion, stated and then dropped. It never blocks and it never asks twice.

Disabled with a reason

Entity
Northline Travel LLC · USD
Set by the entity you are working in and it cannot be changed here.

A dead control always says who decided. A disabled field with no explanation is a support ticket.

Locked by state

Customer locked
Marchetti Group CCN-1055
The whole trip chain hangs off the customer, so it cannot change after the first save.

Different from disabled. Disabled means not yours to set. Locked means it was yours, once, and the moment has passed.

Derived

Nights
7

Computed from other fields, never typed, and shown so nobody goes looking for where to enter it.

Refused

Customer
Brooks Travel Co ACN-3006
This account is blacklisted. No enquiry, quotation or booking can be created against it until an admin lifts the stop.

The hardest state. It stops everything downstream, so it is stated at the field where the choice was made and again at the gate.

03 / the contract

Eight rules, and every form on the platform obeys them.

RuleWhat it means in practice
Validate on leavingA field is checked when a person leaves it, never while they are still typing into it. Once a field has shown an error it validates live, so the message clears the moment it is fixed rather than on the next blur.
One button, always liveA single save button that carries the highest threshold currently reachable. It reads Save as draft until every condition is met, then becomes Save enquiry. It is never disabled, so the form is never dead. The counter and the sentence beside it are what keep the change honest: a button that quietly changes meaning is a trick, a button that changes meaning while a bar next to it counts five of seven is a status report.
A dead control says why, permanentlyBeside the control, in words, not in a tooltip. It names every outstanding condition, not just the first, so fixing one thing never leaves a person guessing again.
Errors name the fixWhat is wrong, and the value or action that resolves it. "Pick a date after 14 Sep 2026", never "invalid date". No apologies, no exclamation marks.
Warnings are opinionsStated once, in ochre, and then they get out of the way. They never block, never repeat, and never require dismissal.
Disabled, locked and derived are three thingsNot yours to set. Yours once and the moment has passed. Computed and never typed. They look alike and they must read differently, so each carries its own sentence.
Nothing is a required-field asteriskRequired is the resting state of a label. Optional fields say so in the label. A form where most fields are required should not be covered in marks.
The gate is the summaryNo error summary at the top of the page. The bar at the foot counts the conditions, names the outstanding ones and carries the buttons, so the answer to "why can I not save" is always in the same place.
Why the single button needs the counter

Ruled 20 August: one button, not two. The risk with a button that changes its own meaning is that a person presses Save without noticing which save they got. The counter answers that before the press rather than after it: five of seven, and the two outstanding conditions named in the sentence beside it. The button label and the counter always agree, and if they ever could not, the counter is the one that is right.

One deliberate omission

There is no success state on a field. A green tick beside a correctly filled input is decoration: the person can see what they typed, and marking sixteen fields as correct to draw attention to two that are not is a worse way of saying the same thing than the counter at the foot of the form.

Decisions on this lab

Ruled, and recorded here.

  1. Ruled: one button. A single save that carries the highest threshold currently reachable, never disabled, with the condition counter beside it doing the explaining.
  2. Ruled: validate on leaving a field. Checked on blur, then live once a field has shown an error, so a fix clears the message immediately rather than on the next blur.
  3. Still open from Lab 07. A crossed gate is an exposure incident and currently lives only on the booking that caused it. It needs a home on the attention rail and in a finance worklist, and that lands with the Board and Worklist archetypes.