Skip to main content

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​

AttributeTypeRequiredAllowed/DefaultDescription
componentstringYesbarcodeScannerIdentifies the component type. Must be exactly barcodeScanner.
namestringNoβ€”Component name identifier. Use to reference this component from other config if needed.
propsobjectNoβ€”Configuration object for the component behavior and rendering.

props​

AttributeTypeRequiredDescription
minBarcodeLengthintegerNoMinimum length for recognized barcodes. Use to prevent partial/accidental reads.
deduplicatebooleanNoMobile: suppress repeated reads of the same code. Defaults to true.
scanDelayMsnumberNoMobile: per-code deduplication window in milliseconds. Defaults to 1000.
minScanIntervalMsnumberNoMobile: minimum interval between accepted scans. Defaults to 0 (disabled).
continuousbooleanNoMobile: allow more than one accepted scan. Defaults to true.
maxBarcodesintegerNoMobile: maximum accepted scans when continuous scanning is enabled.
onScanactionsListNoActions executed after a successful scan. Receives context including result.
isHiddentemplateExpressionNoBoolean 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:

  1. The scanned barcode is stored in application state at store.scannedBarcode.
  2. 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:

  1. If the scanned code is a QR code, store its data and navigate to /qr-details.
  2. Otherwise, call logBarcodeScan and 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.format only if present; add fallbacks for unknown formats.
    • Sanitize or validate result.data before using in mutations or navigation.
  • User feedback:
    • Show clear confirmations (notifications, highlights) after onScan.
    • Consider audible or haptic feedback on mobile devices.
  • Security and privacy:
    • Avoid logging sensitive barcode contents unless required.
    • Restrict actions that mutate data to authorized roles.
  • Conditional rendering:
    • Use props.isHidden to disable/hide scanners based on workflow state or permissions.