Barcode scanner troubleshooting

User
document.addEventListener('deviceready', function () {
window.f7App = new Framework7({
el: '#app',
name: 'FossettsCircusApp',
theme: 'auto',
routes: [
{ path: '/', url: 'pages/home.html' },
{ path: '/staff-tickets/', url: 'pages/staff-tickets.html' },
{ path: '/staff-pay-terminal/', url: 'pages/staff-pay-terminal.html' },
{ path: '/staff-check-orders/', url: 'pages/staff-check-orders.html' },

{ path: '/event/:id/:dateId/', url: 'pages/event-details.html' }
]
});

// Create main view with default URL
window.mainView = f7App.views.create('.view-main', { url: '/' });

function startApp() {
navigator.splashscreen.hide();
initializeApp();
}

if (cordova.platformId === 'android' && cordova.plugins?.permissions) {
const permissions = cordova.plugins.permissions;
permissions.checkPermission(permissions.CAMERA, function (status) {
if (status.hasPermission) {
startApp();
} else {
permissions.requestPermission(
permissions.CAMERA,
function (status) {
status.hasPermission ? startApp() : navigator.app.exitApp();
},
function () {
navigator.app.exitApp();
}
);
}
});
} else {
startApp();
}
});

function initializeApp() {
window.TOKEN = 'fossettscircustoken';
window.eventId = -1;
window.eventDateId = -1;
window.ApiUrl = 'https://staging.fossettscircus.com/boxoffice/index.php/api/';
let scanInProgress = false;
let alertVisible = false;

const scanConfig = {
preferFrontCamera: false,
showFlipCameraButton: true,
showTorchButton: true,
torchOn: false,
saveHistory: false,
prompt: "Place a code inside the scan area",
resultDisplayDuration: 500,
formats: "QR_CODE",
disableAnimations: true,
disableSuccessBeep: false
};

function showAlert(message, title = 'Alert') {
if (alertVisible) return;
alertVisible = true;
f7App.dialog.alert(message, title, () => {
alertVisible = false;
});
}

// Event Details Page
f7App.on('pageInit', function (page) {
if (page.name === 'event-details') {
const query = page.route.query;
const title = query.title || 'No Title';
const location = query.location || '';
const time = query.time || '';
const code = query.code || '';
eventDateId = query.eventDateId || -1;
eventId = query.eventId || -1;

page.$el.find('.event-title').text(title);
page.$el.find('.event-location').text(location);
page.$el.find('.event-time').text(time);
page.$el.find('input[name="code"]').val(code);

function sendCode(code, type) {
f7App.dialog.preloader(type === 'qr' ? 'Scanning code…' : 'Sending code…');
$('.scan').prop('disabled', true);

$.ajax({
url: `${ApiUrl}staff_scan`,
method: 'POST',
data: {
token: TOKEN,
event_date_id: eventDateId,
order_code: code
},
success: function (result) {
const apiResult = JSON.parse(result);
showAlert(apiResult.message, apiResult.result ? 'Scan Success' : 'Scan Failed');
},
error: function () {
showAlert('Something went wrong. Please try again.', 'Scan Failed');
},
complete: function () {
$('.scan').prop('disabled', false);
f7App.dialog.close();
scanInProgress = false;
}
});
}

function scanSuccess(result) {
if (!result.cancelled) {
if (eventDateId > -1) {
sendCode(result.text, 'qr');
} else {
showAlert('You must select an event date to scan tickets', 'Scan Failed');
scanInProgress = false;
}
} else {
showAlert('Scan was cancelled', 'Info');
scanInProgress = false;
}
}

function scanError(error) {
showAlert('Scanning failed: ' + error, 'Scan Failed');
scanInProgress = false;
}

page.$el.on('click', '.scan', function () {
if (scanInProgress) {
showAlert('Scan is already in progress. Please wait.', 'Hold On');
return;
}
scanInProgress = true;
cordova.plugins.barcodeScanner.scan(scanSuccess, scanError, scanConfig);
});
}
});

// Staff Tickets Page
f7App.on('pageInit', function (page) {
if (page.name === 'staff-tickets') {
loadEvents('yes');
page.$el.on('click', '.reload-events-staff', function () {
loadEvents('yes');
});
}
});

// Staff Pay Terminal Page
f7App.on('pageInit', function (page) {
if (page.name === 'staff-pay-terminal') {
page.$el.on('input', '#amountInput', function () {
const amount = parseFloat($(this).val());
const btn = $('#chargeBtn');

if (amount > 0) {
btn.removeClass('disabled:opacity-50').addClass('color-green');
btn.text('Charge €' + amount.toFixed(2));
} else {
btn.addClass('disabled:opacity-50').removeClass('color-green');
btn.text('Charge €0.00');
}
});
}
});
f7App.on('pageInit', function (page) {
if (page.name === 'staff-check-orders') {

function sendCodeAddon(code, type) {
f7App.dialog.preloader(type === 'qr' ? 'Scanning code…' : 'Sending code…');
$('.scan-addon').prop('disabled', true);

$.ajax({
url: `${ApiUrl}staff_scan_addon`,
method: 'POST',
data: {
token: TOKEN,
order_code: code
},
success: function (result) {
const apiResult = JSON.parse(result);
if(apiResult.result){
$('#addonsList').html(
apiResult.addons.map(function(addon) {
return '' + addon + '';
}).join('')
);
}else{
showAlert(apiResult.message, 'Scan Failed');
}
},
error: function () {
showAlert('Something went wrong. Please try again.', 'Scan Failed');
},
complete: function () {
$('.scan-addon').prop('disabled', false);
f7App.dialog.close();
scanInProgress = false;
}
});
}
function scanSuccessAddon(result) {
if (!result.cancelled) {
if (eventDateId > -1) {
sendCodeAddon(result.text, 'qr');
} else {
showAlert('You must select an event date to scan tickets', 'Scan Failed');
scanInProgress = false;
}
} else {
showAlert('Scan was cancelled', 'Info');
scanInProgress = false;
}
}

function scanErrorAddon(error) {
showAlert('Scanning failed: ' + error, 'Scan Failed');
scanInProgress = false;
}
page.$el.on('click', '.scan-addon', function () {
alert("ffafasf");
if (scanInProgress) {
showAlert('Scan is already in progress. Please wait.', 'Hold On');
return;
}
scanInProgress = true;
cordova.plugins.barcodeScanner.scan(scanSuccessAddon, scanErrorAddon, scanConfig);
});
}
});
}

