A utility function for extracting the FormData as an object from the native <form>
element, allowing more ergonomic of usage of The Platform's default form/fields usage.
Each input within your <form>
should have a name
attribute.
(or else the <form>
element doesn't know what inputs are relevant)
This will provide values for all types of controls/fields,
- input: text, checkbox (and checkbox arrays), radio, file, range, etc
- select
- behavior is fixed from browser default behavior, where
only the most recently selected value comes through in
the FormData. This fix only affects
<select multiple>
- behavior is fixed from browser default behavior, where
only the most recently selected value comes through in
the FormData. This fix only affects
- submitter (the button/etc that causes the form to submit (if it has a name attribute))
npm add form-data-utils
import { dataFrom } from 'form-data-utils';
function handleSubmit(event) {
event.preventDefault();
let obj = dataFrom(event);
// ^ { firstName: "NVP", isHuman: null, }
}
<template>
<form onsubmit={{handleSubmit}}>
<label>
First Name
<input type="text" name="firstName" value="NVP" />
</label>
<label>
Are you a human?
<input type="checkbox" name="isHuman" value="nah" />
</label>
<button type="submit">Submit</button>
</form>
</template>
In some cases, you might want to select values that aren't primitive types, e.g selecting a user from a list of users.
Unfortunately, FormData only supports strings. To work around this, form-data-utils
provides some utility functions
to "attach" a non-primitive value to an element:
setValue(element: HTMLElement, value: unknown)
- binds a given value to a given element (value can be anything, e.g objects, arrays, etc)deleteValue(element: HTMLElement)
- undoes a previoussetValue
call
After setting a value with setValue
, that value will be considered by the dataFrom
function.
Note
The ideal way to call these functions will probably vary with the framework you're using.
For example, in Ember.js, you would use these functions in a modifier that you can then apply to elements.
import { dataFrom, deleteValue, setValue } from 'form-data-utils';
import { modifier } from 'ember-modifier';
// define the ember specific modifier
const associateValue = modifier((element, [value]) => {
setValue(element, value);
return () => deleteValue(element);
});
function handleSubmit(event) {
event.preventDefault();
let obj = dataFrom(event);
// ^ { admin: { id: 123, name: 'Sam...' }, user: { id: 321, name: 'Chris...' } }
}
<template>
<form onsubmit={{handleSubmit}}>
{{#each users as |user|}}
<div>
<input type="radio" name="admin" value={{user.id}} {{associateValue user}} />
<label for={{user.id}}>{{user.name}}</label>
</div>
{{/each}}
<select name="user">
<option value=""></option>
{{#each users as |user|}}
<option value={{user.id}} {{associateValue user}}>{{user.name}}</option>
{{/each}}
</select>
<button type="submit">Submit</button>
</form>
</template>
setValue
(and deleteValue
) doesn't really care how you call it. It just needs an element and a value, that's it.
Note
setValue
only supports <input type="checkbox"
, <input type="radio"
and <select
.
Warning
The value given by setValue
has priority. This means that providing both a value
attribute and a value via setValue
will result in the value
attribute being ignored by dataFrom
. However, you might still use the value
attribute it to create a more meaningful html structure.
Another thing that form-data-utils
does is to normalize the types of the values you get back from dataFrom
. The following table lists the types you get back depending on the various controls available:
Control | Type | Default (empty) value |
---|---|---|
<input type="text" (email, search, etc) |
string |
'' |
<input type="number" |
number |
null |
<input type="range" |
number |
ranges can't be empty |
<input type="date" |
Date |
null |
<input type="datetime-local" |
Date |
null |
<input type="file" |
File |
null |
<input type="file" multiple |
File[] |
[] |
<input type="checkbox" without value |
boolean |
false |
<input type="checkbox" with value |
GivenValueType |
null |
multiple <input type="checkbox" with same name without value |
boolean[] |
[] |
multiple <input type="checkbox" with same name with value |
GivenValueType[] |
[] |
<input type="radio" without value |
boolean |
false |
<input type="radio" with value |
GivenValueType |
null |
<select |
GivenValueType |
null |
<select multiple |
GivenValueType[] |
[] |
<button type="submit" with name |
GivenValueType |
null |
Note
GivenValueType
here means the type of the value you passed in the value
attribute or using the setValue(element, value)
function.
See the Contributing guide for details.
This project is licensed under the MIT License.