Files
code-snippets/javascript/form-utils/README.md
2025-10-31 19:52:49 +01:00

107 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# form-utils (JavaScript)
Small, dependencyfree helpers to improve form UX and simplify common patterns:
- Autowire typical form behaviors (trim inputs, validate, optional XHR submit)
- File input niceties (mirror selected filename, preview images)
- "Submit on click/change" forms via CSS classes
- Lightweight XHR flow with a minimal JSON response convention
- Radio groups with label state syncing
## Quick usage
Minimal setup; adjust paths as needed.
```html
<!-- Example HTML -->
<form class="form-xhr form-onchange" method="post" action="/upload">
<div>
<input type="file" name="file" data-file-preview-target="preview-img" />
<input type="text" name="file-path" placeholder="Selected file…" />
<img id="preview-img" alt="Preview" />
</div>
<div class="radio-container">
<label class="radio-input-wrapper">
<input type="radio" name="size" value="s" /> Small
</label>
<label class="radio-input-wrapper">
<input type="radio" name="size" value="m" /> Medium
</label>
</div>
<button type="submit">Submit</button>
</form>
<script type="module">
import FormUtils from "./form-utils.js";
// Initialize helpers for the whole document (or pass a container element)
await FormUtils.init();
</script>
```
What this does:
- Trims all text/number inputs and textareas before submit
- Validates the form; if valid:
- `.form-xhr` → submits with `XMLHttpRequest` and processes a simple JSON response
- otherwise → performs a normal form submit
- `.form-onchange` → also triggers submit when any field changes
- `.form-onclick` → also triggers submit when the form is clicked
- File input:
- Mirrors the chosen filename to a sibling `input[name="file-path"]`
- If the file is an image and `data-file-preview-target` points to an `<img>`, previews it
- Radio UI:
- In a `.radio-container`, toggles `.radio-checked` on labels whose input is checked
## Markup conventions
- Classes used by the helpers:
- `form-xhr` — submit via XHR instead of regular navigation
- `form-onclick` — dispatch a submit event when the form is clicked
- `form-onchange` — dispatch a submit event when any field changes
- `radio-container` — wrapper enabling radio label syncing
- `radio-input-wrapper` — wrapper around each radio/checkbox input
- `radio-checked` — added to a label when its input is checked
- File preview:
- Add `data-file-preview-target="some-id"` on the file input
- Provide `<img id="some-id">` to receive the preview
- Optional: add a sibling `input[name="file-path"]` to mirror the filename
## JSON response convention (XHR)
When a `.form-xhr` form is submitted, the response is expected to be JSON. Non2xx statuses are logged as errors. A minimal, extensible convention is supported:
```json
{
"::function": [
{ "name": "log", "params": { "ok": true } }
]
}
```
Currently supported actions:
- `log``console.log(params)`
Unrecognized actions are ignored without error.
## API (overview)
All methods are static on `FormUtils`:
- `init(container?)` — wires up inputs, selects, forms, and radio groups within `container` (or `document`)
- `clearFocus()` — blurs the active element
- `readPath(event)` — mirrors selected filename into a sibling `input[name="file-path"]`
- `readImage(event)` — previews chosen image into the `<img>` referenced by `data-file-preview-target`
- `dispatchSubmitEvent(event)` — dispatches a synthetic `submit` on the current form
- `trimInputs(form)` — trims text/number inputs and textareas
- `checkValidity(event)` — validates; normal submit or XHR depending on presence of `.form-xhr`
- `ajaxRequest(form)` / `ajaxResponse(xhr)` — XHR submit and response handling
- `initRadios(container?)` / `radioChangeListener(event)` — label state syncing for radio groups
Notes:
- Assumes a browser environment (DOM APIs available).
- Nonblocking and dependencyfree.
## License
See the repositorylevel `LICENSE` file.