One tap on the scan button opens two camera sessions instead of one, and later the plain navigation button opens the camera over a view that should have none. The code itself reads fine: the decoded information arrives and the display updates. The fault is not in decoding and not in camera hardware. It is one Scan Barcode action configured in two places — once on the button and once on a parent container. The sections below trace that single mistake to both symptoms, confirm it in two minutes, remove it, and cover the two faults that mimic it.
What the double fire looks like
Two symptoms arrive together, and they look unrelated until you line them up:
- Tapping the scan button opens two camera screens in rapid sequence, one right after the other. The later session reads the code normally, and the decoded information shows as expected.
- After that scan, tapping the navigation button — which carries no scan action at all — opens the camera again, this time on top of the destination view. The operator has to tap the camera's Cancel link before the requested view appears.
Count the sessions and the pattern is exact: a scan tap opens 2 sessions where 1 is intended, and a navigation tap opens 1 where 0 is intended. Everything downstream doubles with it, so a traceability write or an ERP posting built on the read happens twice per scan until the fix ships.
One action, two places: why both handlers run
A click does not stop at the component you pressed. The client dispatches it up the component tree: the button handles the event first, then the container directly above it, then each ancestor in turn. Web developers call this event bubbling, and it is standard DOM behaviour: an event raised on a child element is dispatched to that element first and then to each of its ancestors in turn. An action configured on any ancestor joins the dispatch, exactly as if the operator had pressed that ancestor too.
In the project that produced this exact behaviour, the second copy of the action sat on the column container that wrapped both buttons. Add up the scan actions on each click path:
One misplaced action accounts for both symptoms, with no second fault required.
The two-minute test
- Select the scan button and open its event list. You should see one OnClick event carrying the Scan Barcode action.
- Select the container that wraps the buttons, then each ancestor above it, and read the same list.
- A second OnClick event carrying another Scan Barcode action is the fault. Disable that container action, redeploy, and tap the scan button once: the session count drops from 2 to 1.
- Press the navigation button next. With the container action gone, no camera opens over the destination view and no Cancel tap is needed.
No decode logs or network traces are needed. The event list is the evidence.
Fix: the action lives on the button alone
- Open the view and select the parent container — the column container in the reported case.
- Open its OnClick event and delete the Scan Barcode action. Keep the container itself; it is doing layout work.
- Confirm exactly one Scan Barcode action remains in the view, on the scan button's OnClick event.
- Save, redeploy, and retest on the device class that showed the fault, because phone, tablet and desktop clients dispatch input in their own ways.
- Tap the scan button once and count: 1 session, 1 read, 1 handler call. Tap the navigation button once: navigation only, no camera.
- Check containers above the container too. Nested groups, the view root and any reusable template the view sits in can carry configured events the same way.
If the camera still opens twice
Two other faults produce a near-identical screen. Work them in this order after the container fix.
One tap, two input events
On touch devices a single tap can reach the client as both the native touch event and a synthesized mouse event, and a component configured for both fires twice per tap. Separate the two with a counter: wire a counter to each event you own and tap once. An increase of 1 on the button plus 1 on the parent is bubbling; an increase of 2 on the same component is input duplication. Bind the component to one input event type and the count returns to 1. A write-up of a mobile client where a mouse-down handler also fires on touch input shows the same counter logic and the guard that stops the double dispatch.
The camera opens once but the value arrives twice
When the session count is already 1 and the decoded value still shows twice, the duplication sits downstream of the camera: the Barcode Scanned session event is being handled in two places. Usually two open views each registered a message handler, or one handler got registered twice after a script re-run. Give the event one owner per session, then latch the value on the receiving side — the latch-on-the-pulse pattern is the standard way. When two windows legitimately need the same scans, the two-listener routing pattern keeps ownership explicit, and the per-user session property stops one operator's session from bleeding into another's.
If the handler re-triggers itself while it is still running, that is recursion rather than duplication, and the recursive-update fix covers it separately.
A debounce guard as the backstop
With the parent action removed, nothing should re-fire. For noisy input paths — worn touch panels, gloved taps, a network stack that retries — timestamp the session event and drop any repeat of the same decoded value inside a guard window:
The window only has to exceed the input bounce, not the process. A genuine second presentation of the same label arrives seconds or minutes later, far outside a 500 ms guard, and passes. Set the window from the fastest legitimate repeat on your line, then leave it alone.
When the scan belongs to the line, not the phone
A phone or tablet reading its own camera is the right tool for commissioning, setup and ad-hoc checks. When the same read gates production — lot verification, traceability, a pass/fail station — take the hand and the browser out of the path. A fixed code reader fired by a hardware trigger from the PLC removes the touch UI and the whole event-dispatch chain from the loop, and the PLC-triggered decode pattern shows that wiring end to end.
For a presentation station where an operator shows one label at a time:
- Resolution
- Up to 3 MP
- Shutter
- Global
- Interface
- USB
The LS-CRD-0047 pairs a 1.2 MP sensor with USB 2.0 output and a 60-120 mm reading distance, so the decode lands on the wire the moment the label meets the mark.
Where the reader bolts up beside a conveyor and the PLC owns the trigger:
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
- Shutter
- Global
- Lens mount
- M12
The MV-ID3013PM-12M-WBN pairs a 12 mm lens with a 1.3 MP global-shutter sensor over Fast Ethernet, and the M12 mount suits a bracket beside the line. The smart cameras family adds onboard inspection when the decision has to be made in the housing itself, and the camera finder filters both families by interface, resolution and shutter.
To plan the reader-to-PLC handshake, start the system configurator at the trigger step, or bring the build question to us through the contact page.
Before you close the ticket
- Configure each action on the lowest component that owns the gesture: the button, not the panel around it.
- After copying a component or a whole view out of a template, open the event list of every container above it — copies bring their configured events along.
- During commissioning, count events per tap with a temporary counter. A tap that yields 2 of anything is a configuration fault, not a device fault.
- Retest on every device class the operators use, because touch and desktop clients dispatch input differently.
- Keep one owner per Barcode Scanned session event, and connect any legitimate second consumer explicitly.
The code-reading topic page collects the rest of the decode-side fixes, from framing faults in the PLC receive buffer to trigger wiring and suffix handling.
Questions
Why does the camera open over the destination view after the navigation button?
The navigation button carries no scan action, but a click keeps travelling: it leaves the button you pressed and runs through every ancestor, and the container above both buttons holds a Scan Barcode action of its own. Any clickable child inside that container triggers it — rows, icons and labels included — so the camera opens on top of the view you navigated to. Deleting the container's OnClick event fixes both buttons at once.
Can I keep the parent action and just stop the event from bubbling?
Some view designers let you mark an event as handled, but that leaves a trap: every component added under the container later must remember the guard, and a template copy pasted into another view loses it. Deleting the action from the container is the durable fix. If the container genuinely needs its own click action, move the scan to a component with no clickable children.
The decoded value arrives twice but the camera opens once — is that the same fault?
No. Two camera sessions mean two Scan Barcode actions on the click path. A doubled value with a single session means the Barcode Scanned event is handled twice: two open views each registered a message handler, or one handler registered twice after a script re-run. Give the event one owner per session, then latch or debounce the value at the receiver so a repeat inside the same cycle cannot re-enter the display.
How do I stop a hardware barcode scanner from sending the same read twice?
Presentation and fixed scanners include a same-symbol timeout: once enabled, the reader refuses to resend an identical code until the timeout expires. Set it a little longer than the fastest legitimate reappearance of the same label on your line, and keep the host-side debounce window as a second layer for retries on serial or network links.

