sgcHTML Forms and Inputs
Twenty-one input widgets for sgcHTML forms: text, numbers, dates, selection,
sliders, colour, rich text, file upload and a signature pad. Each renders a
Bootstrap-styled control and can bind directly to a Delphi TDataSource.
Read sgcwebsockets-html-core first. It covers the page builder these widgets
register with, and the edition gate that decides whether they exist at all.
In short: sgcHTML is All-Access only, needs Indy, and is not available on
Android or iOS.
When to use this skill
- Put a form on a server-rendered page: text, email, password, number, date
- Offer a choice: select, multi-select, radio group, checkbox, autocomplete
- Take a date, a time, a datetime or a date range
- Take a number on a slider, or a range between two values
- Take rich text, a colour, an uploaded file or a drawn signature
- Bind any of those to a dataset field so the page shows live data
The surface every widget shares
These are on all of them, and they are most of what you will actually set:
| Property |
What it does |
PageBuilder |
The builder this widget renders into. Nothing appears without it |
Label_ |
The visible label. Note the trailing underscore |
ElementName |
The HTML form field name, which is what a POST arrives under |
ElementID, CSSClass, Style, Attributes |
Raw HTML passthrough |
Section, SectionTitle, SectionOrder, RowGroup |
Where it lands on the page |
ColumnWidth |
Bootstrap column width, cwAuto or cw1 to cw12 |
DataSource, DataField, DataAutoRefresh |
Dataset binding |
ComponentVisible |
Render it or not |
HTML |
Read-only, the fragment this widget produces |
OnDataChanged, OnBeforeRefresh, OnAfterRefresh |
Delphi events |
OnClick |
A string of JavaScript, not a Delphi event |
Label_ ends in an underscore because Label collides in Delphi. Writing
FEdit.Label := 'Name' will not compile, and the fix is the underscore.
OnClick being a string is the one that surprises people. It is client-side
JavaScript emitted into the markup. For server-side reactions use the Delphi
events, or HTMX from sgcwebsockets-html-core.
Before you start, ask the developer
Use a structured question tool if your host has one, for example Claude Code's
AskUserQuestion. Otherwise ask in chat:
- Is this bound to a dataset, or free-standing? With
DataSource and
DataField set, the widget shows live data and you write almost no code.
Without them you set Value yourself.
- How is the form submitted? A normal POST reads
ElementName values on
the server. HTMX submits fragments instead. That decision shapes the handler.
- What layout?
Section and RowGroup group widgets, ColumnWidth sets
the Bootstrap columns. Without them everything stacks.
- Which input type? One
TsgcHTMLComponent_Edit covers text, email,
password, number, date and more through InputType, so a separate component
is often unnecessary.
Components in this skill
| Group |
Components |
| Text |
_Edit, _Memo, _RichEditor |
| Choice |
_Select, _MultiSelect, _RadioGroup, _CheckBox, _AutoComplete, _Transfer |
| Date and time |
_DatePicker, _TimePicker, _DateTimePicker, _DateRangePicker |
| Numeric |
_Slider, _RangeSlider, _Rating |
| Other input |
_ColorPicker, _FileUpload, _SignaturePad |
| Structure |
_Form, _InputGroup |
All are prefixed TsgcHTMLComponent_.
Quickstart, a bound form
uses
sgcHTML_Component; // plus each widget's own unit, see its API page
FEdit := TsgcHTMLComponent_Edit.Create(Self);
FEdit.PageBuilder := FPage;
FEdit.Label_ := 'Email';
FEdit.ElementName := 'email';
FEdit.InputType := itEmail;
FEdit.Required := True;
FEdit.Placeholder := 'you@example.com';
FEdit.HelpText := 'We only use this to reply.';
FEdit.ColumnWidth := cw6;
FEdit.Section := 'contact';
FEdit.SectionTitle := 'Contact details';
// bind it to a dataset instead of setting Value by hand
FEdit.DataSource := dsCustomers;
FEdit.DataField := 'EMAIL';
FEdit.DataAutoRefresh := True;
TsgcHTMLInputType is (itText, itEmail, itPassword, itNumber, itTel, itURL, itSearch, itDate, itTime, itDateTimeLocal, itMonth, itWeek, itColor, itRange, itFile, itHidden), so a plain _Edit covers most fields on its own.
TsgcHTMLColWidth is (cwAuto, cw1 ... cw12), the twelve Bootstrap columns.
Two cw6 widgets sit side by side, three cw4 make thirds.
Layout without writing CSS
Widgets are placed by property, not by markup:
Section groups widgets into a block, SectionTitle gives that block a
heading, and SectionOrder decides where the block sits on the page.
RowGroup puts widgets on the same row.
ColumnWidth divides that row.
Set none of them and the form renders as a single stacked column, which is a
perfectly reasonable default for a short form.
Things that catch people out
Label does not exist. It is Label_.
OnClick is JavaScript in a string. Assigning a Delphi method to it will not
compile, and it is not a server-side event.
- A widget with no
PageBuilder renders nowhere and reports nothing.
ElementName is what the browser posts. Leaving it blank means the value
arrives unnamed and you cannot read it server-side.
Required renders the HTML validation attribute. That is a browser check and
trivially bypassed, so validate again on the server.
- Binding a
DataSource without DataField shows an empty control rather than
raising, which reads as the binding being broken when it is just incomplete.
Routing
- Find a component:
reference/components-index.md lists every component, its unit, and its edition, grouped by Reg module.
- Uses clause: add the component's
unit: value (shown on its API page) to your uses clause. Nothing compiles without it.
- API detail:
reference/api/<Component>.md has the Properties, Events and Methods, each in both Delphi and C++Builder form.
- Option / enum / event types: property and event types link to
reference/types/<TypeName>.md, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers.
- Examples:
examples/index.md is the full demo catalog; examples/<Component>.md is a focused, real usage snippet for the most-used components.
- Concepts:
concepts/overview.md (getting started + uses-clause rule) and concepts/editions-and-features.md (which components your edition includes).
- Bundled resources:
concepts/resources.md lists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN.
- Version history:
reference/history.md lists what changed in each sgcWebSockets release.
Editions
Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or concepts/editions-and-features.md, before relying on a component.
Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.
1---2name: sgcwebsockets-html-forms3description: sgcHTML Forms and Inputs4---56# sgcHTML Forms and Inputs78Twenty-one input widgets for sgcHTML forms: text, numbers, dates, selection,9sliders, colour, rich text, file upload and a signature pad. Each renders a10Bootstrap-styled control and can bind directly to a Delphi `TDataSource`.1112Read `sgcwebsockets-html-core` first. It covers the page builder these widgets13register with, and the edition gate that decides whether they exist at all.14In short: sgcHTML is All-Access only, needs Indy, and is not available on15Android or iOS.1617## When to use this skill1819- Put a form on a server-rendered page: text, email, password, number, date20- Offer a choice: select, multi-select, radio group, checkbox, autocomplete21- Take a date, a time, a datetime or a date range22- Take a number on a slider, or a range between two values23- Take rich text, a colour, an uploaded file or a drawn signature24- Bind any of those to a dataset field so the page shows live data2526## The surface every widget shares2728These are on all of them, and they are most of what you will actually set:2930| Property | What it does |31| --- | --- |32| `PageBuilder` | The builder this widget renders into. Nothing appears without it |33| `Label_` | The visible label. Note the trailing underscore |34| `ElementName` | The HTML form field name, which is what a POST arrives under |35| `ElementID`, `CSSClass`, `Style`, `Attributes` | Raw HTML passthrough |36| `Section`, `SectionTitle`, `SectionOrder`, `RowGroup` | Where it lands on the page |37| `ColumnWidth` | Bootstrap column width, `cwAuto` or `cw1` to `cw12` |38| `DataSource`, `DataField`, `DataAutoRefresh` | Dataset binding |39| `ComponentVisible` | Render it or not |40| `HTML` | Read-only, the fragment this widget produces |41| `OnDataChanged`, `OnBeforeRefresh`, `OnAfterRefresh` | Delphi events |42| `OnClick` | **A string of JavaScript**, not a Delphi event |4344`Label_` ends in an underscore because `Label` collides in Delphi. Writing45`FEdit.Label := 'Name'` will not compile, and the fix is the underscore.4647`OnClick` being a string is the one that surprises people. It is client-side48JavaScript emitted into the markup. For server-side reactions use the Delphi49events, or HTMX from `sgcwebsockets-html-core`.5051## Before you start, ask the developer5253Use a structured question tool if your host has one, for example Claude Code's54`AskUserQuestion`. Otherwise ask in chat:55561. **Is this bound to a dataset, or free-standing?** With `DataSource` and57 `DataField` set, the widget shows live data and you write almost no code.58 Without them you set `Value` yourself.592. **How is the form submitted?** A normal POST reads `ElementName` values on60 the server. HTMX submits fragments instead. That decision shapes the handler.613. **What layout?** `Section` and `RowGroup` group widgets, `ColumnWidth` sets62 the Bootstrap columns. Without them everything stacks.634. **Which input type?** One `TsgcHTMLComponent_Edit` covers text, email,64 password, number, date and more through `InputType`, so a separate component65 is often unnecessary.6667## Components in this skill6869| Group | Components |70| --- | --- |71| Text | `_Edit`, `_Memo`, `_RichEditor` |72| Choice | `_Select`, `_MultiSelect`, `_RadioGroup`, `_CheckBox`, `_AutoComplete`, `_Transfer` |73| Date and time | `_DatePicker`, `_TimePicker`, `_DateTimePicker`, `_DateRangePicker` |74| Numeric | `_Slider`, `_RangeSlider`, `_Rating` |75| Other input | `_ColorPicker`, `_FileUpload`, `_SignaturePad` |76| Structure | `_Form`, `_InputGroup` |7778All are prefixed `TsgcHTMLComponent_`.7980## Quickstart, a bound form8182```pascal83uses84 sgcHTML_Component; // plus each widget's own unit, see its API page8586FEdit := TsgcHTMLComponent_Edit.Create(Self);87FEdit.PageBuilder := FPage;88FEdit.Label_ := 'Email';89FEdit.ElementName := 'email';90FEdit.InputType := itEmail;91FEdit.Required := True;92FEdit.Placeholder := 'you@example.com';93FEdit.HelpText := 'We only use this to reply.';94FEdit.ColumnWidth := cw6;95FEdit.Section := 'contact';96FEdit.SectionTitle := 'Contact details';9798// bind it to a dataset instead of setting Value by hand99FEdit.DataSource := dsCustomers;100FEdit.DataField := 'EMAIL';101FEdit.DataAutoRefresh := True;102```103104`TsgcHTMLInputType` is `(itText, itEmail, itPassword, itNumber, itTel, itURL,105itSearch, itDate, itTime, itDateTimeLocal, itMonth, itWeek, itColor, itRange,106itFile, itHidden)`, so a plain `_Edit` covers most fields on its own.107108`TsgcHTMLColWidth` is `(cwAuto, cw1 ... cw12)`, the twelve Bootstrap columns.109Two `cw6` widgets sit side by side, three `cw4` make thirds.110111## Layout without writing CSS112113Widgets are placed by property, not by markup:114115- `Section` groups widgets into a block, `SectionTitle` gives that block a116 heading, and `SectionOrder` decides where the block sits on the page.117- `RowGroup` puts widgets on the same row.118- `ColumnWidth` divides that row.119120Set none of them and the form renders as a single stacked column, which is a121perfectly reasonable default for a short form.122123## Things that catch people out124125- `Label` does not exist. It is `Label_`.126- `OnClick` is JavaScript in a string. Assigning a Delphi method to it will not127 compile, and it is not a server-side event.128- A widget with no `PageBuilder` renders nowhere and reports nothing.129- `ElementName` is what the browser posts. Leaving it blank means the value130 arrives unnamed and you cannot read it server-side.131- `Required` renders the HTML validation attribute. That is a browser check and132 trivially bypassed, so validate again on the server.133- Binding a `DataSource` without `DataField` shows an empty control rather than134 raising, which reads as the binding being broken when it is just incomplete.135136## Routing137138- **Find a component**: `reference/components-index.md` lists every component, its `unit`, and its edition, grouped by Reg module.139- **Uses clause**: add the component's `unit:` value (shown on its API page) to your `uses` clause. Nothing compiles without it.140- **API detail**: `reference/api/<Component>.md` has the Properties, Events and Methods, each in both Delphi and C++Builder form.141- **Option / enum / event types**: property and event types link to `reference/types/<TypeName>.md`, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers.142- **Examples**: `examples/index.md` is the full demo catalog; `examples/<Component>.md` is a focused, real usage snippet for the most-used components.143- **Concepts**: `concepts/overview.md` (getting started + uses-clause rule) and `concepts/editions-and-features.md` (which components your edition includes).144- **Bundled resources**: `concepts/resources.md` lists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN.145- **Version history**: `reference/history.md` lists what changed in each sgcWebSockets release.146147## Editions148149Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or `concepts/editions-and-features.md`, before relying on a component.150151Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.152