571 lines
26 KiB
PHP
571 lines
26 KiB
PHP
<?= $this->extend('layout/register_layout') ?>
|
||
<?= $this->section('content') ?>
|
||
<div class="registration-form container mt-5 mb-5">
|
||
<?php $errors = session()->getFlashdata('errors') ?? []; ?>
|
||
<?php $captcha_error = session()->getFlashdata('captcha_error') ?? ''; ?>
|
||
|
||
<form action="<?= base_url('/register') ?>" method="post" id="registrationForm">
|
||
<?= csrf_field() ?>
|
||
<?php if (session()->getFlashdata('error')): ?>
|
||
<div class="alert alert-danger" role="alert">
|
||
<?= session()->getFlashdata('error') ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php if (session()->getFlashdata('top_error')): ?>
|
||
<div class="alert alert-danger text-center">
|
||
<?= esc(session()->getFlashdata('top_error')) ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="text-center mb-4">
|
||
<a href="<?= base_url('/') ?>">
|
||
<img src="<?= base_url('assets/images/alrahma_logo.png') ?>" alt=""
|
||
style="width: 120px; height: 120px; border-radius: 50%; object-fit: cover;">
|
||
</a>
|
||
</div>
|
||
|
||
<h3 class="text-center text-success" style="font-family: Arial, sans-serif;">Registration Form</h3>
|
||
<div class="alert alert-info" role="alert">
|
||
- This account is for parents/guardians to manage students. If you already registered in a prior year, please reuse your existing account.<br>
|
||
- If you cannot access your old email, reset your password.
|
||
</div>
|
||
<p class="text-center text-secondary mt-3 mb-2">
|
||
(All fields with * are required)
|
||
</p>
|
||
<br>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="firstname" name="firstname" placeholder="First Name*"
|
||
maxlength="50" required value="<?= old('firstname') ?>">
|
||
<div class="form-text text-muted d-none" id="firstname-hint">2–30 characters. Letters, spaces, and hyphens only.</div>
|
||
<?php if (isset($errors['firstname'])): ?>
|
||
<div class="text-danger"><?= $errors['firstname'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="lastname" name="lastname" placeholder="Last Name*"
|
||
maxlength="50" required value="<?= old('lastname') ?>">
|
||
<div class="form-text text-muted d-none" id="lastname-hint">2–30 characters. Letters, spaces, and hyphens only.</div>
|
||
<?php if (isset($errors['lastname'])): ?>
|
||
<div class="text-danger"><?= $errors['lastname'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<select id="gender" name="gender" class="form-select item" required>
|
||
<option value="" disabled selected>Select Gender*</option>
|
||
<option value="Male" <?= old('gender') == 'Male' ? 'selected' : '' ?>>Male</option>
|
||
<option value="Female" <?= old('gender') == 'Female' ? 'selected' : '' ?>>Female</option>
|
||
</select>
|
||
<?php if (isset($errors['gender'])): ?>
|
||
<div class="text-danger"><?= $errors['gender'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="tel"
|
||
class="form-control item"
|
||
id="cellphone"
|
||
name="cellphone"
|
||
placeholder="Phone - Cell*"
|
||
maxlength="12"
|
||
required
|
||
title="Enter a valid 10-digit phone number (e.g., 123-456-7890)"
|
||
value="<?= old('cellphone') ?>">
|
||
|
||
<div class="form-text text-muted d-none" id="cellphone-hint">10-digit US phone number required.</div>
|
||
|
||
<?php if (isset($errors['cellphone'])): ?>
|
||
<div class="text-danger"><?= $errors['cellphone'] ?></div>
|
||
<?php endif; ?>
|
||
|
||
<div id="cellphone-error" class="text-danger"></div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="email" class="form-control item" id="email" name="email" placeholder="Email*"
|
||
maxlength="50" required value="<?= old('email') ?>">
|
||
<div class="form-text text-muted d-none" id="email-hint">Valid format (e.g. user@example.com), max 50 characters.</div>
|
||
<?php if (isset($errors['email'])): ?>
|
||
<div class="text-danger"><?= $errors['email'] ?></div>
|
||
<?php endif; ?>
|
||
<div id="email-error" class="text-danger"></div>
|
||
</div>
|
||
|
||
<div class="mb-3 position-relative">
|
||
<input type="email" class="form-control item" id="confirm_email" name="confirm_email"
|
||
placeholder="Confirm Email*" maxlength="50" required
|
||
value="<?= old('confirm_email') ?>"
|
||
onpaste="return false;" oncopy="return false;" oncut="return false;"
|
||
title="Copy/paste is disabled for accuracy">
|
||
<div class="form-text text-muted d-none" id="confirm_email-hint">Must match the email field. Copy/paste disabled.</div>
|
||
<?php if (isset($errors['confirm_email'])): ?>
|
||
<div class="text-danger"><?= $errors['confirm_email'] ?></div>
|
||
<?php endif; ?>
|
||
<div id="confirm-email-error" class="text-danger"></div>
|
||
<div class="invalid-feedback d-none" id="copy-warning-email">
|
||
Copy/paste is disabled for this field.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="address_street" name="address_street"
|
||
placeholder="Address - Street*" maxlength="50" required value="<?= old('address_street') ?>">
|
||
<div class="form-text text-muted d-none" id="address_street-hint">2–30 characters. Letters, digits, spaces, hyphens allowed.</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="apt" name="apt" placeholder="Apt" maxlength="15"
|
||
value="<?= old('apt') ?>">
|
||
<div class="form-text text-muted d-none" id="apt-hint">Optional. Max 15 characters.</div>
|
||
<div id="apt-error" class="text-danger small"></div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="city" name="city" placeholder="City*" maxlength="15"
|
||
required value="<?= old('city') ?>">
|
||
<div class="form-text text-muted d-none" id="city-hint">2–15 characters. Letters and spaces allowed.</div>
|
||
<?php if (isset($errors['city'])): ?>
|
||
<div class="text-danger"><?= $errors['city'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<select id="state" name="state" class="form-select item" required>
|
||
<option value="" disabled selected>Select State*</option>
|
||
<?php
|
||
$states = [
|
||
'CT' => 'Connecticut',
|
||
'ME' => 'Maine',
|
||
'MA' => 'Massachusetts',
|
||
'NH' => 'New Hampshire',
|
||
'NY' => 'New York',
|
||
'RI' => 'Rhode Island',
|
||
'VT' => 'Vermont'
|
||
];
|
||
foreach ($states as $abbr => $name): ?>
|
||
<option value="<?= $abbr ?>" <?= old('state') == $abbr ? 'selected' : '' ?>><?= $name ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<?php if (isset($errors['state'])): ?>
|
||
<div class="text-danger"><?= $errors['state'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="zip" name="zip" placeholder="Zip*" maxlength="5"
|
||
pattern="\d{5}" title="Please enter a 5-digit zip code" inputmode="numeric" required
|
||
value="<?= old('zip') ?>">
|
||
<div class="form-text text-muted d-none" id="zip-hint">5-digit US ZIP code only.</div>
|
||
<?php if (isset($errors['zip'])): ?>
|
||
<div class="text-danger"><?= $errors['zip'] ?></div>
|
||
<?php endif; ?>
|
||
<div id="zip-error" class="text-danger"></div>
|
||
</div>
|
||
|
||
<!-- Parent/Guardian Checkbox -->
|
||
<div class="form-check mb-3">
|
||
<input class="form-check-input" type="checkbox" value="1" id="is_parent" name="is_parent" <?= old('is_parent') ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="is_parent">
|
||
Check this box if you are a Parent/Guardian
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Second Parent Info Section -->
|
||
<div id="second-parent-section" style="display: none; border: 1px solid #ccc; padding: 15px; margin-top: 10px; border-radius: 5px;">
|
||
<h6>Second Parent/Guardian Information</h6>
|
||
|
||
<div class="form-check form-switch mb-3">
|
||
<input class="form-check-input" type="checkbox" value="1"
|
||
id="no_second_parent_info" name="no_second_parent_info"
|
||
<?= old('no_second_parent_info') ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="no_second_parent_info">
|
||
Check this box if no second parent info is available
|
||
</label>
|
||
</div>
|
||
|
||
<div class="row" id="second-parent-fields">
|
||
<!-- First Name -->
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="second_firstname" name="second_firstname"
|
||
placeholder="First Name*" maxlength="50" value="<?= old('second_firstname') ?>">
|
||
<div class="form-text text-muted d-none" id="second_firstname-hint">2–30 characters. Letters, spaces, and hyphens only.</div>
|
||
<?php if (isset($errors['second_firstname'])): ?>
|
||
<div class="text-danger"><?= $errors['second_firstname'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Last Name -->
|
||
<div class="mb-3">
|
||
<input type="text" class="form-control item" id="second_lastname" name="second_lastname"
|
||
placeholder="Last Name*" maxlength="50" value="<?= old('second_lastname') ?>">
|
||
<div class="form-text text-muted d-none" id="second_lastname-hint">2–30 characters. Letters, spaces, and hyphens only.</div>
|
||
<?php if (isset($errors['second_lastname'])): ?>
|
||
<div class="text-danger"><?= $errors['second_lastname'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<select id="second_gender" name="second_gender" class="form-select item">
|
||
<option value="" disabled selected>Select Gender*</option>
|
||
<option value="Male" <?= old('second_gender') == 'Male' ? 'selected' : '' ?>>Male</option>
|
||
<option value="Female" <?= old('second_gender') == 'Female' ? 'selected' : '' ?>>Female</option>
|
||
</select>
|
||
<?php if (isset($errors['second_gender'])): ?>
|
||
<div class="text-danger"><?= $errors['second_gender'] ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="mb-3">
|
||
<input type="email" class="form-control item" id="second_email" name="second_email" placeholder="Email*"
|
||
maxlength="50" value="<?= old('second_email') ?>">
|
||
<div class="form-text text-muted d-none" id="second_email-hint">Valid format (e.g. user@example.com), max 50 characters.</div>
|
||
<?php if (isset($errors['second_email'])): ?>
|
||
<div class="text-danger"><?= $errors['second_email'] ?></div>
|
||
<?php endif; ?>
|
||
<div id="second_email-error" class="text-danger"></div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<input type="text"
|
||
class="form-control item"
|
||
id="second_cellphone"
|
||
name="second_cellphone"
|
||
placeholder="Phone - Cell*"
|
||
maxlength="12"
|
||
title="Enter a valid 10-digit phone number (e.g., 123-456-7890"
|
||
value="<?= old('second_cellphone') ?>">
|
||
|
||
<div class="form-text text-muted d-none" id="second_cellphone-hint">10-digit US phone number required.</div>
|
||
|
||
<?php if (isset($errors['second_cellphone'])): ?>
|
||
<div class="text-danger"><?= $errors['second_cellphone'] ?></div>
|
||
<?php endif; ?>
|
||
|
||
<div id="second_cellphone-error" class="text-danger"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<br>
|
||
<div class="form-check mb-3">
|
||
<input class="form-check-input" type="checkbox" value="1" id="accept_school_policy"
|
||
name="accept_school_policy" required <?= old('accept_school_policy') ? 'checked' : '' ?>>
|
||
<label class="form-check-label mb-3 policy-label" for="accept_school_policy">
|
||
I have read and I accept all school policies
|
||
<!-- Use a button, not an <a>; keep it OUTSIDE the label -->
|
||
<button type="button" class="btn btn-link p-0 small text-success" id="openPolicyLink">
|
||
(Read school policies here)
|
||
</button>
|
||
</label>
|
||
</div>
|
||
<div class="mb-3">
|
||
<div class="text-center border p-2 bg-light item">
|
||
<?= strip_tags($captchaQuestion) ?>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3 position-relative">
|
||
<input type="text"
|
||
class="form-control item <?= isset($errors['captcha']) ? 'is-invalid' : '' ?>"
|
||
id="captcha"
|
||
name="captcha"
|
||
placeholder="Enter the text above*"
|
||
maxlength="8"
|
||
autocomplete="off"
|
||
required
|
||
onpaste="return false;" oncopy="return false;" oncut="return false;"
|
||
title="Copy/paste is disabled for accuracy">
|
||
|
||
<!-- JS-based warning -->
|
||
<div id="captcha-warning" class="invalid-feedback d-none">
|
||
⚠️ Copying and pasting is disabled. Please manually type the answer.
|
||
</div>
|
||
|
||
<!-- Server-side error -->
|
||
<?php if (isset($errors['captcha'])): ?>
|
||
<div class="invalid-feedback d-block"><?= esc($errors['captcha']) ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="mb-3 d-grid">
|
||
<button type="submit" class="btn btn-success item">Create Account</button>
|
||
<a href="/" class="btn btn-secondary item">Back to Home</a>
|
||
</div>
|
||
</form>
|
||
|
||
<!-- Policy Modal -->
|
||
<div class="modal fade" id="policyModal" tabindex="-1" aria-labelledby="policyModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title text-success" id="policyModalLabel">School Policies</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<iframe src="<?= base_url('policy/school_policy') ?>" width="100%" height="400" frameborder="0"></iframe>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<?= $this->endSection() ?>
|
||
|
||
<?= $this->section('scripts') ?>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// ---- Elements ----
|
||
const form = document.getElementById('registrationForm');
|
||
|
||
const isParentCheckbox = document.getElementById('is_parent');
|
||
const secondParentSection = document.getElementById('second-parent-section');
|
||
const noSecondParentCheckbox = document.getElementById('no_second_parent_info');
|
||
const secondParentFieldsWrapper = document.getElementById('second-parent-fields');
|
||
|
||
// Policy button: open modal via JS only (no data attributes, no href)
|
||
const policyBtn = document.getElementById('openPolicyLink');
|
||
if (policyBtn) {
|
||
['click', 'mousedown', 'mouseup'].forEach(evt =>
|
||
policyBtn.addEventListener(evt, ev => {
|
||
ev.preventDefault();
|
||
ev.stopPropagation();
|
||
})
|
||
);
|
||
policyBtn.addEventListener('click', function() {
|
||
const modalEl = document.getElementById('policyModal');
|
||
if (modalEl && typeof bootstrap !== 'undefined' && bootstrap.Modal) {
|
||
new bootstrap.Modal(modalEl).show();
|
||
}
|
||
});
|
||
}
|
||
|
||
// Second-parent inputs we consider "required" when applicable
|
||
const secondRequiredIds = ['second_firstname', 'second_lastname', 'second_email', 'second_cellphone'];
|
||
const secondRequiredEls = secondRequiredIds.map(id => document.getElementById(id)).filter(Boolean);
|
||
|
||
// Phone inputs (yours + second parent)
|
||
const phoneInputs = document.querySelectorAll('input[type="tel"], #cellphone, #second_cellphone');
|
||
|
||
// ---- Helpers ----
|
||
function setSecondParentFieldsRequired(enable) {
|
||
secondRequiredEls.forEach(el => {
|
||
if (!el) return;
|
||
if (enable) {
|
||
el.setAttribute('required', 'required');
|
||
el.classList.add('second-required');
|
||
} else {
|
||
el.removeAttribute('required');
|
||
el.classList.remove('second-required');
|
||
el.classList.remove('is-invalid');
|
||
}
|
||
});
|
||
}
|
||
|
||
function enableDisableSecondParentFields(disable) {
|
||
const inputs = secondParentFieldsWrapper ? secondParentFieldsWrapper.querySelectorAll('input, select') : [];
|
||
inputs.forEach(el => {
|
||
el.disabled = disable;
|
||
if (disable) el.classList.remove('is-invalid');
|
||
});
|
||
}
|
||
|
||
function clearSecondParentFields() {
|
||
if (!secondParentFieldsWrapper) return;
|
||
secondParentFieldsWrapper.querySelectorAll('input').forEach(el => {
|
||
el.value = '';
|
||
});
|
||
// Clear inline error text if present
|
||
const errIds = ['second_cellphone-error', 'second_email-error'];
|
||
errIds.forEach(id => {
|
||
const e = document.getElementById(id);
|
||
if (e) e.textContent = '';
|
||
});
|
||
}
|
||
|
||
function showHideSecondParentSection(show) {
|
||
if (!secondParentSection) return;
|
||
secondParentSection.style.display = show ? 'block' : 'none';
|
||
}
|
||
|
||
// ---- Behaviors per your rules ----
|
||
// 1) Default: DO NOT auto-check "no_second_parent_info". Keep it unchecked.
|
||
if (noSecondParentCheckbox) noSecondParentCheckbox.checked = false;
|
||
|
||
// 2) Toggle logic when main "is_parent" changes
|
||
function onIsParentChanged() {
|
||
if (isParentCheckbox.checked) {
|
||
// Parent -> show section. Now whether we require fields depends on the "no info" switch.
|
||
showHideSecondParentSection(true);
|
||
if (noSecondParentCheckbox && noSecondParentCheckbox.checked) {
|
||
// No info: ignore second parent data
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
if (secondParentFieldsWrapper) secondParentFieldsWrapper.style.display = 'none';
|
||
} else {
|
||
// Info required
|
||
setSecondParentFieldsRequired(true);
|
||
enableDisableSecondParentFields(false);
|
||
if (secondParentFieldsWrapper) secondParentFieldsWrapper.style.display = 'block';
|
||
}
|
||
} else {
|
||
// Not a parent -> ignore second parent data completely
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
showHideSecondParentSection(false);
|
||
// IMPORTANT: do NOT auto-toggle the "no_second_parent_info" checkbox here.
|
||
}
|
||
}
|
||
|
||
// 3) Toggle logic when "no_second_parent_info" changes
|
||
function onNoSecondParentChanged() {
|
||
// If not parent, ignore entirely
|
||
if (!isParentCheckbox.checked) {
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
showHideSecondParentSection(false);
|
||
return;
|
||
}
|
||
|
||
// Parent is checked:
|
||
if (noSecondParentCheckbox.checked) {
|
||
// No info -> ignore second parent data
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
if (secondParentFieldsWrapper) secondParentFieldsWrapper.style.display = 'none';
|
||
} else {
|
||
// Require info
|
||
setSecondParentFieldsRequired(true);
|
||
enableDisableSecondParentFields(false);
|
||
if (secondParentFieldsWrapper) secondParentFieldsWrapper.style.display = 'block';
|
||
}
|
||
}
|
||
|
||
// ---- Phone formatting / validation ----
|
||
phoneInputs.forEach(input => {
|
||
input.addEventListener('input', function(e) {
|
||
const raw = e.target.value.replace(/\D/g, '').slice(0, 10);
|
||
let formatted = raw;
|
||
if (raw.length > 3) formatted = raw.slice(0, 3) + '-' + raw.slice(3);
|
||
if (raw.length > 6) formatted = formatted.slice(0, 7) + '-' + raw.slice(6);
|
||
e.target.value = formatted;
|
||
|
||
const errorElement = document.getElementById(input.id + '-error');
|
||
if (raw.length === 10 || input.disabled || !input.hasAttribute('required')) {
|
||
input.classList.remove('is-invalid');
|
||
if (errorElement) errorElement.textContent = '';
|
||
} else {
|
||
input.classList.add('is-invalid');
|
||
if (errorElement) errorElement.textContent = 'Please enter a valid 10-digit phone number.';
|
||
}
|
||
});
|
||
|
||
input.addEventListener('blur', function(e) {
|
||
const raw = e.target.value.replace(/\D/g, '');
|
||
const errorElement = document.getElementById(input.id + '-error');
|
||
if (raw.length !== 10 && !input.disabled && input.hasAttribute('required')) {
|
||
input.classList.add('is-invalid');
|
||
if (errorElement) errorElement.textContent = 'Please enter a valid 10-digit phone number.';
|
||
} else {
|
||
input.classList.remove('is-invalid');
|
||
if (errorElement) errorElement.textContent = '';
|
||
}
|
||
});
|
||
});
|
||
|
||
// ---- Event wiring ----
|
||
if (isParentCheckbox) isParentCheckbox.addEventListener('change', onIsParentChanged);
|
||
if (noSecondParentCheckbox) noSecondParentCheckbox.addEventListener('change', onNoSecondParentChanged);
|
||
|
||
// ---- Initial state ----
|
||
// Start with section hidden and inputs disabled, not required.
|
||
showHideSecondParentSection(false);
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
|
||
// ---- Final pre-submit guard ----
|
||
if (form) {
|
||
form.addEventListener('submit', function(e) {
|
||
let ok = true;
|
||
|
||
// Rule 1: First, check Parent/Guardian
|
||
if (!isParentCheckbox.checked) {
|
||
// Not a parent -> ignore second parent data
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
showHideSecondParentSection(false);
|
||
} else {
|
||
// Is a parent
|
||
if (noSecondParentCheckbox && noSecondParentCheckbox.checked) {
|
||
// No second parent info -> ignore second parent data
|
||
setSecondParentFieldsRequired(false);
|
||
enableDisableSecondParentFields(true);
|
||
clearSecondParentFields();
|
||
} else {
|
||
// Require second parent info
|
||
setSecondParentFieldsRequired(true);
|
||
enableDisableSecondParentFields(false);
|
||
|
||
// Validate second required fields
|
||
for (const el of secondRequiredEls) {
|
||
if (!el) continue;
|
||
|
||
const val = (el.value || '').trim();
|
||
if (!val) {
|
||
el.classList.add('is-invalid');
|
||
ok = false;
|
||
} else {
|
||
el.classList.remove('is-invalid');
|
||
}
|
||
|
||
if (el.id === 'second_cellphone') {
|
||
const raw = val.replace(/\D/g, '');
|
||
if (raw.length !== 10) {
|
||
el.classList.add('is-invalid');
|
||
const err = document.getElementById('second_cellphone-error');
|
||
if (err) err.textContent = 'Please enter a valid 10-digit phone number.';
|
||
ok = false;
|
||
}
|
||
}
|
||
|
||
if (el.id === 'second_email') {
|
||
const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
|
||
if (!emailOk) {
|
||
el.classList.add('is-invalid');
|
||
const err = document.getElementById('second_email-error');
|
||
if (err) err.textContent = 'Please enter a valid email address.';
|
||
ok = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Validate all required phone inputs (primary + any enabled second)
|
||
document.querySelectorAll('input[type="tel"]').forEach(input => {
|
||
const raw = (input.value || '').replace(/\D/g, '');
|
||
if (input.hasAttribute('required') && !input.disabled && raw.length !== 10) {
|
||
input.classList.add('is-invalid');
|
||
const err = document.getElementById(input.id + '-error');
|
||
if (err) err.textContent = 'Please enter a valid 10-digit phone number.';
|
||
ok = false;
|
||
}
|
||
});
|
||
|
||
if (!ok) {
|
||
e.preventDefault();
|
||
const firstError = document.querySelector('.is-invalid');
|
||
if (firstError) firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||
}
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
<?= $this->endSection() ?>
|