';
updateResultsContent.innerHTML = resultsHtml;
}
} else {
// Show error message
let errorMessage = 'Error updating inventory.';
if (data.errors && data.errors.length > 0) {
errorMessage += ' ' + data.errors.join(' ');
}
showAlert(inventoryForm, 'danger', errorMessage);
}
})
.catch(error => {
// Reset button state
submitButton.textContent = originalText;
submitButton.disabled = false;
// Show error message
showAlert(inventoryForm, 'danger', `Error: ${error.message}`);
console.error('Error:', error);
});
});
}
/**
* Initialize settings form with validation and AJAX submission
*/
function initSettingsForm() {
const settingsForm = document.getElementById('settings-form');
if (!settingsForm) return;
// Get all inputs
const textInputs = settingsForm.querySelectorAll('input[type="text"]');
const numberInputs = settingsForm.querySelectorAll('input[type="number"]');
// Add event listeners for validation
textInputs.forEach(input => {
input.addEventListener('input', function() {
validateSettingTextInput(this);
});
});
numberInputs.forEach(input => {
input.addEventListener('input', function() {
validateSettingNumberInput(this);
});
});
// Add submit handler
settingsForm.addEventListener('submit', function(e) {
// Validate all inputs before submission
let isValid = true;
textInputs.forEach(input => {
if (!validateSettingTextInput(input)) {
isValid = false;
}
});
numberInputs.forEach(input => {
if (!validateSettingNumberInput(input)) {
isValid = false;
}
});
if (!isValid) {
e.preventDefault();
showAlert(settingsForm, 'danger', 'Please correct the errors in the form before submitting.');
}
});
// Reset to defaults button
const resetButton = document.getElementById('reset-defaults');
if (resetButton) {
resetButton.addEventListener('click', function() {
if (confirm('Are you sure you want to reset all settings to their default values?')) {
window.location.href = '/settings/reset';
}
});
}
}
/**
* Validate a text input for settings
* @param {HTMLInputElement} input - The input to validate
* @returns {boolean} - Whether the input is valid
*/
function validateSettingTextInput(input) {
// Check if value is empty
if (input.value.trim() === '') {
input.classList.add('is-invalid');
showInputError(input, 'This field cannot be empty');
return false;
}
// Input is valid
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}
/**
* Validate a number input for settings
* @param {HTMLInputElement} input - The input to validate
* @returns {boolean} - Whether the input is valid
*/
function validateSettingNumberInput(input) {
const value = parseInt(input.value);
// Check if value is a number
if (isNaN(value)) {
input.classList.add('is-invalid');
showInputError(input, 'Please enter a valid number');
return false;
}
// Check if value is positive
if (value < 1) {
input.classList.add('is-invalid');
showInputError(input, 'Please enter a positive number');
return false;
}
// Input is valid
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}
/**
* Initialize drink type form with validation and AJAX name uniqueness check
*/
function initDrinkTypeForm() {
const drinkTypeForm = document.getElementById('drink-type-form');
if (!drinkTypeForm) return;
// Get form inputs
const nameInput = drinkTypeForm.querySelector('input[name="name"]');
const descriptionInput = drinkTypeForm.querySelector('textarea[name="description"]');
const desiredStockInput = drinkTypeForm.querySelector('input[name="desired_stock"]');
// Store original name for edit mode
const originalName = nameInput ? nameInput.value : '';
// Add validation for name input
if (nameInput) {
nameInput.addEventListener('input', function() {
validateDrinkTypeName(this, originalName);
});
// Check name uniqueness on blur
nameInput.addEventListener('blur', function() {
checkDrinkTypeNameUniqueness(this, originalName);
});
}
// Add validation for desired stock input
if (desiredStockInput) {
desiredStockInput.addEventListener('input', function() {
validateDesiredStock(this);
});
}
// Add form submission handler
drinkTypeForm.addEventListener('submit', function(e) {
let isValid = true;
// Validate name
if (nameInput && !validateDrinkTypeName(nameInput, originalName)) {
isValid = false;
}
// Validate desired stock
if (desiredStockInput && !validateDesiredStock(desiredStockInput)) {
isValid = false;
}
if (!isValid) {
e.preventDefault();
showAlert(drinkTypeForm, 'danger', 'Please correct the errors in the form before submitting.');
}
});
}
/**
* Validate a drink type name
* @param {HTMLInputElement} input - The input to validate
* @param {string} originalName - The original name (for edit mode)
* @returns {boolean} - Whether the input is valid
*/
function validateDrinkTypeName(input, originalName) {
const value = input.value.trim();
// Check if value is empty
if (value === '') {
input.classList.add('is-invalid');
showInputError(input, 'Name is required');
return false;
}
// Check if value is too long
if (value.length > 255) {
input.classList.add('is-invalid');
showInputError(input, 'Name cannot be longer than 255 characters');
return false;
}
// Input is valid
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}
/**
* Check if a drink type name is unique
* @param {HTMLInputElement} input - The input to check
* @param {string} originalName - The original name (for edit mode)
*/
function checkDrinkTypeNameUniqueness(input, originalName) {
const value = input.value.trim();
// Skip check if name hasn't changed or is empty
if (value === '' || value === originalName) {
return;
}
// Show loading state
input.classList.add('is-loading');
// Check if name already exists
fetch(`/api/drink-types/check-name?name=${encodeURIComponent(value)}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Remove loading state
input.classList.remove('is-loading');
if (data.exists) {
input.classList.add('is-invalid');
showInputError(input, 'A drink type with this name already exists');
}
})
.catch(error => {
// Remove loading state
input.classList.remove('is-loading');
console.error('Error checking name uniqueness:', error);
});
}
/**
* Validate a desired stock input
* @param {HTMLInputElement} input - The input to validate
* @returns {boolean} - Whether the input is valid
*/
function validateDesiredStock(input) {
const value = parseInt(input.value);
// Check if value is a number
if (isNaN(value)) {
input.classList.add('is-invalid');
showInputError(input, 'Desired stock must be a number');
return false;
}
// Check if value is non-negative
if (value < 0) {
input.classList.add('is-invalid');
showInputError(input, 'Desired stock cannot be negative');
return false;
}
// Input is valid
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}