# 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 using `classList.toggle('show')` - Section headers: `

Title

` - Section body: `
` - Labels had no consistent font-size class ### After - Bootstrap card/collapse pattern: `
` → `
` - Section headers: `

Title

` - Section 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`) ```css .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-color` class 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_settlement` as 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 `
` to prevent native submit - Submit button remains `type="button"` with `onclick="submitNonEbClaim()"` - `submitNonEbClaim()` now calls `validateNonEbForm()` first — only proceeds to AJAX if validation passes ### Validation CSS Added ```css .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` | 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` | 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`, `required` attributes on relevant input fields - `
` added after each validated field with descriptive error message ### JS Validation Functions Added - **`clearValidation()`** — Removes `.is-invalid` and `.is-invalid-select2` from all form elements - **`setInvalid(field, msg)`** — Marks a field invalid with custom message - **`validateNonEbForm()`** — Main validation function: - Validates all required and optional fields per rules above - Select2 dropdowns: highlights the `.select2-selection` border 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`/`change` events on `.form-control` → removes `.is-invalid` - `change` event on `select` → removes both `.is-invalid` and `.is-invalid-select2` from 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 `
` elements and centered "OR" text - Styled with `font-weight-bold text-muted`, `0.9rem` font size ### File Upload Field - `` - 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: 1. **Has any asset row with data?** — Iterates all `.asset-row` elements, checks if any input has a non-empty value 2. **Has a valid file?** — Checks if file is selected and extension is one of `.xlsx`, `.xls`, `.csv`, `.pdf` 3. If **neither** condition met → shows error "Please fill at least one asset row or upload an asset file." 4. 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()` with `new FormData(document.getElementById('nonEbClaimForm'))` - AJAX call: switched from `sendAjaxRequestForGlobal()` to `$.ajax()` with `processData: false, contentType: false` to support file upload - Added `X-Requested-With: XMLHttpRequest` header for CI4 `$this->request->isAJAX()` detection ### Real-time Error Clearing - Asset row input change → hides `#asset_section_error` - File input change → removes `.is-invalid` and 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: ```js 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_file` upload handling — implemented in both `createClaim()` and `updateClaim()` - The `sendAjaxRequestForGlobal()` utility was replaced with raw `$.ajax()` in submit because it doesn't support `FormData` with `processData: 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: ```html

Title

``` To: ```html

Title

``` ### 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 | `
` + `onclick="toggleAccordion(this)"` | `
` + Bootstrap card/collapse (`collapseThree`) | | 4. Intimation & Claim Reference | Same old pattern | `
` (`collapseFour`) | | 5. Status & Tracking | Same old pattern | `
` (`collapseFive`) | | 6. Asset Details | Same old pattern | `
` (`collapseSix`) | | 7. Surveyor Details | `
` | `
` + inner Bootstrap card/collapse (`collapseSeven`) | | 8. Documents & Attachments | Same old pattern | `
` (`collapseEight`) | | 9. Settlement Details | `
` | `
` + 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 |