Implement comprehensive mobile experience framework for entire application

This commit is contained in:
Eric Gullickson
2025-07-27 21:03:06 -05:00
parent f46d471453
commit ea055f1c38
20 changed files with 713 additions and 174 deletions

View File

@@ -1,133 +1,29 @@
// Mobile detection utility
function isMobileDevice() {
return window.matchMedia("(max-width: 768px)").matches ||
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
// Initialize form inputs based on device type
function initializeFormInputs() {
if (isMobileDevice()) {
// Convert date input to native HTML5 on mobile
var dateInput = $('#gasRecordDate');
if (dateInput.length) {
dateInput.attr('type', 'date');
dateInput.removeClass('datepicker'); // Remove Bootstrap datepicker class
}
// Default to simple mode on mobile
var modeToggle = $('#fuelEntryModeToggle');
if (modeToggle.length && !modeToggle.is(':checked')) {
modeToggle.prop('checked', true);
toggleFuelEntryMode(true);
}
// Initialize mobile-friendly tag selector
initMobileTagSelector($("#gasRecordTag"));
} else {
// Use Bootstrap datepicker on desktop
// Initialize gas record modal for mobile (using shared mobile framework)
function initializeGasRecordMobile() {
initMobileModal({
modalId: '#gasRecordModal',
dateInputId: '#gasRecordDate',
tagSelectorId: '#gasRecordTag',
modeToggleId: '#fuelEntryModeToggle',
simpleModeDefault: true
});
// Handle desktop initialization
if (!isMobileDevice()) {
initDatePicker($('#gasRecordDate'));
// Use standard tag selector on desktop
initTagSelector($("#gasRecordTag"));
}
}
// Mobile-optimized tag selector
function initMobileTagSelector(input) {
if (input.length) {
// Initialize with mobile-friendly options
input.tagsinput({
maxTags: 5, // Limit tags on mobile
trimValue: true,
confirmKeys: [13, 44, 32], // Enter, comma, space
focusClass: 'focus',
freeInput: true
});
// Add mobile-specific styling
input.parent().addClass('mobile-tag-input');
// Increase touch target size for mobile
input.parent().find('.bootstrap-tagsinput').css({
'min-height': '44px',
'padding': '8px',
'font-size': '16px' // Prevent zoom on iOS
});
// Style the input within tags
input.parent().find('.bootstrap-tagsinput input').css({
'font-size': '16px',
'min-height': '30px'
});
}
}
// Swipe to dismiss functionality for mobile modals
function initSwipeToDismiss() {
if (!isMobileDevice()) return;
var modal = $('#gasRecordModal');
var modalContent = modal.find('.modal-content');
var startY = 0;
var currentY = 0;
var isDragging = false;
var threshold = 100; // Minimum swipe distance to dismiss
// Touch start
modalContent.on('touchstart', function(e) {
startY = e.originalEvent.touches[0].clientY;
isDragging = true;
modalContent.css('transition', 'none');
});
// Touch move
modalContent.on('touchmove', function(e) {
if (!isDragging) return;
currentY = e.originalEvent.touches[0].clientY;
var deltaY = currentY - startY;
// Only allow downward swipes
if (deltaY > 0) {
modalContent.css('transform', `translateY(${deltaY}px)`);
}
});
// Touch end
modalContent.on('touchend', function(e) {
if (!isDragging) return;
isDragging = false;
var deltaY = currentY - startY;
modalContent.css('transition', 'transform 0.3s ease-out');
if (deltaY > threshold) {
// Dismiss modal
modalContent.css('transform', 'translateY(100%)');
setTimeout(function() {
hideAddGasRecordModal();
modalContent.css('transform', '');
}, 300);
} else {
// Snap back
modalContent.css('transform', '');
}
});
}
function showAddGasRecordModal() {
$.get(`/Vehicle/GetAddGasRecordPartialView?vehicleId=${GetVehicleId().vehicleId}`, function (data) {
if (data) {
$("#gasRecordModalContent").html(data);
// Initialize inputs based on device type
initializeFormInputs();
// Initialize mobile experience using shared framework
initializeGasRecordMobile();
$('#gasRecordModal').modal('show');
// Initialize swipe to dismiss for mobile
initSwipeToDismiss();
}
});
}
@@ -148,15 +44,12 @@ function showEditGasRecordModal(gasRecordId, nocache) {
if (data) {
$("#gasRecordModalContent").html(data);
// Initialize inputs based on device type
initializeFormInputs();
// Initialize mobile experience using shared framework
initializeGasRecordMobile();
$('#gasRecordModal').modal('show');
bindModalInputChanges('gasRecordModal');
// Initialize swipe to dismiss for mobile
initSwipeToDismiss();
$('#gasRecordModal').off('shown.bs.modal').on('shown.bs.modal', function () {
if (getGlobalConfig().useMarkDown) {
toggleMarkDownOverlay("gasRecordNotes");
@@ -569,13 +462,10 @@ function editMultipleGasRecords(ids) {
if (data) {
$("#gasRecordModalContent").html(data);
// Initialize inputs based on device type
initializeFormInputs();
// Initialize mobile experience using shared framework
initializeGasRecordMobile();
$('#gasRecordModal').modal('show');
// Initialize swipe to dismiss for mobile
initSwipeToDismiss();
}
});
}