Onsen UI Conversion Guide
August 7, 2025 · AI Conversations
Door Staff
Check tickets and manage show entry
Access Door System
Customer
Scan tickets or view upcoming events
Continue as Customer
Staff Login
Login
← Back
Reload Events
Logout
Scan result
×
No scans yet
Scan Next
or
Set Code Manually
<script>
</script>
<script>
</script>
<script>
</script>
<script>
</script>
<script>
</script>
convert above to onsenui layout
1. Replace Bootstrap layout components with Onsen UI's “, “, “, “, and “.
2. Replace `.container`, `.row`, and `.col-*` grid with Onsen's “ and “.
3. Adjust modal and form styles to Onsen UI components.
—
Here is a **converted version using Onsen UI components**:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width" />
<link rel="stylesheet" href="css/onsenui.css">
<link rel="stylesheet" href="css/onsen-css-components.min.css">
<link rel="stylesheet" href="css/index.css" />
<script src="js/onsenui.min.js"></script>
<title>Fossettscircus Scanner</title>
</head>
<body>
<ons-page id="access-choice-screen">
<ons-toolbar>
<div class="center">Fossettscircus</div>
</ons-toolbar>
<div class="content">
<ons-row class="access-choice">
<ons-col width="50%" class="text-center">
<ons-card>
<div class="title">Door Staff</div>
<div class="content">
<p>Check tickets and manage show entry</p>
<ons-button modifier="large" id="staff-access" class="button--cta">Access Door System</ons-button>
</div>
</ons-card>
</ons-col>
<ons-col width="50%" class="text-center">
<ons-card>
<div class="title">Customer</div>
<div class="content">
<p>Scan tickets or view upcoming events</p>
<ons-button modifier="large" id="customer-access" class="button--cta">Continue as Customer</ons-button>
</div>
</ons-card>
</ons-col>
</ons-row>
</div>
</ons-page>
<ons-page id="staff-login-screen" class="d-none">
<ons-toolbar>
<div class="left">
<ons-back-button>Back</ons-back-button>
</div>
<div class="center">Staff Login</div>
</ons-toolbar>
<div class="content">
<ons-card>
<form id="staff-login-form">
<ons-input modifier="underbar" type="email" id="staff-email" placeholder="Email" float></ons-input><br>
<ons-input modifier="underbar" type="password" id="staff-password" placeholder="Password" float></ons-input><br><br>
<ons-button modifier="large" type="submit">Login</ons-button>
</form>
</ons-card>
</div>
</ons-page>
<ons-page id="customer-screen" class="d-none">
<ons-toolbar>
<div class="center">Customer View</div>
</ons-toolbar>
<div class="content">
<img src="img/logo.png" class="img-responsive" alt="logo" style="width: 60%; margin: auto; display: block;">
<ons-button modifier="large" class="reload-events">Reload Events</ons-button>
<ons-list class="events"></ons-list>
</div>
</ons-page>
<ons-page id="staff-screen" class="d-none">
<ons-toolbar>
<div class="center">Staff Panel</div>
</ons-toolbar>
<div class="content">
<img src="img/logo.png" class="img-responsive" alt="logo" style="width: 60%; margin: auto; display: block;">
<ons-button modifier="large" class="logout-staff">Logout</ons-button>
<ons-list class="events"></ons-list>
</div>
</ons-page>
<ons-dialog id="modal-scan-result">
<div class="content">
<p id="scan-info" class="text-center bg-primary text-white p-2">Scan Info</p>
<p id="scan-result" class="text-center bg-dark text-white p-2">No scans yet</p>
<ons-button class="scan" modifier="large">Scan Next</ons-button>
<div class="text-center my-3" style="border-bottom: 1px solid #000; line-height: 0.1em;">
<span class="bg-white px-2">or</span>
</div>
<ons-input type="text" placeholder="Code" class="mb-2" name="code"></ons-input>
<ons-button class="manually" modifier="large">Set Code Manually</ons-button>
</div>
</ons-dialog>
<script src="cordova.js"></script>
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
—
### Key Notes:
– You can toggle pages (`ons-page`) via JavaScript using:
document.getElementById('access-choice-screen').hidden = true;
document.getElementById('staff-login-screen').hidden = false;
– For routing, you may use `ons-navigator` if your app grows.
– Add `ons-modal` or `ons-alert-dialog` for richer modal interactions.
Would you like me to add the JavaScript logic (`index.js`) to toggle between these screens?
if (cordova.platformId === 'android') {
var permissions = cordova.plugins.permissions;
permissions.checkPermission(permissions.CAMERA, function (status) {
if (!status.hasPermission) {
// Request permission
permissions.requestPermission(
permissions.CAMERA,
function (status) {
if (status.hasPermission) {
navigator.splashscreen.hide(); // Hide splash after permission
initializeApp(); // Proceed with your app
} else {
navigator.app.exitApp(); // Exit if denied
}
},
function () {
navigator.app.exitApp(); // Exit on request error
}
);
} else {
navigator.splashscreen.hide();
initializeApp(); // Permission already granted
}
});
} else {
navigator.splashscreen.hide(); // For browser/iOS fallback
initializeApp();
}
}, false);
function initializeApp() {
let TOKEN = 'fossettscircustoken';
$(document).ready(function()
{
// $('ons-button').on('click', function(e) {
// ons.notification.alert('Button is tapped!');
// })
// Customer Access
$('#customer-access').on('click', function () {
$('.access-choice-screen').hide();
$('.customer-screen').removeClass('d-none');
localStorage.setItem('access_type', 'customer');
});
// Handle Staff Access Click
$('#staff-access').on('click', function () {
$('.access-choice-screen').hide();
if (localStorage.getItem('staff_token') === 'stafftoken') {
$('.staff-login-screen').addClass('d-none');
$('.staff-screen').removeClass('d-none');
} else {
$('.staff-login-screen').removeClass('d-none');
$('.staff-screen').addClass('d-none');
}
});
// Handle Back Button
$('#back-to-access').on('click', function () {
$('.staff-login-screen').addClass('d-none');
$('.access-choice-screen').show();
});
var eventId = -1;
var eventDateId = -1;
let ApiUrl = 'https://staging.fossettscircus.com/boxoffice/index.php/api/';
let loader=`
Loading…
`;
var scanConfig = {
preferFrontCamera : false, // iOS and Android
showFlipCameraButton : true, // iOS and Android
showTorchButton : true, // iOS and Android
torchOn: false, // Android, launch with the torch switched on (if available)
saveHistory: false, // Android, save scan history (default false)
prompt : "Place a code inside the scan area", // Android
resultDisplayDuration: 500, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
formats : "QR_CODE", // default: all but PDF_417 and RSS_EXPANDED
//orientation : "landscape", // Android only (portrait|landscape), default unset so it rotates with the device
disableAnimations : true, // iOS
disableSuccessBeep: false // iOS and Android
};
var sendCode = function(code)
{
$('.scan').prop('disabled', true);
$('.manually').prop('disabled', true);
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html('Code '+ code +' sent to boxoffice, plase wait…');
$.ajax({
url: `${ApiUrl}scan`,
method: 'POST',
data: {
token: TOKEN,
event_date_id: eventDateId,
order_code: code
},
success: function(result,status,xhr)
{
var apiResult = JSON.parse(result);
if ( apiResult.result )
{
$('#scan-result').removeClass('bg-dark').addClass('bg-success').html(apiResult.message+''+apiResult.seating+''+apiResult.tickets);
// reset input to set next code
$('[name="code"]').val(eventId +'.'+ eventDateId +'.');
}
else
{
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html(apiResult.message);
}
},
error: function(xhr,status,error)
{
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html('Code '+ result.text +' could not be sent to boxoffice, please try again');
},
complete: function()
{
$('.scan').prop('disabled', false);
$('.manually').prop('disabled', false);
}
});
}
var scanError = function (error)
{
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html("Scanning failed: " + error);
$('#modal-scan-result').modal('show');
};
var scanSuccess = function(result)
{
if (! result.cancelled )
{
if (eventDateId > -1)
{
sendCode(result.text);
}
else
{
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html('You must select an event date to scan tickets');
}
}
else
{
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html('Scan was cancelled');
}
$('#modal-scan-result').modal('show');
};
$(document).on('click', '.reload-events', function()
{
$('ul.events').html(loader);
$.ajax({
url: `${ApiUrl}today`,
method: 'POST',
data: {
token: TOKEN
},
success: function(result,status,xhr)
{
console.log(result);
var events = JSON.parse(result);
if (events.result) {
$('.customer-screen ul.events').html('');
$('.staff-screen ul.events').html('');
const weekday = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
$.each(events.data, function(i, val)
{
var eventDatetime = new Date(val.event_datetime);
var dateOptions = { year: '2-digit', month: '2-digit', day: '2-digit' };
var timeOptions = { hour12: true, hour: '2-digit', minute: '2-digit' };
var dayname=weekday[eventDatetime.getDay()];
$('.customer-screen ul.events').append(`${eventDatetime.toLocaleDateString('en-GB', dateOptions)} – ${eventDatetime.toLocaleTimeString('en-US', timeOptions)} ${dayname} – ${val.venue_full}`);
$('.staff-screen ul.events').append(`${eventDatetime.toLocaleDateString('en-GB', dateOptions)} – ${eventDatetime.toLocaleTimeString('en-US', timeOptions)} ${dayname} – ${val.venue_full}Collect Payment`);
});
}else{
$('.events').html(`${events.message}`);
}
},
error: function(xhr,status,error)
{
console.log(error);
}
});
});
// load events click
$('.reload-events').trigger('click');
$(document).on('click', '.customer-screen .events .list-group-item', function()
{
$('.customer-screen .events .list-group-item').removeClass('active');
$(this).addClass('active');
$('#scan-info').html($(this).html());
eventId = $(this).attr('data-event-id');
eventDateId = $(this).attr('data-event-date-id');
$('[name="code"]').val(eventId +'.'+ eventDateId +'.');
// first scan on event date click
//cordova.plugins.barcodeScanner.scan(scanSuccess, scanError, scanConfig);
$('#modal-scan-result').modal('show');
});
$(document).on('click', '.scan', function()
{
cordova.plugins.barcodeScanner.scan(scanSuccess, scanError, scanConfig);
});
$(document).on('click', '.manually', function()
{
sendCode($('[name="code"]').val());
});
//Staff Login
$(document).on('submit', '#staff-login-form', function(e)
{
$("#login-result").html(loader);
e.preventDefault();
var email = $('#staff-email').val();
var password = $('#staff-password').val();
$.ajax({
url: `${ApiUrl}staff_login`,
method: 'POST',
data: {
token: TOKEN,
email: email,
password: password
},
success: function(result,status,xhr)
{
var apiResult = JSON.parse(result);
if ( apiResult.result )
{
localStorage.setItem('staff_token', apiResult.token);
$('.staff-login-screen').addClass('d-none');
$('.staff-screen').removeClass('d-none');
localStorage.setItem('access_type', 'staff');
}
else
{
$('#login-result').removeClass('bg-success').addClass('bg-danger').html(apiResult.message);
}
},
error: function(xhr,status,error)
{
console.log(error);
}
});
});
$(document).on('click', '.logout-staff', function()
{
ons.notification.alert('You have been logged out');
localStorage.removeItem('staff_token');
localStorage.removeItem('access_type');
$('.staff-screen').addClass('d-none');
$('.staff-login-screen').addClass('d-none');
$('.customer-screen').addClass('d-none');
$('.access-choice-screen').show();
});
});
}
Now convert above according onsen ui
### ✅ Key Adjustments:
– `.hide()`/`.show()` and Bootstrap `d-none` replaced with `ons-navigator.pushPage()` and `hidden` property.
– Replaced Bootstrap modals with `ons-dialog`.
– Used `ons.notification.alert()` where appropriate.
—
### ✅ Modified JS for Onsen UI (include in `index.js`):
function initializeApp() {
let TOKEN = 'fossettscircustoken';
let eventId = -1;
let eventDateId = -1;
const ApiUrl = 'https://staging.fossettscircus.com/boxoffice/index.php/api/';
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 () {
const showPage = (id) => {
$('ons-page').each(function () {
this.hidden = true;
});
$(id)[0].hidden = false;
};
// Staff Access
$('#staff-access').on('click', () => {
if (localStorage.getItem('staff_token') === 'stafftoken') {
showPage('#staff-screen');
} else {
showPage('#staff-login-screen');
}
});
$('#back-to-access').on('click', () => {
showPage('#access-choice-screen');
});
// Customer Access
$('#customer-access').on('click', () => {
localStorage.setItem('access_type', 'customer');
showPage('#customer-screen');
});
// Load Events
$('.reload-events').on('click', () => {
const loader = `<ons-list-item class="text-center">Loading...</ons-list-item>`;
$('ul.events').html(loader);
$.post(`${ApiUrl}today`, { token: TOKEN }, function (res) {
const events = JSON.parse(res);
const $custList = $('.customer-screen ul.events');
const $staffList = $('.staff-screen ul.events');
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
$custList.empty();
$staffList.empty();
if (events.result) {
events.data.forEach(val => {
const dt = new Date(val.event_datetime);
const day = days[dt.getDay()];
const date = dt.toLocaleDateString('en-GB');
const time = dt.toLocaleTimeString('en-US');
const text = `${date} - ${time} ${day} - ${val.venue_full}`;
const item = `<ons-list-item tappable data-event-id="${val.event_id}" data-event-date-id="${val.event_date_id}">${text}</ons-list-item>`;
$custList.append(item);
$staffList.append(`<ons-list-item modifier="chevron" tappable data-event-id="${val.event_id}" data-event-date-id="${val.event_date_id}">${text} <ons-button modifier="quiet" class="collect-payment">Collect Payment</ons-button></ons-list-item>`);
});
} else {
$('ul.events').html(`<ons-list-item class="text-center bg-info text-white">${events.message}</ons-list-item>`);
}
});
}).trigger('click');
// Select Event for Scan
$(document).on('click', '.customer-screen ons-list-item', function () {
$('.customer-screen ons-list-item').removeClass('active');
$(this).addClass('active');
eventId = $(this).data('event-id');
eventDateId = $(this).data('event-date-id');
$('#scan-info').html($(this).text());
$('[name="code"]').val(eventId + '.' + eventDateId + '.');
document.querySelector('#modal-scan-result').show();
});
$('.scan').on('click', () => {
cordova.plugins.barcodeScanner.scan(scanSuccess, scanError, scanConfig);
});
$('.manually').on('click', () => {
sendCode($('[name="code"]').val());
});
// Staff Login
$('#staff-login-form').on('submit', function (e) {
e.preventDefault();
$("#login-result").html('Logging in...');
const email = $('#staff-email').val();
const password = $('#staff-password').val();
$.post(`${ApiUrl}staff_login`, { token: TOKEN, email, password }, function (res) {
const result = JSON.parse(res);
if (result.result) {
localStorage.setItem('staff_token', result.token);
localStorage.setItem('access_type', 'staff');
showPage('#staff-screen');
} else {
$("#login-result").html(`<ons-alert-dialog> <div class="alert-dialog-content">${result.message}</div> </ons-alert-dialog>`);
}
});
});
$('.logout-staff').on('click', () => {
ons.notification.alert('You have been logged out');
localStorage.clear();
showPage('#access-choice-screen');
});
function sendCode(code) {
$('.scan, .manually').prop('disabled', true);
$('#scan-result').removeClass('bg-success').addClass('bg-dark').html(`Sending code: <u>${code}</u>`);
$.post(`${ApiUrl}scan`, { token: TOKEN, event_date_id: eventDateId, order_code: code }, function (res) {
const apiResult = JSON.parse(res);
$('#scan-result')
.removeClass('bg-dark bg-success')
.addClass(apiResult.result ? 'bg-success' : 'bg-dark')
.html(`${apiResult.message}<br>${apiResult.seating || ''}<br>${apiResult.tickets || ''}`);
$('[name="code"]').val(eventId + '.' + eventDateId + '.');
}).fail(() => {
$('#scan-result').html(`Code <u>${code}</u> could not be sent`);
}).always(() => {
$('.scan, .manually').prop('disabled', false);
});
}
function scanSuccess(result) {
if (!result.cancelled) {
if (eventDateId > -1) {
sendCode(result.text);
} else {
$('#scan-result').html('Select an event date before scanning');
}
} else {
$('#scan-result').html('Scan was cancelled');
}
document.querySelector('#modal-scan-result').show();
}
function scanError(error) {
$('#scan-result').html("Scan failed: " + error);
document.querySelector('#modal-scan-result').show();
}
});
}
—
### 🧩 What’s Next?
– Make sure `#modal-scan-result` is an “ and *not* Bootstrap.
– Make sure pages like `#access-choice-screen`, `#staff-screen`, etc., are wrapped in “ and have `hidden` attribute by default except the first.
Let me know if you want me to update the full HTML as well to reflect these `ons-page` IDs and dialog setup.