Barcode Scanner Component
Introductionβ
The Barcode Scanner Component in CXTMS provides fast, accurate barcode capture using the device camera or external scanners (e.g., USB/Bluetooth βkeyboard wedgeβ devices). It is event-driven: when a barcode is successfully read, a configurable list of actions runs via props.onScan. Use name to reference this component elsewhere if needed, and props.isHidden for conditional rendering.
YAML Structureβ
component: barcodeScanner
name: scannerPrimary
props:
minBarcodeLength: 8
isHidden: "{{ eval !store.enableScanner }}"
onScan:
- setStore:
scannedBarcode: "{{ result.data }}"
- notification:
message: "Barcode scanned: {{ result.data }}"
Attribute Descriptionβ
Root levelβ
| Attribute | Type | Required | Allowed/Default | Description |
|---|---|---|---|---|
component | string | Yes | barcodeScanner | Identifies the component type. Must be exactly barcodeScanner. |
name | string | No | β | Component name identifier. Use to reference this component from other config if needed. |
props | object | No | β | Configuration object for the component behavior and rendering. |
propsβ
| Attribute | Type | Required | Description |
|---|---|---|---|
minBarcodeLength | integer | No | Minimum length for recognized barcodes. Use to prevent partial/accidental reads. |
deduplicate | boolean | No | Mobile: suppress repeated reads of the same code. Defaults to true. |
scanDelayMs | number | No | Mobile: per-code deduplication window in milliseconds. Defaults to 1000. |
minScanIntervalMs | number | No | Mobile: minimum interval between accepted scans. Defaults to 0 (disabled). |
continuous | boolean | No | Mobile: allow more than one accepted scan. Defaults to true. |
maxBarcodes | integer | No | Mobile: maximum accepted scans when continuous scanning is enabled. |
onScan | actionsList | No | Actions executed after a successful scan. Receives context including result. |
isHidden | templateExpression | No | Boolean expression controlling conditional rendering. When truthy, the component is hidden. |
onScan contextβ
Actions in onScan receive a result payload with commonly used fields:
result.data: the decoded barcode contents (string)result.format: the detected symbology/format (for example,QR_CODE,CODE_128), when available
Note: Field availability may vary by platform/scanner. Guard logic accordingly.
Web form integrationβ
On the web renderer, onScan actions receive the surrounding form context. This means actions such as setFields can write the scanned value directly into a field when the scanner is inside a form component or a React Hook Form provider. Legacy Formik forms remain supported.
The web listener ignores keystrokes while focus is in an input, textarea, select, option, button, or content-editable element. Outside those controls, it completes a scan on Enter or after 200 ms without another key. The default minBarcodeLength is 4.
Mobile HID scanner behaviorβ
The mobile renderer accepts USB and Bluetooth HID scanners through the same scan accumulator
used by the camera scanner. Repeated reads are deduplicated per barcode, so alternating codes
do not reset each other's deduplication window. Configure the behavior with deduplicate,
scanDelayMs, minScanIntervalMs, continuous, and maxBarcodes. These settings apply to
both the native HID listener and its hidden-input fallback.
Native HID keystrokes include their device event timestamps. Mobile uses those timestamps,
rather than the potentially bursty time at which JavaScript receives the events, to decide
whether a pause separates two scans. This prevents a busy JavaScript thread from splitting one
physical scan into fragments. A scanner terminator (Enter or Tab) completes the scan
immediately; scanners without a terminator use a 600 ms quiet-window fallback. Fragments shorter
than minBarcodeLength are discarded.
Only the currently focused mobile navigation screen listens for HID scanner input. When a
screen loses focus, the native listener is detached, any partial scan buffer is cleared, and
the hidden-input fallback is removed. This prevents React-mounted screens lower in the
navigation stack from processing the same physical scan or firing duplicate onScan actions.
Examplesβ
1) Basic scanner with state update and notificationβ
component: barcodeScanner
name: scannerPrimary
props:
minBarcodeLength: 8
onScan:
- setStore:
scannedBarcode: "{{ result.data }}"
- notification:
message: "Barcode scanned: {{ result.data }}"
What happens:
- The scanned barcode is stored in application state at
store.scannedBarcode. - A notification displays the scanned value.
2) Conditional logic by format, navigation or mutationβ
component: barcodeScanner
name: scannerConditional
props:
minBarcodeLength: 10
onScan:
- if:
condition: "{{ eval result.format === 'QR_CODE' }}"
then:
- setStore:
qrCodeData: "{{ result.data }}"
- navigate:
to: "/qr-details"
else:
- mutation:
command: "logBarcodeScan"
variables:
barcodeData: "{{ result.data }}"
format: "{{ result.format }}"
- notification:
message: "Barcode logged: {{ result.data }}"
What happens:
- If the scanned code is a QR code, store its data and navigate to
/qr-details. - Otherwise, call
logBarcodeScanand show a confirmation notification.
3) Conditional rendering (hide when disabled)β
component: barcodeScanner
name: scannerToggled
props:
isHidden: "{{ eval !store.enableScanner }}"
onScan:
- notification:
message: "Captured: {{ result.data }}"
This hides the component unless store.enableScanner is true.
4) Populate a form field from a scanβ
component: form
name: packageForm
children:
- component: field
name: barcode
props:
type: text
label: Barcode
- component: barcodeScanner
name: packageScanner
props:
minBarcodeLength: 6
onScan:
- setFields:
barcode: "{{ result.data }}"
On web, setFields uses the enclosing form context to populate barcode. Keep focus outside editable controls while using a keyboard-wedge scanner, because normal typing in those controls is deliberately excluded from scan capture.
Best Practicesβ
- Choose a sensible
minBarcodeLength:- Too low can admit false positives (e.g., stray keystrokes from wedge scanners).
- Too high can reject legitimate short codes.
- Design for both camera and wedge scanners:
- Wedge scanners paste input quickly; ensure focus states in your UI wonβt interfere with capturing.
- For camera scanning, provide adequate lighting/contrast and test on target devices.
- Guard your logic:
- Check
result.formatonly if present; add fallbacks for unknown formats. - Sanitize or validate
result.databefore using in mutations or navigation.
- Check
- User feedback:
- Show clear confirmations (notifications, highlights) after
onScan. - Consider audible or haptic feedback on mobile devices.
- Show clear confirmations (notifications, highlights) after
- Security and privacy:
- Avoid logging sensitive barcode contents unless required.
- Restrict actions that mutate data to authorized roles.
- Conditional rendering:
- Use
props.isHiddento disable/hide scanners based on workflow state or permissions.
- Use