18 KiB
Dev Log — 2026-03-26
Feature: Non-EB Claim Form — UI Overhaul, Validation & Asset File Upload
Objective
Continued development of the Non-EB Claims creation form (non_eb_claim_form.php). This session covered three major areas: (1) UI restyling to match the GMC ticket form, (2) comprehensive frontend validation with JS-only form submission, and (3) asset section enhancement with file upload support.
1. UI Restyling — Match ticket_form_gmc.php Accordion & Card Style
What Changed
Replaced the custom accordion implementation with Bootstrap card/collapse pattern used in the existing GMC ticket form.
Before
- Custom CSS classes:
.accordion,.accordion-content,.arrow,.rotate - Custom JS
toggleAccordion(el)function usingclassList.toggle('show') - Section headers:
<h4 onclick="toggleAccordion(this)">Title <span class="arrow">▶</span></h4> - Section body:
<div class="accordion-content show"> - Labels had no consistent font-size class
After
- Bootstrap card/collapse pattern:
<div class="card mb-1">→<div class="collapse show"> - Section headers:
<h4 class="m-1">Title <a data-toggle="collapse" href="#collapseX"><i class="mdi mdi-chevron-down"></i></a></h4> - Section body:
<div id="collapseX" class="collapse show" data-parent="#accordionX"><div class="card-body"> - Removed
toggleAccordion()JS function entirely - All labels now use
class="label-font-size"(0.875rem) matching GMC form
CSS Classes Added (matching ticket_form_gmc.php)
.readonly-color { background-color: #e0e0e0; color: #666; }
.readonly-select { pointer-events: none; background-color: #f0f0f0; color: #666; }
.label-font-size { font-size: 0.875rem; }
Readonly Fields Styled
- Insurer, Policy No, Policy Start Date, Policy Expiry Date inputs — added
readonly-colorclass for darker background on auto-filled fields
Section ID Mapping
| Section | Accordion ID | Collapse ID |
|---|---|---|
| Policy & Account Details | accordion1 | collapseOne |
| Insured Contact Details | accordion2 | collapseTwo |
| Loss / Incident Details | accordion3 | collapseThree |
| Intimation & Claim Reference | accordion4 | collapseFour |
| Status & Tracking | accordion5 | collapseFive |
| Asset Details | accordion6 | collapseSix |
| Surveyor Details | section_surveyor | collapseSeven |
| Documents & Attachments | accordion8 | collapseEight |
| Settlement Details | section_settlement | collapseNine |
- Surveyor and Settlement sections use
section_surveyor/section_settlementas parent IDs (for JS show/hide toggling based on status)
2. Frontend Validation & JS-Only Form Submit
What Changed
Removed reliance on native HTML5 form submission. Implemented full JavaScript validation matching backend rules in NonEbClaimController::getValidationRules().
Form Changes
- Added
onsubmit="return false;"to<form>to prevent native submit - Submit button remains
type="button"withonclick="submitNonEbClaim()" submitNonEbClaim()now callsvalidateNonEbForm()first — only proceeds to AJAX if validation passes
Validation CSS Added
.is-invalid { border-color: #dc3545 !important; }
.invalid-feedback { display: none; color: #dc3545; font-size: 0.8rem; }
.is-invalid ~ .invalid-feedback, .is-invalid + .invalid-feedback { display: block; }
.select2-container .select2-selection--single.is-invalid-select2 { border-color: #dc3545 !important; }
Validation Rules (matching backend)
| Field | Type | Rules |
|---|---|---|
client_select |
Select2 | Required |
branch_id |
Select2 | Required |
acm_id |
Select2 | Required |
claim_status_id |
Select | Required |
insured_contact_name |
Text | Required, min 3 chars, pattern ^[a-zA-Z0-9\s_-]+$ |
insured_contact_number |
Text | Required, numeric only, 10-15 digits |
insured_contact_email |
Optional, email format regex | |
nature_of_loss |
Text | Required, min 3 chars |
loss_location |
Text | Required |
loss_date |
Date | Required |
loss_estimate |
Number | Optional, must be numeric |
claim_number |
Text | Optional, pattern ^[a-zA-Z0-9\/_-]+$ |
nhance_claim_ref_no |
Text | Optional, max 100 chars |
surveyor_contact_number |
Text | Optional (only if section visible), numeric, 10-15 digits |
surveyor_email |
Optional (only if section visible), email format | |
loss_assessed_value |
Number | Optional (only if section visible), numeric |
settled_amount |
Number | Optional (only if section visible), numeric |
settlement_utr |
Text | Optional (only if section visible), max 100 chars |
HTML Validation Attributes Added
minlength,maxlength,pattern,min,requiredattributes on relevant input fields<div class="invalid-feedback">added after each validated field with descriptive error message
JS Validation Functions Added
clearValidation()— Removes.is-invalidand.is-invalid-select2from all form elementssetInvalid(field, msg)— Marks a field invalid with custom messagevalidateNonEbForm()— Main validation function:- Validates all required and optional fields per rules above
- Select2 dropdowns: highlights the
.select2-selectionborder red via.is-invalid-select2 - Surveyor/Settlement fields: only validated if their parent section is visible
- On failure: shows all errors via
toastr.error(), expands collapsed section if first invalid field is hidden, scrolls to first invalid field and focuses it - Returns
true/false
Real-time Validation Clearing
input/changeevents on.form-control→ removes.is-invalidchangeevent onselect→ removes both.is-invalidand.is-invalid-select2from Select2 container
3. Asset Section — File Upload with OR Divider
What Changed
Added a file upload option in the Asset Details section as an alternative to manually filling asset rows.
UI Structure
[Asset Row 1: ID/Code | Serial No | Vehicle No | Description]
[+ Add More Asset] button
─────────────────── OR ───────────────────
[Upload Asset File (Excel or PDF)] [Browse...]
OR Divider
- Flexbox layout with two
<hr>elements and centered "OR" text - Styled with
font-weight-bold text-muted,0.9remfont size
File Upload Field
<input type="file" name="asset_file" id="asset_file" accept=".xlsx,.xls,.csv,.pdf">- Accepts:
.xlsx,.xls,.csv,.pdf - Error message div:
#asset_section_error— shown when neither asset row nor file is provided
Validation Logic
On form submit, checks:
- Has any asset row with data? — Iterates all
.asset-rowelements, checks if any input has a non-empty value - Has a valid file? — Checks if file is selected and extension is one of
.xlsx,.xls,.csv,.pdf - If neither condition met → shows error "Please fill at least one asset row or upload an asset file."
- If file has invalid extension → marks file input invalid with specific message
Form Submit Changed to FormData
- Form tag: added
enctype="multipart/form-data" submitNonEbClaim(): replaced$('#nonEbClaimForm').serialize()withnew FormData(document.getElementById('nonEbClaimForm'))- AJAX call: switched from
sendAjaxRequestForGlobal()to$.ajax()withprocessData: false, contentType: falseto support file upload - Added
X-Requested-With: XMLHttpRequestheader for CI4$this->request->isAJAX()detection
Real-time Error Clearing
- Asset row input change → hides
#asset_section_error - File input change → removes
.is-invalidand hides#asset_section_error
4. Policy Date Format Fix (Continued from Previous Session)
Issue
Policy start/end dates displayed as 2-Dec-2026 12:00 am instead of 12-02-2026 when selecting a policy.
Root Cause
API returns dates in MySQL format YYYY-MM-DD (e.g., 2026-02-12). The JS formatDate() function was not being applied correctly.
Fix Applied
Replaced formatDate() call with inline string split conversion in policy change handler:
var startRaw = sel.attr('data-start-date') || '';
if (startRaw && startRaw.indexOf('-') > -1) {
var sp = startRaw.split('-');
if (sp[0].length === 4) startRaw = sp[2] + '-' + sp[1] + '-' + sp[0];
}
- Splits
2026-02-12→['2026','02','12'] - Checks first part is 4 digits (year)
- Rearranges to
12-02-2026
Files Modified
| File | Changes |
|---|---|
app/Views/non_eb_claim_form.php |
Full UI restyle, validation, asset file upload |
app/Controllers/NonEbClaimController.php |
Minor — reverted PHP date formatting (not needed, API already returns MySQL format) |
Notes
- Backend controller
asset_fileupload handling — implemented in bothcreateClaim()andupdateClaim() - The
sendAjaxRequestForGlobal()utility was replaced with raw$.ajax()in submit because it doesn't supportFormDatawithprocessData: false
5. Edit View (non_eb_claim_edit.php) — Sync with Create Form
Objective
Bring the edit view in line with the create form's UI, validation, and scripting changes from sections 1–4 above.
A. CSS Changes
| Change | Before (Edit) | After (Edit) |
|---|---|---|
| Accordion CSS | Custom .accordion, .accordion-content, .arrow, .rotate |
Removed — replaced by Bootstrap card/collapse |
toggleAccordion() JS |
Present | Removed |
| Validation CSS | Missing | Added .is-invalid, .invalid-feedback, .is-invalid-select2 |
| Readonly CSS | Missing | Added .readonly-color, .readonly-select |
B. HTML Section Changes — All 9 Sections Converted to Bootstrap Card/Collapse
Each section changed from:
<div class="accordion">
<h4 onclick="toggleAccordion(this)">Title <span class="arrow rotate">▶</span></h4>
<div class="accordion-content show">
To:
<div id="accordionX" class="mb-3">
<div class="card mb-1">
<h4 class="m-1">Title <a data-toggle="collapse" href="#collapseX"><i class="mdi mdi-chevron-down"></i></a></h4>
<div id="collapseX" class="collapse show" data-parent="#accordionX">
<div class="card-body">
Section-Specific HTML Changes
| Section | ID Mapping | Key Field Changes |
|---|---|---|
| 1. Policy & Account | accordion1 / collapseOne | Added Policy Start Date & Expiry Date fields (readonly, readonly-color). Insurer field gets readonly-color. Policy No gets readonly-color. All labels get label-font-size. |
| 2. Insured Contact | accordion2 / collapseTwo | Added id attrs on inputs. Added minlength="3", pattern on contact name. Added minlength="10" maxlength="15" pattern="^[0-9]+$" on contact number. Added invalid-feedback divs. |
| 3. Loss / Incident | accordion3 / collapseThree | Added id attrs, minlength="3" on nature_of_loss, min="0" on loss_estimate. Added invalid-feedback divs. Date placeholder changed to dd-mm-yyyy. |
| 4. Intimation & Ref | accordion4 / collapseFour | Added id attrs, maxlength="100" on nhance_claim_ref_no, pattern on claim_number. Added invalid-feedback divs. Date placeholder dd-mm-yyyy. |
| 5. Status & Tracking | accordion5 / collapseFive | Labels get label-font-size. |
| 6. Asset Details | accordion6 / collapseSix | Labels get label-font-size. |
| 7. Surveyor Details | section_surveyor / collapseSeven | Added minlength="10" maxlength="15" pattern="^[0-9]+$" on contact number. Added invalid-feedback divs on contact number and email. maxlength="255" on name/contact person. |
| 8. Documents | accordion8 / collapseEight | Labels get label-font-size. Date placeholder dd-mm-yyyy. |
| 9. Settlement | section_settlement / collapseNine | Added min="0" on numeric fields, maxlength="100" on UTR. Added invalid-feedback divs. |
Form Tag Changes
- Added
onsubmit="return false;"to prevent native submit
C. JavaScript Changes
| Change | Details |
|---|---|
Removed toggleAccordion() |
No longer needed — Bootstrap collapse handles it |
Added validateNonEbForm() |
Full JS validation matching create form — all 16+ field rules |
Added clearValidation() |
Removes .is-invalid / .is-invalid-select2 |
Added setInvalid() |
Marks field invalid with message |
Added formatDate() |
Handles MySQL YYYY-MM-DD to dd-mm-yyyy conversion |
Added resetContact() |
Clears insured contact fields |
Added noneb_contact_list |
Stores contact data from AJAX |
| Branch change handler | Added contact auto-fill from noneb_contact_list |
appendPolicies() |
Added data-policy-type, data-start-date, data-end-date attrs |
| Policy change handler | Added date auto-fill (policy start/end date) with YYYY-MM-DD → dd-mm-yyyy |
resetPolicy() |
Added clearing of policy start/end date fields |
submitNonEbClaim() |
Now calls validateNonEbForm() before AJAX |
| Real-time validation clearing | input/change on .form-control removes .is-invalid. change on select removes .is-invalid-select2. Asset file change clears error. |
| flatpickr dateFormat | Changed from d/m/Y to d-m-Y to match create form |
Files Modified (Updated)
| File | Changes |
|---|---|
app/Views/non_eb_claim_form.php |
Full UI restyle, validation, asset file upload (session 1) |
app/Views/non_eb_claim_edit.php |
Full UI restyle sync, validation, contact auto-fill, date fields (session 2) |
app/Controllers/NonEbClaimController.php |
asset_file upload handling in create/update |
app/Models/NonEbTicketMasterModel.php |
Added asset_file, branch_id to allowedFields |
app/Config/Constants.php |
Added UPLOAD_EXT_ASSET_FILES |
db.md |
Added branch_id, asset_file columns + ALTER TABLE queries |
6. Edit View (non_eb_claim_edit.php) — Full Sync with Create Form (Session 3)
Objective
Complete remaining sections (3–9) and all JS that were still using the old accordion pattern. This session fully brings non_eb_claim_edit.php in parity with non_eb_claim_form.php.
A. HTML — Sections 3–9 Converted to Bootstrap Card/Collapse
| Section | Old | New |
|---|---|---|
| 3. Loss / Incident Details | <div class="accordion"> + onclick="toggleAccordion(this)" |
<div id="accordion3" class="mb-3"> + Bootstrap card/collapse (collapseThree) |
| 4. Intimation & Claim Reference | Same old pattern | <div id="accordion4" class="mb-3"> (collapseFour) |
| 5. Status & Tracking | Same old pattern | <div id="accordion5" class="mb-3"> (collapseFive) |
| 6. Asset Details | Same old pattern | <div id="accordion6" class="mb-3"> (collapseSix) |
| 7. Surveyor Details | <div class="accordion" id="section_surveyor"> |
<div id="section_surveyor" class="mb-3"> + inner Bootstrap card/collapse (collapseSeven) |
| 8. Documents & Attachments | Same old pattern | <div id="accordion8" class="mb-3"> (collapseEight) |
| 9. Settlement Details | <div class="accordion" id="section_settlement"> |
<div id="section_settlement" class="mb-3"> + inner Bootstrap card/collapse (collapseNine) |
Section-Specific Field Changes
| Section | Field Changes |
|---|---|
| 3. Loss / Incident | Added id attrs on all inputs. Added minlength="3" on nature_of_loss. Added min="0" on loss_estimate. Added invalid-feedback divs. Date placeholder dd/mm/yyyy → dd-mm-yyyy. All labels get label-font-size. |
| 4. Intimation | Added id attrs. Added maxlength="100" on nhance_claim_ref_no. Added pattern="^[a-zA-Z0-9\/_-]+$" on claim_number. Added invalid-feedback divs. Date placeholders dd/mm/yyyy → dd-mm-yyyy. Labels get label-font-size. |
| 5. Status & Tracking | Labels get label-font-size. |
| 6. Asset Details | Asset row labels get label-font-size. Asset file upload label gets label-font-size. |
| 7. Surveyor Details | Added minlength="10" maxlength="15" pattern="^[0-9]+$" on contact number. Added maxlength="255" on name and contact person. Added invalid-feedback on contact number and email. Labels get label-font-size. |
| 8. Documents | Labels get label-font-size. Date placeholder dd/mm/yyyy → dd-mm-yyyy. |
| 9. Settlement | Added min="0" on loss_assessed_value and settled_amount. Added maxlength="100" on settlement_utr. Added invalid-feedback divs on all three. Labels get label-font-size. |
B. JavaScript Changes
| Change | Details |
|---|---|
Removed toggleAccordion() |
No longer needed — Bootstrap collapse handles it |
appendPolicies() |
Added data-policy-type, data-start-date, data-end-date attrs; also added insurer_short_name/insurer_branch_code display logic matching create form |
resetPolicy() |
Added $('#policy_start_date').val('') and $('#policy_end_date').val('') |
Added noneb_contact_list |
Variable to store contact data keyed by branch |
Removed noneb_branch_list |
Was unused; removed |
Added resetContact() |
Clears insured_contact_name, insured_contact_number, insured_contact_email |
| Client change handler | Added resetContact() call; populates noneb_contact_list from response.contact_data; added error toastr on failure |
| Branch change handler | Added contact auto-fill from noneb_contact_list[branch_id] (name, number, email) |
| Policy change handler | Changed .data() to .attr() for custom data attributes. Added date auto-fill: reads data-start-date/data-end-date, converts YYYY-MM-DD → dd-mm-yyyy via inline split, writes to #policy_start_date/#policy_end_date |
Added formatDate() |
Handles both dd-Mon-yyyy hh:mm and YYYY-MM-DD formats → dd-mm-yyyy |
Added clearValidation() |
Removes .is-invalid and .is-invalid-select2 from all form elements |
Added setInvalid() |
Marks a field invalid with optional custom message |
Added validateNonEbForm() |
Full validation matching backend rules — 16+ fields including conditional surveyor/settlement sections and asset row/file check |
submitNonEbClaim() |
Added if (!validateNonEbForm()) return; before AJAX |
flatpickr dateFormat |
Changed from d/m/Y to d-m-Y |
| Select2 init | Added $('#client_select').select2(), $('#branch_id').select2(), $('#client_policy_id').select2() alongside existing .select2-init |
| Real-time validation clearing | input/change on .form-control removes .is-invalid; change on select removes .is-invalid and .is-invalid-select2; #asset_file change hides #asset_section_error; asset row input hides #asset_section_error |
Files Modified (Session 3)
| File | Changes |
|---|---|
app/Views/non_eb_claim_edit.php |
Sections 3–9 HTML converted to Bootstrap card/collapse; full JS sync — validation, contact auto-fill, policy date auto-fill, real-time clearing |