function loadEvents(staff) {
f7App.dialog.preloader('Loading events…');
$.ajax({
url: `${ApiUrl}today`,
method: 'POST',
data: { token: TOKEN },
success: function (result) {
const events = JSON.parse(result);
const $container = $('div.events').html('');
const weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

if (events.result) {
events.data.forEach(val => {
const eventDatetime = new Date(val.event_datetime);
const dateOptions = { year: '2-digit', month: '2-digit', day: '2-digit' };
const timeOptions = { hour12: true, hour: '2-digit', minute: '2-digit' };
const dayname = weekday[eventDatetime.getDay()];
const code = `${val.event_id}.${val.event_date_id}.`;

const html = `

${val.venue_full}
${dayname} at ${eventDatetime.toLocaleDateString('en-GB', dateOptions)} – ${eventDatetime.toLocaleTimeString('en-US', timeOptions)}

0/500

`;

$container.append(html);
});
} else {
$container.html(`${events.message}`);
}
},
error: function () {
f7App.dialog.alert('Something went wrong. Please try again.', 'Error');
},
complete: function () {
f7App.dialog.close();
}
});
}
scan-addon click not working

Assistant
Your `scan-addon` button click is not working most likely due to **one or more of the following** issues:

### ✅ 1. **Missing or incorrect `page.name` in `pageInit`**
You're using this:

