DatabaseControl
A control for choosing a database record from a dropdown list.
The source is any query. The control wraps it in a subquery and adds searching, sorting and paging, never rewriting it - the same contract as buildQuery() in report-engine. Joins, a fixed filter or a computed item text therefore go into the SQL, not into the control's parameters:
"author_id" to DatabaseControl(
label = BooksTr.Form.author(),
query = QueryFragment("SELECT id, name FROM books.authors"),
displayColumn = "name"
)The control's value is the idColumn of the selected row. The whole row - including the columns the control does not show - goes to ActionContext.payload on selection, so an action can fill other controls from it.
Parameters
Source query. Its parameters are attached to every call.
Result column shown as the item text.
Result column that is the control's value.
Sorting of the list, by displayColumn by default. idColumn is always appended at the end as a tie-breaker: without it paging with OFFSET is not deterministic, and when further pages are appended an item with a repeated text at a page boundary could show up twice or not at all.
Search condition for the typed text. No lambda, or null from it, means the default displayColumn::text ILIKE %text%. The same shape as buildQuickSearch in report-engine.
Number of items loaded at once.
Constructors
Properties
How long to wait after the last typed character before the query goes out.
Validator responsible for validating this control. Every control type provides its own implementation (e.g. StringValidator). Empty implementation by default
Functions
Whether this control can hold value, i.e. whether it is a value of type T (and for a choice from fixed options - one of them). Checked for initial values and in updateControl. Controls without a value of their own accept nothing: a section, a button, and a repeatable list, which manages its rows itself. Containers check the shape of their initial data in setInitValue.
Children of this control in the current form state, each with a context in which this control is the parent: a section has one set, a repeatable - one per row. The engine walks down the tree through them when initializing, validating and collecting data.
Converts the control's internal state (ControlState) into a result to save (ControlResultData). Can be overridden for custom conversions (e.g. in RepeatableControl).
Makes a deep copy of the initial value for the current value. Matters for mutable types (e.g. List), so that changes to value do not affect initValue.
Renders the control's own UI. Every concrete control type (e.g. StringControl) implements it.
Renders this control's validation errors.
Runs the actions defined for this control, usually after a value change.
Returns the control's result (current and initial value) for further processing. If the control is invisible, its currentValue is set to null.
Sets the references to the form components. This is the second stage of a control's initialization, called by FormHandler. Gives access to the global state, the schema and the error manager. Also lets particular controls run additional initialization steps they need
Renders the loading indicator.
Renders the main content of the menu.
Renders the list of options to choose from.
Registers the children in the global map Holds references to the controls defined inside a control that has its own
Why the control does not accept value, or null when it does.
Renders the control in the user interface. This is the entry point for FormView. Handles visibility.
Subclasses implement this to render the content of the dropdown menu.
Called once per value, outside rendering, and the result is stored in ControlState.displayText.
Renders the search field inside the menu.
Sets the control's initial value and creates its state (ControlState).
Runs this control's validation with its validator.