aria-describedby passthrough for hint and error text — the same shape of gap as the name.
Accessible name for the control, for when no visible label exists. Prefer
AriaLabelledBy when one does — an aria-label duplicates that label's text and drifts
from it on rename. aria-labelledby beats aria-label where both are present.
The id of a VISIBLE label element that names this control — the preferred wiring whenever a label already exists on screen. It is also the only path that can name a control's SECONDARY pieces (a filter box, a toggle, a calendar) from that same label: see SecondaryLabelledBy.
Readonlyhostid for the control's focusable element, so other markup can REFERENCE it — aria-controls,
hint text, test hooks.
Whether it doubles as a <label for> target depends on the control, because label[for]
associates only with LABELABLE elements: it works on the input-backed controls (mj-combobox,
mj-numeric-input, mj-datepicker, mj-page-search) and on mj-switch, whose <button> is
labelable too. It does NOT work on mj-dropdown, whose trigger is a div[role=combobox] —
wiring label[for] there produces markup that looks correct, passes review, and leaves the
control named only in the browsers that guess. Each control's own docs say which it is.
The single gate on Toggle() / Open() — true when EITHER the Disabled input or Angular
Forms says so. Never assign it directly; go through syncDisabled().
ReadonlyNamedThis instance's id suffix, shared by every id the control generates.
aria-activedescendant for the input: the option the arrow keys have moved to. Focus stays in
the input the whole time, so without this the highlight is a CSS class and nothing else — a
screen-reader user arrowing through the list hears no change at all.
aria-label for the clear button in the no-visible-label case.
aria-labelledby id list for the clear button when a VISIBLE label names the combobox.
Host-driven disable. Composed with Angular Forms' setDisabledState() into IsDisabled
(the actual gate) — see syncDisabled. A setter, not a bare field, because this input is
routinely bound to an expression that changes over the control's lifetime, and the gate has
to follow it every time.
Id of the popup listbox, so the input can point aria-controls at it while open — the half of
the combobox pattern that makes "collapsed/expanded" refer to something a screen reader can
find.
aria-label for the toggle button in the no-visible-label case. It had no name at all before
#4116 — an unnamed button next to a named input, which announces as "button".
aria-labelledby id list for the toggle button when a VISIBLE label names the combobox.
A callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.
A callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.
The callback function to register
Registers a callback function that is called when the control's value changes in the UI.
This method is called by the forms API on initialization to update the form model when values propagate from the view to the model.
When implementing the registerOnChange method in your own value accessor,
save the given function so your class calls it at the appropriate time.
The following example stores the provided function as an internal method.
registerOnChange(fn: (_: any) => void): void {
this._onChange = fn;
}
When the value changes in the UI, call the registered function to allow the forms API to update itself:
host: {
'(change)': '_onChange($event.target.value)'
}
The callback function to register
Registers a callback function that is called by the forms API on initialization to update the form model on blur.
When implementing registerOnTouched in your own value accessor, save the given
function so your class calls it when the control should be considered
blurred or "touched".
The following example stores the provided function as an internal method.
registerOnTouched(fn: any): void {
this._onTouched = fn;
}
On blur (or equivalent), your class should call the registered function to allow the forms API to update itself:
host: {
'(blur)': '_onTouched()'
}
aria-label for a secondary control in the no-visible-label case: word followed by the
host's own name, or fallback when the host has no name either.
The already-starts-with-word guard is not cosmetic: this repo's house habit is
AriaLabel="Filter roles", and an unconditional prefix announces that box as
"Filter Filter roles".
The match ends on a WORD BOUNDARY, not on a space: AriaLabel="Filter: roles" already begins
with the word and must not be prefixed either, while "Filters" is a different word and must
be. A space-only test gets the punctuated case wrong in the doubling direction.
aria-labelledby for a secondary control when a VISIBLE label names the host: the hidden word
plus that label's own text, composed by the accessibility tree from an id LIST. Empty when
there is no such label, in which case SecondaryLabel supplies a string instead.
An id list is the only mechanism that can work here — the component never sees the label's text, only its id. Without it, every filterable dropdown on a form named this way announces an identical "Filter options", and a form with six of them has six indistinguishable filter boxes.
Id of a hidden span holding one fixed WORD of a secondary control's name — "Filter", "Clear", "Open calendar for". Composed with the host's visible label by SecondaryLabelledBy.
Optionalevent: Event
mj-combobox — Editable dropdown with filtering and optional custom values.
Replaces
<kendo-combobox>. Unlike mj-dropdown, the trigger is a text input that filters the list as you type. When AllowCustom is true, typed text that doesn't match any item is emitted as the value.Every combobox needs an ACCESSIBLE NAME, or it announces as "combobox, collapsed" with no hint of what it selects (WCAG 2.1 4.1.2). Use MJNamedControlBase.AriaLabelledBy when a visible label already exists and MJNamedControlBase.AriaLabel when none does. Here the trigger is a real
<input>, so MJNamedControlBase.InputId IS a valid<label for>target — unlikemj-dropdown, whose trigger is a div.Example: With a visible label (preferred)
Example