if (page.name === 'staff-check-orders') {

But this relies on the presence of:

<div class="page" data-name="staff-check-orders">

### ✅ Fix:
Ensure the `pages/staff-check-orders.html` file contains:

<div class="page" data-name="staff-check-orders">

If not present, `page.name` will be `undefined`, and the `scan-addon` logic won’t bind.

### ✅ 2. **`alert("ffafasf")` is triggered, but nothing else happens**
That confirms the click is firing, but the barcode scanner is not launching. Check:

#### a. **`cordova.plugins.barcodeScanner` is undefined**
This usually happens when:
– Plugin is not installed correctly
– Plugin is used before `deviceready`
– You're testing on the browser (barcode scanner only works on device/emulator)

### ✅ Fix:
Make sure the plugin is installed:

cordova plugin add phonegap-plugin-barcodescanner

And ensure you're testing **on a real device or emulator**, not in a browser.

### ✅ 3. **`scanInProgress` might already be true**
Once `scanInProgress = true`, further clicks are blocked unless it's reset. But if `eventDateId` is not set (i.e. -1), this block may happen:

if (eventDateId > -1) {
  sendCodeAddon(result.text, 'qr');
} else {
  showAlert('You must select an event date to scan tickets', 'Scan Failed');
  scanInProgress = false;
}

So if `eventDateId` is still -1 on that page, scan won't proceed.

### ✅ Fix:
Set a valid `eventDateId` globally or from a field/query before scan:

window.eventDateId = 123; // assign this somewhere before scan is triggered

### ✅ 4. **Wrong selector or missing class**
Check your HTML has a button like:

<button class="scan-addon">Scan Addons</button>

### ✅ 5. **Permissions issue (Android)**
Make sure camera permission is granted before calling scanner.

You're handling this already on `deviceready`, so just make sure it's not skipped due to async errors.

### ✅ Summary of what you should check:

| Check | Solution |
|——-|———-|
| ✅ `data-name="staff-check-orders"` | Ensure in HTML |
| ✅ BarcodeScanner Plugin | Installed and works only on real device |
| ✅ `window.eventDateId` | Set a valid value before scanning |
| ✅ `.scan-addon` element | Must exist and be correctly classed |
| ✅ `cordova.plugins.barcodeScanner` | Confirm defined in `deviceready` |
| ✅ Button clickable | Check CSS/HTML doesn’t disable it |

Let me know if you want to debug with a `console.log()` chain or I can help prepare a minimal working `staff-check-orders.html` file.

User
plugin is already installed and in under page.name === 'event-details' scanner workign fine
Assistant
Thanks for the clarification — since the scanner is working fine under `'event-details'` but **not under `'staff-check-orders'`**, that narrows it down. The problem is **not with the plugin**, but with the **event binding or the page data name**.

Let's troubleshoot in order:

### ✅ 1. **Ensure your page has `data-name="staff-check-orders"`**

In your `pages/staff-check-orders.html`, the top-level “ should look like this:

<div class="page" data-name="staff-check-orders">

> ⚠️ If `data-name` is missing, then `page.name` will be `undefined`, and your `pageInit` condition won't match.

### ✅ 2. **Verify `.scan-addon` button is inside the page**

Make sure your button exists and is inside the `.page` element. For example:

<div class="page" data-name="staff-check-orders">
  ...
  <button class="scan-addon">Scan Addon</button>
</div>

### ✅ 3. **Make sure no early event conflicts are preventing the click handler**

To confirm the `pageInit` is even firing, add a log:

f7App.on('pageInit', function (page) {
  console.log('pageInit:', page.name); // Add this

  if (page.name === 'staff-check-orders') {
    console.log('Staff Check Orders Init'); // And this

> ✅ If **you don’t see this in the console**, your `data-name` is wrong or missing.

### ✅ 4. **Add a failsafe delegated click binding as a backup**

Framework7 sometimes replaces page DOM after init. You can add a fallback listener outside `pageInit`:

$(document).on('click', '.page[data-name="staff-check-orders"] .scan-addon', function () {
  console.log('Delegated scan-addon clicked');
});

This helps test if the button is rendered but missing binding due to timing.

### ✅ 5. **Inspect for typos in the button class or misplaced HTML**

Double-check that:
– Class name is spelled exactly `.scan-addon`
– There’s no duplication or nested `form` preventing default behavior

### 🔍 Final Debug Checklist

| Test | Expectation |
|——|————-|
| `data-name="staff-check-orders"` | ✅ Present |
| `console.log('Staff Check Orders Init')` | ✅ Printed |
| `.scan-addon` button | ✅ Visible and inside page |
| Delegated click via `$(document).on()` | ✅ Fires as backup |
| `eventDateId > -1` | ✅ Set before scanning |

Would you like me to generate a minimal working HTML example for `staff-check-orders.html` with the button and scan logic? That might help confirm.

User
We have event load in framework 7 home page but after app installed event not load first time but it works when I open app second time
Assistant
Thanks for the clear explanation — you're saying:

> ✅ `loadEvents()` works on the Home page normally…
> ❌ But **on first launch after installation**, events don't load
> ✅ When reopening the app later, they **do** load

This is a common issue in **Cordova + Framework7** hybrid apps and is usually caused by **one of the following**:

### ✅ 1. **`loadEvents()` is called before Framework7 view is fully initialized**

You call `loadEvents('yes')` inside this block:

f7App.on('pageInit', function (page) {
  if (page.name === 'staff-tickets') {
    loadEvents('yes');
  }
});

But if `Framework7` hasn’t finished setting up views or routing properly on first launch, that `pageInit` may not trigger as expected.

### ✅ Fix:
Move `loadEvents()` call into `viewDidEnter` or `pageAfterIn` instead of `pageInit`:

f7App.on('pageAfterIn', function (page) {
  if (page.name === 'staff-tickets') {
    loadEvents('yes');
  }
});

or even more reliably:

f7App.views.main.router.on('routeChange', function (newRoute, oldRoute, resolve) {
  if (newRoute.name === 'staff-tickets') {
    loadEvents('yes');
  }
});

### ✅ 2. **Home page not triggering `pageInit` because it's the default route**

Framework7 might not trigger `pageInit` for the home page (`/`) on the **first launch** if it's pre-rendered.

### ✅ Fix:
Manually call `loadEvents()` in `initializeApp()` if the homepage is loaded by default:

function startApp() {
  navigator.splashscreen.hide();
  initializeApp();

  // Manually trigger loadEvents for homepage on first load
  const currentRoute = mainView.router.currentRoute;
  if (currentRoute.path === '/' || currentRoute.name === 'home') {
    loadEvents('yes');
  }
}

Or detect inside `initializeApp()` using:

f7App.on('init', () => {
  const currentPage = f7App.views.main.router.currentPageEl;
  if ($(currentPage).attr('data-name') === 'home') {
    loadEvents('yes');
  }
});

### ✅ 3. **Cordova plugin not ready yet (especially camera/permissions)**

If `loadEvents()` relies on `TOKEN`, `ApiUrl`, or permissions (camera), and those aren’t set until after `deviceready`, then your first call may fail silently.

### ✅ Fix:
Ensure `loadEvents()` only runs after:
– `cordova.platformId` is ready
– Permissions are granted
– All globals like `TOKEN` are set

### ✅ 4. **Splash screen not hidden fast enough, blocking UI rendering**

If `navigator.splashscreen.hide()` is delayed or not called properly, the app looks stuck.

### ✅ Fix:
Move `navigator.splashscreen.hide()` *after* your `loadEvents()` call inside `startApp()`:

function startApp() {
  initializeApp();
  navigator.splashscreen.hide();
}

Or delay splashscreen hide using a short timeout:

function startApp() {
  initializeApp();
  setTimeout(() => navigator.splashscreen.hide(), 500); // Optional
}

### ✅ Recommended Fix Summary

function startApp() {
  initializeApp();

  // Manually load events if home page is loaded first
  const route = mainView.router.currentRoute;
  if (route.path === '/' || route.name === 'home') {
    loadEvents('yes');
  }

  navigator.splashscreen.hide();
}

Would you like me to help you implement a `viewDidEnter` or `pageAfterIn` hook for the home page to ensure `loadEvents()` is always triggered reliably?

User
Page name will be home and url /
Assistant
Perfect — since your home page route is:

{ path: '/', url: 'pages/home.html' }

And **the page has**:

<div class="page" data-name="home">

Then here’s how you can **reliably trigger `loadEvents('yes')`** even on the **first app launch after install**.

### ✅ Final Recommended Fix

Inside your `initializeApp()` function, **add this block** to ensure `loadEvents()` runs if the user lands on the home page right after app install:

f7App.on('pageAfterIn', function (page) {
  if (page.name === 'home') {
    console.log('Home pageAfterIn → calling loadEvents()');
    loadEvents('yes');
  }
});

> `pageAfterIn` is **more reliable than `pageInit`** for the **initial page** because Framework7 sometimes skips `pageInit` for the first rendered page.

### ✅ Optional: Add fallback inside `startApp()` for extra safety

If for some reason the route is already active before the hook above binds:

function startApp() {
  initializeApp();

  // If app starts on home page, load events
  const route = mainView.router.currentRoute;
  if (route.path === '/' || route.name === 'home') {
    console.log('Detected home page on startup → calling loadEvents()');
    loadEvents('yes');
  }

  navigator.splashscreen.hide();
}

### 🔄 Summary

– ✅ Use `pageAfterIn` for consistent behavior when navigating to `/`
– ✅ Use `currentRoute` check in `startApp()` for very first launch fallback
– ✅ Make sure your home page HTML has:

<div class="page" data-name="home">

Let me know if you'd like me to review your `home.html` or enhance the UI while loading events.

Leave a Comment

Your email address will not be published. Required fields are marked *