Extract and set form values through the DOM—no frameworks required! https://github.com/TheoryOfNekomata/formxtra
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 3.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # formxtr
  2. Extract form values through the DOM.
  3. ## Motivation
  4. Forms are used to package related data, typically sent to an external location or processed internally. In the browser,
  5. the default behavior of submitting form data is not always preferred, as this is done through loading a document,
  6. typically the same document, as soon as the form is submitted. In addition, [applications have limited control over how
  7. the data are formatted on submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-enctype)
  8. with this approach. This is why the new way of sending form data is done through AJAX/fetch requests, wherein the data
  9. are serialized into formats like JSON. To turn form data into a specific format requires access to the elements holding
  10. the values to each field in the form.
  11. Some libraries for extracting form values query field elements in the DOM, which is inefficient since they need to
  12. traverse the DOM tree in some way, using methods such as `document.getElementsByTagName()` and
  13. `document.querySelector()`.
  14. Upon retrieving the field values somehow, some libraries attempt to duplicate the values of the fields as they change,
  15. for instance by attaching event listeners and storing the new values into some internal object or map, which can be
  16. retrieved by some other exposed function.
  17. With `formxtr`, there is no need to traverse the DOM for individual fields to get their values. Provided the fields are
  18. associated to the form (either as a descendant of the `<form>` element or [associated through the `form=""`
  19. attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form)) and has a valid
  20. `name`, the values of these fields can be easily extracted, using the `form.elements` attribute built-in to the DOM and
  21. used for getting its currently associated fields. With this, only the reference to the form is needed. The current state
  22. of the field elements are already stored in the DOM, waiting to be accessed.
  23. ## Installation
  24. The package can be found on:
  25. - [Modal Pack](https://js.pack.modal.sh)
  26. - [npm](https://npmjs.com/package/formxtr)
  27. - [GitHub Package Registry](https://github.com/TheoryOfNekomata/formxtr/packages/784699)
  28. ## Usage
  29. For an example form:
  30. ```html
  31. <!-- ... -->
  32. <form id="loginForm">
  33. <input type="text" name="username" />
  34. <input type="password" name="password" />
  35. <button type="submit" name="type" value="client">Log In As Client</button>
  36. <button type="submit" name="type" value="admin">Log In As Admin</button>
  37. </form>
  38. <label>
  39. <input type="checkbox" name="remember" form="loginForm" />
  40. Remember my login credentials
  41. </label>
  42. <!-- ... --->
  43. ```
  44. Use the library as follows (code is in TypeScript, but can work with JavaScript as well):
  45. ```typescript
  46. import getFormValues from '@theoryofnekomata/formxtr';
  47. const form: HTMLFormElement = document.getElementById('form');
  48. // optional, but just in case there are multiple submit buttons in the form,
  49. // individual submitters can be considered
  50. const submitter = form.querySelector('[type="submit"][name="type"][value="client"]');
  51. const values = getFormValues(form, { submitter });
  52. const processResult = (result: Record<string, unknown>) => {
  53. throw new Error('Not yet implemented.');
  54. };
  55. // Best use case is with event handlers
  56. form.addEventListener('submit', async e => {
  57. const { target: form, submitter } = e;
  58. e.preventDefault();
  59. const values = getFormValues(form, { submitter });
  60. // Get the form values and send as request to some API
  61. const response = await fetch(
  62. 'https://example.com/api/log-in',
  63. {
  64. method: 'POST',
  65. body: JSON.stringify(values),
  66. headers: {
  67. 'Content-Type': 'application/json',
  68. },
  69. },
  70. );
  71. if (response.ok) {
  72. const result = await response.json();
  73. processResult(result);
  74. }
  75. })
  76. ```
  77. ## Tests
  78. The library has been tested on the static DOM using JSDOM and Jest, and the real dynamic DOM using Cypress.