From 103b9dda8476b498cf49d0ec1aff5b02e3c6efcb Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sat, 11 Mar 2023 16:24:52 +0800 Subject: [PATCH] Update README Make readme more concise. --- README.md | 130 ++++++++++++++++--------------------------- docs/00-rationale.md | 19 +++++++ 2 files changed, 67 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index ee011a8..dde5dc0 100644 --- a/README.md +++ b/README.md @@ -19,110 +19,76 @@ The package can be found on: For an example form: ```html - +
- - - - + + + +
- - ``` Use the library as follows (code is in TypeScript, but can work with JavaScript as well): ```typescript -// The default export is same with `getFormValues`, but it is recommended to use the named import for future-proofing! import { getFormValues, setFormValues } from '@theoryofnekomata/formxtra'; -// This is the only query we need. On libraries like React, we can easily get form elements when we attach submit event -// listeners. +// This is the only query we need. On libraries like React, we can easily get form elements when we +// attach submit event listeners. const form: HTMLFormElement = document.getElementById('form'); -// Optional, but just in case there are multiple submit buttons in the form, -// individual submitters can be considered -const submitter = form.querySelector('[type="submit"][name="type"][value="client"]'); - -const values = getFormValues(form, { submitter }); +const processResponse = async (response: Response) => { + const result = await response.json(); -const processResult = (result: Record) => { - setFormValues(form, { - username: 'Username', - password: 'verylongsecret', - }); - - throw new Error('Not yet implemented.'); + alert(`Welcome ${result.user}!`); }; // Best use case is with event handlers form.addEventListener('submit', async e => { - const { currentTarget: form, submitter } = e; - e.preventDefault(); - - const values = getFormValues(form, { submitter }); - - // Get the form values and send as request to some API - const response = await fetch( - 'https://example.com/api/log-in', - { - method: 'POST', - body: JSON.stringify(values), - headers: { - 'Content-Type': 'application/json', - }, - }, - ); - - if (response.ok) { - const result = await response.json(); - - processResult(result); - } -}) + const { + currentTarget: thisForm, + submitter, + } = e; + e.preventDefault(); + + const values = getFormValues(thisForm, { submitter }); + + // Get the form values and send as request to some API + const response = await fetch( + 'https://example.com/api/log-in', + { + method: 'POST', + body: JSON.stringify(values), + headers: { + 'Content-Type': 'application/json', + }, + }, + ); + + if (response.ok) { + processResponse(response); + } +}); + +const autofillButton = document.getElementById('autofill'); + +autofillButton.addEventListener('click', e => { + setFormValues(form, { username: 'admin', remember: true }); +}); ``` ## Tests The library has been tested on the static DOM using JSDOM, and the real dynamic DOM using Cypress. - -## Motivation - -Forms are used to package related data, typically sent to an external location or processed internally. In the browser, -the default behavior of submitting form data is not always preferred, as this is done through loading or reloading a -document as soon as the form is submitted. In addition, [applications have limited control over how the data are -formatted on submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-enctype) with -this approach. This is why the new way of sending form data is done through AJAX/fetch requests, wherein the data are -serialized into formats like JSON. To turn form data into a specific format requires access to the elements holding the -values to each field in the form. - -Libraries made for extracting form values query field elements in the DOM, which is inefficient since they need to -traverse the DOM tree in some way, using methods such as `document.getElementsByTagName()` and -`document.querySelector()`. This is the same case with setting each form values for, say, prefilling values to save -time. It might be a simple improvement to the user experience, but the logic behind can be unwieldy as there may be -inconsistencies in setting up each field value depending on the form library being used. - -Upon retrieving the field values somehow, some libraries attempt to duplicate the values of the fields as they change, -for instance by attaching event listeners and storing the new values into some internal object or map. This is then -retrieved by some other exposed function or mechanism within that library. This is common with reactive frameworks, -where changes to the document are essential to establish functionality and improved user experience. - ---- - -With `formxtra`, there is no need to traverse elements for individual fields to get and set their values, provided they are: - -* Associated to the form (either as a descendant of the `
` element or [associated through the `form=""` - attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form)) -* Has a valid `name` - -The values of these fields can be easily extracted and set, using the `form.elements` attribute built-in to the DOM. -With this, only the reference to the form is needed. The current state of the field elements is already stored in the -DOM, waiting to be accessed. - -Additional documentation can be found on the [`docs` directory](./docs). diff --git a/docs/00-rationale.md b/docs/00-rationale.md index c5fa2d0..efdcfe1 100644 --- a/docs/00-rationale.md +++ b/docs/00-rationale.md @@ -37,3 +37,22 @@ Let us set some facts about existing form libraries: * However, the solution for this is to provide a corresponding `` element for each custom\ component, which should always get the latter's serializable value. In return, this can also simplify the submission of the form as the custom components' values are already in the form. + +Forms are used to package related data, typically sent to an external location or processed internally. In the browser, +the default behavior of submitting form data is not always preferred, as this is done through loading or reloading a +document as soon as the form is submitted. In addition, [applications have limited control over how the data are +formatted on submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-enctype) with +this approach. This is why the new way of sending form data is done through AJAX/fetch requests, wherein the data are +serialized into formats like JSON. To turn form data into a specific format requires access to the elements holding the +values to each field in the form. + +Libraries made for extracting form values query field elements in the DOM, which is inefficient since they need to +traverse the DOM tree in some way, using methods such as `document.getElementsByTagName()` and +`document.querySelector()`. This is the same case with setting each form values for, say, prefilling values to save +time. It might be a simple improvement to the user experience, but the logic behind can be unwieldy as there may be +inconsistencies in setting up each field value depending on the form library being used. + +Upon retrieving the field values somehow, some libraries attempt to duplicate the values of the fields as they change, +for instance by attaching event listeners and storing the new values into some internal object or map. This is then +retrieved by some other exposed function or mechanism within that library. This is common with reactive frameworks, +where changes to the document are essential to establish functionality and improved user experience.