Commit 9f14038
authored
feat(insurance): client-side phone/fax validation on insurance + pharmacy edit forms (openemr#12534)
## Summary
Follow-up to openemr#12529. That PR stopped the `TypeError` when a user typed a
phone the legacy `phone_numbers` schema couldn't represent (anything
that isn't a 10-digit NANP number), but the user still got no feedback —
the bad value was silently dropped on save. This PR adds client-side
validation so the *Practice Settings → Insurance Company* and
*Procedures → Pharmacies* edit forms reject bad input before submit,
with the browser's native error bubble pointing at the offending field.
## Scope (narrow on purpose)
Two forms, four fields. These are the **only** two places in the
codebase whose phone setters silently drop on
`TypedPhoneNumber::tryCreate()` returning null (the same survey I did
before openemr#12529). Other phone-bearing forms (patient demographics telecom,
etc.) store the raw string verbatim — a different failure mode that
needs a different fix in a separate PR.
## Changes
For both `templates/insurance_companies/general_edit.html` and
`templates/pharmacies/general_edit.html`:
- **`type=\"text\"` → `type=\"tel\"`** on the phone and fax inputs —
semantic, and triggers the numeric soft keyboard on mobile.
-
**`pattern=\"\\(?\\d\\d\\d\\)?[\\s.\\-]?\\d\\d\\d[\\s.\\-]?\\d\\d\\d\\d\"`**
matching the same 10-digit NANP shapes the server already accepts
(`5551234567`, `555-123-4567`, `(555) 123-4567`, `555.123.4567`, etc.).
- **`title=\"{xla t='Enter a 10-digit phone number, e.g.
555-123-4567'}\"`** so the browser's validation bubble explains the
expected format (translated).
- **`submit_insurancecompany()` / `submit_pharmacy()`** now call
`form.reportValidity()` before submit. Without this the JS-driven Save
anchor bypasses HTML5 validation entirely.
## Why not `\\d{3}`?
Smarty 4.5 treats `{3}` and `{4}` as tag delimiters and silently strips
them during template compilation, so the rendered pattern becomes
`\\(?\\d3\\)?[\\s.\\-]?\\d3[\\s.\\-]?\\d4` — a regex that rejects every
plausible phone number. The explicit `\\d\\d\\d` form sidesteps Smarty
and is short enough not to be unreadable.
## What this does not address
- **Server-side coverage is unchanged.** A programmatic POST (curl, API
client, anything outside a browser) still hits the legacy `set_number()`
silent-drop path. openemr#12529's persist null-guard still carries that
defense; this PR is the UX layer on top.
- **No new error-display mechanism** in the legacy `C_InsuranceCompany`
/ `C_Pharmacy` controllers. The browser's native bubble is the entire
validation surface — proportional for the cheap tier; a server-side
validation error page would be a larger UX scope.
- **NANP-only.** The underlying schema is still 10-digit US/Canada.
International formats (`+44 …`) deserve a schema-and-storage change, not
a regex tweak here.
## Verification
Drove both forms through the dev stack's Selenium grid (script in
scratch, not committed). Captured per-input behaviour against
`form.checkValidity()`, `phone.checkValidity()`, and the rendered
`pattern` attribute, then exercised the actual `submit_*` JS handlers
and observed whether the page stayed on the edit form or navigated away.
| Input | Insurance | Pharmacy |
|---|---|---|
| `555-1234` (7 digits) | ✗ blocked | ✗ blocked |
| `555-123-45678` (11 digits) | ✗ blocked | ✗ blocked |
| `garbage` | ✗ blocked | ✗ blocked |
| `555-123-4567` | ✓ passes | ✓ passes |
| `(555) 123-4567` | ✓ passes | ✓ passes |
| `5551234567` | ✓ passes | ✓ passes |
| (empty) | ✓ passes (optional) | ✓ passes (optional) |
## Test plan
- [x] On *Practice Settings → Insurance Company → Add*, type `555-1234`
in **Phone**, click **Save** → expect the browser's native error bubble
next to the Phone field, form stays on the edit page.
- [x] Same form, type `555-123-4567` in **Phone** + a name, click
**Save** → expect successful save with phone written to the row.
- [x] Same for **Fax** field.
- [x] On *Procedures → Pharmacies → Add* (or Edit), repeat the three
checks above.
- [x] Empty Phone/Fax fields still save (they remain optional).
- [ ] On a mobile device, the numeric keyboard pops up when focusing the
Phone/Fax fields (bonus, from `type=\"tel\"`).1 parent 27e8a2a commit 9f14038
2 files changed
Lines changed: 29 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
77 | | - | |
| 77 | + | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
| 83 | + | |
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
| |||
153 | 153 | | |
154 | 154 | | |
155 | 155 | | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
| 156 | + | |
| 157 | + | |
162 | 158 | | |
| 159 | + | |
163 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
164 | 171 | | |
165 | 172 | | |
166 | 173 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
| 104 | + | |
| 105 | + | |
113 | 106 | | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
114 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
115 | 118 | | |
116 | 119 | | |
117 | 120 | | |
| |||
0 commit comments