The EntityAttributeBooleanField component is a specialized attribute field responsible for rendering and managing boolean values within an entity.
It uses Quasar’s QToggle component and integrates seamlessly with the lin-pulsar-core design system and scoped i18n to provide a
consistent, configurable, and localized boolean input.
- Renders a boolean attribute as a toggle switch
- Synchronizes the toggle state with the entity model
- Emits updates in a controlled, immutable way
- Supports scoped translations for labels
- Integrates UI customization through the design system
- Supports disabling the field via
inputSettings.disable - Supports an initial state via
inputSettings.defaultValuewhen the entity has no value - Supports storing values other than
true/falseviainputSettings.trueValueandinputSettings.falseValue,defaultValueaccepting the same vocabulary
The component relies on the shared AttributeFieldProps interface with FieldBooleanSettings.
| Prop | Type | Required | Description |
|---|---|---|---|
instanceId |
string |
Yes | Identifier used for contextual data |
i18nScope |
string |
Yes | I18n scope for localizing the component |
uiNamespace |
string |
Yes | Base UI design namespace for styling |
definition |
LinPulsarAttributeConfiguration<FieldBooleanSettings> |
Yes | Attribute definition (name, type, input configuration) |
entity |
Record<string, unknown> |
Yes | Entity object containing the boolean attribute value |
ignoreRules |
boolean |
No | Indicates whether to bypass validation rules for this field (default: false) |
export interface AttributeFieldProps<T = Record<string, unknown>> extends CommonComponentProps {
/** Identifier for contextual data. */
instanceId: string;
/** Attribute configuration describing how the field should be rendered. */
definition: LinPulsarAttributeConfiguration<T>;
/** Entity object holding the attribute value. */
entity: Record<string, unknown>;
/**
* Indicates whether to bypass validation rules for this field.
* When set to true, validation rules will not be applied.
* @default false
*/
ignoreRules?: boolean;
}export interface FieldSettings extends Record<string, unknown> {
/** Indicates whether to bypass validation rules for this field. */
ignoreRules?: boolean;
/** When true, the toggle is rendered as non-interactive (disabled state). */
disable?: boolean;
}
export interface FieldBooleanSettings extends FieldSettings {
/**
* Default value for the boolean field. When provided, this value will be used as the
* initial state of the field.
*/
defaultValue?: unknown;
/**
* The model value that should be considered as checked/ticked/on.
* @default true
*/
trueValue?: unknown;
/**
* The model value that should be considered as unchecked/unticked/off.
* @default false
*/
falseValue?: unknown;
}ignoreRules and disable come from the shared FieldSettings; defaultValue, trueValue and
falseValue are specific to boolean fields.
| Event | Payload | Description |
|---|---|---|
update:entity |
Record<string, unknown> |
Emitted when the toggle value changes and the entity is updated |
- Emits the entire updated entity object
- Does not mutate the original entity reference
- The parent component remains the single source of truth
The component uses useScopedI18n to resolve translations for the attribute label.
`${i18nScope}.fields.${definition.name}`;:label="translateOrDefault('', 'label')"- Attempts to translate the
labelkey within the scoped namespace - Falls back to an empty string if the translation key does not exist
- Prevents raw translation keys from leaking into the UI
UI customization is handled via the lin-pulsar-core design system and useUiDesign().
`${uiNamespace}.${definition.name}`;- Quasar component:
q-toggle - Props resolved as
LinPulsarQToggleProps
Example:
uiNamespace = 'entity-editor'
// Final UI namespace
entity-editor.isActive → q-toggleThis allows fine-grained styling and behavior customization per attribute.
The attribute name supports dot notation to target values located inside sub-objects of the entity (e.g. extraParameters.login):
- The initial value is read from the nested path (
getNestedValuefrom lin-pulsar-core) - Updates rewrite only the targeted nested property, preserving the rest of the entity structure (
setNestedValuefrom lin-pulsar-core) - Missing intermediate objects are created when updating; intermediate values that are not objects are replaced by objects
- The
update:entityevent still emits the complete updated entity object
- The toggle initializes its value from the entity at the path
definition.name, falling back todefinition.inputSettings.defaultValue, then tonull - The user toggles the switch
localValueis updated viav-modelupdateValue()emitsupdate:entitywith a new entity object
QToggle → localValue → updateValue → update:entity
const localValue = ref(getNestedValue(props.entity, props.definition.name) ?? props.definition.inputSettings?.defaultValue ?? null);-
Uses a local reactive value to decouple UI interaction from the parent state
-
Falls back to
inputSettings.defaultValuewhen the entity has no value for the attribute, then tonullwhen no default is configured -
A
watchon() => getNestedValue(props.entity, props.definition.name)keepslocalValuein sync when the parent updates the entity — it only triggers when the specific attribute value changes, not when other fields of the entity change -
The watcher applies the same fallback chain as the initialization:
localValue.value = newValue ?? props.definition.inputSettings?.defaultValue ?? null;
Clearing the attribute from the parent therefore restores the configured default rather than emptying the toggle.
- The default is displayed, not committed. It only feeds
localValue;update:entityis emitted on user interaction only. A form left untouched submits an entity that still has no value for the attribute, even though the toggle showed the default. Pre-fill the entity upstream if the value must be persisted. - The chain is nullish, not falsy. An entity value of
falsewins over adefaultValueoftrue, at initialization as well as on every later update. Replacing??with||would make a toggle silently re-check itself each time the parent unchecks it.
Both settings are forwarded to QToggle, so the attribute can hold something other than a JavaScript
boolean:
:true-value="definition.inputSettings?.trueValue" :false-value="definition.inputSettings?.falseValue"{ "trueValue": "Y", "falseValue": "N" }With this configuration, the entity attribute holds "Y" or "N"; the toggle is rendered checked
when the value equals trueValue.
Points to keep in mind:
- They are data semantics, not styling. Unlike the other toggle options, they are not part of
LinPulsarQTogglePropsand therefore cannot be set fromdesign.json— only from the attribute configuration - Omitting them is safe. The bindings pass
undefined, and Vue then applies Quasar's own defaults:trueValue: true,falseValue: false. Setting them explicitly tonullin the JSON is a different matter —nullis notundefined, so the default is not applied defaultValuemust use the same vocabulary. It is typedunknown, liketrueValueandfalseValue, precisely so the three can agree. Configure{ "trueValue": "Y", "falseValue": "N", "defaultValue": "Y" }, not"defaultValue": true— the literaltruewould match neither stored value and the toggle would render indeterminate- An unset attribute renders indeterminate. With no entity value and no
defaultValue,localValueisnull, which is exactly Quasar's defaultindeterminateValue. The toggle shows neither on nor off until the user clicks it
<script setup lang="ts">
import EntityAttributeBooleanField from '@/components/field/EntityAttributeBooleanField.vue';
const entity = reactive({
enabled: true,
});
const definition = {
name: 'enabled',
input: 'Boolean',
type: 'Boolean',
required: false,
hasValidations: false,
inputSettings: {
ignoreRules: false,
defaultValue: true,
},
};
const onUpdateEntity = (updatedEntity: Record<string, unknown>) => {
Object.assign(entity, updatedEntity);
};
</script>
<template>
<EntityAttributeBooleanField
ui-namespace="entity-editor"
instance-id="user-1"
:definition="definition"
:entity="entity"
@update:entity="onUpdateEntity"
/>
</template>- Clear responsibility: Dedicated to boolean attributes only
- Immutable updates: Avoids side effects by emitting new entity objects
- Localized: Fully supports scoped translations
- Customizable: Integrates with the UI design system
- Reusable: Works in any context with a compatible attribute definition
- Framework-aligned: Built with Vue 3 Composition API and Quasar best practices
- Verify the initial toggle state reflects the entity value
- Assert
update:entityemission when the toggle changes - Mock
useScopedI18nanduseUiDesignfor isolated unit tests - UI rendering can be shallow-mounted since behavior is event-driven
- Verify that
localValueis updated when the entity value atdefinition.namechanges - Verify that
localValueis not overwritten when only other entity attributes change (e.g. mutatenamewhile keeping the boolean attribute value identical) - Verify the watcher falls back to
inputSettings.defaultValuewhen the attribute becomesundefinedornull, and tonullwhen no default is configured - Verify an attribute value of
falsewins over adefaultValueoftrue— the only case that tells??from|| - Verify the toggle is rendered as disabled when
definition.inputSettings.disableistrue
- The component assumes
definition.input === 'Boolean' - Uses
FieldBooleanSettingstype forinputSettings, which supports theignoreRules,disable,defaultValue,trueValueandfalseValueproperties - Boolean fields typically don't require validation rules, but validation can be bypassed via the
ignoreRulesprop ordefinition.inputSettings.ignoreRulesif needed - The field is rendered as non-interactive when
definition.inputSettings.disableistrue - Translation keys are optional and safely fallback
- Designed to be used exclusively through
EntityAttributeField
EntityAttributeBooleanField is a leaf component in the attribute rendering hierarchy.
It focuses exclusively on:
- UI rendering (
QToggle) - Local state handling
- Emitting normalized entity updates
All orchestration, validation, and schema logic remains outside, ensuring a clean and scalable architecture.