Rent a car: Parts of the form
In this chapter you’ll declare every input the form needs, in a sensible order, with no logic yet. The form ends up rendering all the pieces but doesn’t react to anything — that’s what the next chapters add.
Layout convention
Section titled “Layout convention”GolemUI ships two layouts that cover most needs:
gui.layouts.gridfor rows. Subgrid alignment keeps labels, inputs, and validation messages aligned across all children in a row.gui.layouts.flexfor columns. Lighter, more flexible for vertical stacks.
The top-level form definition is implicitly stacked vertically (the engine adds an auto-stack — see Sensible defaults), so we only need a grid when we want fields side-by-side.
The form
Section titled “The form”The two office dropdowns sit side-by-side in a row, the rest stacks vertically.
import { gui } from '@golemui/gui-shared';
export default [ gui.inputs.dropdown('car', { labelField: 'label', valueField: 'id', items: [ { id: 'compact', label: 'Compact', }, { id: 'suv', label: 'SUV', }, { id: 'convertible', label: 'Convertible', }, { id: 'luxury', label: 'Luxury', }, ], label: 'Select car', }), gui.layouts.grid([ gui.inputs.dropdown('collectOffice', { labelField: 'label', valueField: 'id', items: [ { id: 'lhr', label: 'London Heathrow', }, { id: 'cdg', label: 'Paris CDG', }, { id: 'fra', label: 'Frankfurt Main', }, ], label: 'Collect from office', }), gui.inputs.dropdown('returnOffice', { labelField: 'label', valueField: 'id', items: [ { id: 'lhr', label: 'London Heathrow', }, { id: 'cdg', label: 'Paris CDG', }, { id: 'fra', label: 'Frankfurt Main', }, ], label: 'Return to office', }), ], { direction: 'row', autoFit: true, }), gui.inputs.booleanInput('differentReturn', { label: 'Choose a different return location', }), gui.inputs.rangeCalendar('rentalDates', { label: 'Rental dates', }), gui.inputs.radiogroup('rentalType', { options: [ { label: 'Daily', value: 'daily', }, { label: 'Weekly', value: 'weekly', }, { label: 'Monthly', value: 'monthly', }, ], label: 'Rental type', }), gui.inputs.booleanInput('driverOver25', { label: 'Driver aged over 25', }), gui.inputs.booleanInput('hasDiscountCode', { label: 'I have a discount code', }), gui.inputs.textInput('discountCode', { label: 'Discount code', }), gui.actions.button({ label: 'Reserve', uid: 'submit', onClick: 'submit', }),];{ "form": [ { "kind": "input", "type": "dropdown", "path": "car", "label": "Select car", "props": { "labelField": "label", "valueField": "id", "items": [ { "id": "compact", "label": "Compact" }, { "id": "suv", "label": "SUV" }, { "id": "convertible", "label": "Convertible" }, { "id": "luxury", "label": "Luxury" } ] } }, { "kind": "layout", "type": "grid", "props": { "direction": "row", "autoFit": true }, "children": [ { "kind": "input", "type": "dropdown", "path": "collectOffice", "label": "Collect from office", "props": { "labelField": "label", "valueField": "id", "items": [ { "id": "lhr", "label": "London Heathrow" }, { "id": "cdg", "label": "Paris CDG" }, { "id": "fra", "label": "Frankfurt Main" } ] } }, { "kind": "input", "type": "dropdown", "path": "returnOffice", "label": "Return to office", "props": { "labelField": "label", "valueField": "id", "items": [ { "id": "lhr", "label": "London Heathrow" }, { "id": "cdg", "label": "Paris CDG" }, { "id": "fra", "label": "Frankfurt Main" } ] } } ] }, { "kind": "input", "type": "toggle", "path": "differentReturn", "label": "Choose a different return location" }, { "kind": "input", "type": "rangeCalendar", "path": "rentalDates", "label": "Rental dates" }, { "kind": "input", "type": "radiogroup", "path": "rentalType", "label": "Rental type", "props": { "options": [ { "label": "Daily", "value": "daily" }, { "label": "Weekly", "value": "weekly" }, { "label": "Monthly", "value": "monthly" } ] } }, { "kind": "input", "type": "toggle", "path": "driverOver25", "label": "Driver aged over 25" }, { "kind": "input", "type": "toggle", "path": "hasDiscountCode", "label": "I have a discount code" }, { "kind": "input", "type": "textinput", "path": "discountCode", "label": "Discount code" }, { "kind": "action", "type": "button", "label": "Reserve", "uid": "submit", "on": { "click": "submit" } } ]}Notice that the Return to office dropdown is visible all the time, and the Discount code input is too. We’ll fix both with states in the next chapter.