Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
@jalik/form-parser
Advanced tools
type="number"
) or data-type (ex: data-type="boolean"
)data-type
Play with the lib here: https://codesandbox.io/s/jalik-form-parser-demo-r29grh?file=/src/index.js
npm i -P @jalik/form-parser
yarn add @jalik/form-parser
Let's start with the form below :
<form id="my-form">
<input name="username" value="jalik">
<input name="password" value="secret">
<input name="age" type="number" value="35">
<input name="gender" type="radio" value="male" checked>
<input name="gender" type="radio" value="female">
<input name="email" type="email" value="jalik@mail.com">
<input name="phone" type="tel" data-type="string" value="067123456">
<input name="subscribe" type="checkbox" data-type="boolean" value="true" checked>
<input name="token" type="hidden" value="aZ7hYkl12mPx">
<button type="submit">Submit</button>
</form>
You can collect and parse fields with parseForm(form, options)
.
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values with default options
const fields = parseForm(form)
The fields
object will look like this :
{
"username": "jalik",
"password": "secret",
"age": 35,
"gender": "male",
"email": "jalik@mail.com",
"phone": "067123456",
"subscribe": true,
"token": "aZ7hYkl12mPx"
}
Below is a more complete form example, with a lot of different cases to help you understand the behavior of the parsing function (pay attention to comments, values and attributes).
<form id="my-form">
<!-- Fields without name are ignored -->
<input type="text" value="aaa">
<!-- Disabled fields are always ignored -->
<input name="disabled_field" value="hello" disabled>
<!-- Buttons are always ignored -->
<input name="input_button" type="button" value="Click me">
<input name="input_reset" type="reset" value="Reset">
<input name="input_submit" type="submit" value="Submit">
<button name="button" type="button" value="Click me"></button>
<button name="reset" type="reset" value="Reset"></button>
<button name="submit" type="submit" value="Submit"></button>
<!-- These fields will be parsed to booleans -->
<!-- boolean = false -->
<input name="boolean" type="radio" data-type="boolean" value="true">
<input name="boolean" type="radio" data-type="boolean" value="false" checked>
<!-- hidden_boolean = true -->
<input name="hidden_boolean" type="hidden" data-type="auto" value="true">
<!-- These fields will be parsed to numbers -->
<!-- hidden_float = 9.99 -->
<input name="hidden_float" type="hidden" data-type="number" value="09.99">
<!-- text_integer = 1 -->
<input name="text_integer" type="text" data-type="number" value="01">
<!-- select_number = 30 -->
<select name="select_number" data-type="number">
<option>10</option>
<option>20</option>
<option selected>30</option>
</select>
<!-- float = 9.99 -->
<input name="float" type="number" value="09.99">
<!-- integer = 1 -->
<input name="integer" type="number" value="01">
<!-- range = 0118 -->
<input name="range" type="range" value="0118">
<!-- These fields will be parsed to strings -->
<!-- number_text = '0123' -->
<input name="number_text" type="number" data-type="string" value="0123">
<!-- date = '2017-11-14' -->
<input name="date" type="date" value="2017-11-14">
<!-- file = 'file://path/to/file.txt' -->
<input name="file" type="file" value="file://path/to/file.txt">
<!-- hidden_text = 'shadowed' -->
<input name="hidden_text" type="hidden" value="shadowed">
<!-- month = '2017-11' -->
<input name="month" type="month" value="2017-11">
<!-- text = 'Hello' -->
<input name="text" type="text" value="Hello">
<!-- url = 'http://www.github.com/' -->
<input name="url" type="url" value="http://www.github.com/">
<!-- week = '2017-W16' -->
<input name="week" type="week" value="2017-W16">
<!-- textarea = 'Hello' -->
<textarea name="textarea">Hello</textarea>
<!-- Passwords are never altered or parsed ("data-type" is ignored) -->
<!-- password = ' 1337 ' -->
<input name="password" type="password" data-type="number" value=" 1337 ">
<!-- These fields will be parsed as array -->
<!-- select_multiple = [20, 30] -->
<select name="select_multiple" data-type="number" multiple>
<option>10</option>
<option selected>20</option>
<option selected>30</option>
</select>
<!-- array = ['A', 'B'] -->
<input name="array[]" type="checkbox" value="A" checked>
<input name="array[]" type="checkbox" value="B" checked>
</form>
To get form fields :
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values using default options
const fields = parseForm(form)
The fields
object will look like this :
{
"boolean": false,
"hidden_boolean": true,
"float": 9.99,
"hidden_float": 9.99,
"text_integer": 1,
"integer": 1,
"range": 118,
"select_number": 30,
"date": "2017-11-14",
"file": "file://path/to/file.txt",
"hidden_text": "shadowed",
"month": "2017-11",
"number_text": "0123",
"text": "Hello",
"url": "http://www.github.com/",
"textarea": "Hello",
"password": " 1337 ",
"array": [
"A",
"B"
],
"select_multiple": [
20,
30
]
}
To get an array of values, append []
to a field name:
<form id="my-form">
<!-- This will create an array with checked values -->
<input name="array[]" type="checkbox" value="A">
<input name="array[]" type="checkbox" value="B" checked>
<input name="array[]" type="checkbox" value="C" checked>
<!-- This will create an array with checked values (indexed) -->
<input name="colors[2]" type="checkbox" value="red" checked>
<input name="colors[1]" type="checkbox" value="blue">
<input name="colors[0]" type="checkbox" value="white" checked>
</form>
Get fields values :
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values using default options
const fields = parseForm(form)
The fields
object will look like this :
{
"array": [
"B",
"C"
],
"colors": [
"white",
undefined,
"red"
]
}
To get an object, write attributes like [attribute]
:
<form id="my-form">
<!-- This will create an object with those attributes -->
<input name="address[street]" value="Av. Pouvanaa a Oopa">
<input name="address[city]" value="Papeete">
</form>
Get fields values :
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values using default options
const fields = parseForm(form)
The fields
object will look like this :
{
"address": {
"street": "Av. Pouvanaa a Oopa",
"city": "Papeete"
}
}
If you need to create an object with numbers as attributes, use single or double quotes to force the parser to interpret it as a string and then creating an object instead of an array.
<form id="my-form">
<!-- This will create an object with those attributes -->
<input name="elements['0']" value="Zero">
<input name="elements['1']" value="One">
<input name="elements['2']" value="Two">
</form>
Will give this :
{
"elements": {
"0": "Zero",
"1": "One",
"2": "Two"
}
}
Instead of :
{
"elements": [
"Zero",
"One",
"Two"
]
}
To define the type of field, you can use the attribute data-type
or type
.
The attribute data-type
takes precedence over type
if both of are defined.
When using data-type
attribute, the value can be:
auto
to convert the value to the best guess type (ex: 123
=> number
, true
=> boolean
)boolean
to convert the value to a boolean (ex: true
, 1
, yes
, on
, false
, 0
, no
, off
)number
to convert the value to a numberWhen using type
attribute on <input>
, only number
and range
are parsed to numbers.
<!-- This will parse "true" as a boolean -->
<input name="boolean" type="text" data-type="boolean" value="true">
<!-- This will parse "01" as a number -->
<input name="integer" type="text" data-type="number" value="01">
<!-- This will parse "09.99" as a number -->
<input name="float" type="text" data-type="number" value="09.99">
<!-- This will parse "0963" as a string -->
<input name="string" type="text" data-type="string" value="0963">
<!-- This will parse "13.37" as a number -->
<input name="anything" type="text" data-type="auto" value="13.37">
<!-- This will parse "false" as a boolean -->
<input name="anything_2" type="text" data-type="auto" value="false">
You may want to create your own data-type
, it is possible since the v3.1.0
by passing the parser
option to parseForm()
or parseField()
.
<form id="my-form">
<input name="phone" data-type="phone" value="689.12345678" />
</form>
import { parseForm } from '@jalik/form-parser'
const form = document.getElementById('my-form')
const fields = parseForm(form, {
parser: (value, dataType, field) => {
if (dataType === 'phone') {
const [code, number] = value.split(/\./)
return {
code,
number,
}
}
return null
},
})
{
"phone": {
"code": "689",
"number": "12345678"
}
}
It is possible to reconstruct an object corresponding to the form structure, so it can parse complex forms containing nested arrays and objects.
<form id="my-form">
<input name="phones[0][code]" type="number" data-type="string" value="689">
<input name="phones[0][number]" type="number" data-type="string" value="87218910">
<input name="phones[1][code]" type="number" data-type="string" value="689">
<input name="phones[1][number]" type="number" data-type="string" value="87218910">
<!-- A useless deep nested field value -->
<input name="deep_1[][deep_2][0][][deep_3]" value="DEEP">
</form>
To get fields :
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values using default options
const fields = parseForm(form)
The fields
object will look like this :
{
"phones": [
{
"code": "689",
"number": "87218910"
},
{
"code": "689",
"number": "87218910"
}
],
"deep_1": [
{
"deep_2": [
[
{
"deep_3": "DEEP"
}
]
]
}
]
}
When parsing a form, you can filter values with filterFunction(field, parsedValue)
option in the parseForm(form, options)
.
The filter function must return true
to return the field.
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
const fields = parseForm(form, {
// returns only text fields
filterFunction: (field, parsedValue) => field.type === 'text'
});
Values can be cleaned by passing cleanFunction(value, field)
to parseForm(form, options)
.
Note that only strings are passed to this function and that password fields are ignored.
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
// Parse form values using default options
const fields = parseForm(form, {
cleanFunction: (value, field) => {
// Apply uppercase to lastName field
if (field.name === 'lastName' || /name/gi.test(field.name)) {
value = value.toUpperCase()
}
// Remove HTML code from all fields
return value.replace(/<\/?[^>]+>/gm, '')
}
})
To parse a single field.
<form>
<select data-type="number" name="values" multiple>
<option>1</option>
<option selected>2</option>
<option selected>3</option>
</select>
</form>
import { parseField } from '@jalik/form-parser'
const field = document.getElementById('values')
const values = parseField(field)
// values = [2, 3]
To parse a form with all fields.
<form id="my-form">
<input type="number" name="age" value="35" />
<select data-type="number" name="values" multiple>
<option>1</option>
<option selected>2</option>
<option selected>3</option>
</select>
</form>
import { parseForm } from '@jalik/form-parser'
// Get an existing HTML form element
const form = document.getElementById('my-form')
const fields = parseForm(form, {
// Cleans parsed values
cleanFunction(value, field) {
return typeof value === 'string' ? stripTags(value) : value
},
// Only returns fields that matches the condition
filterFunction(field) {
return field.type === 'text'
},
// Replace empty strings with null
nullify: true,
// Set parsing mode.
// - none: disable parsing
// - type: enable parsing based on "type" attribute (ex: type="number")
// - data-type: enable parsing based on "data-type" attribute (ex: data-type="number")
// - auto: enable parsing based on data-type and type (in this order)
parsing: 'none' | 'type' | 'data-type' | 'auto',
// Remove extra spaces
trim: true
})
History of releases is in the changelog.
The code is released under the MIT License.
v3.1.4 (2024-04-29)
parser
is passed to parseField()
or parseForm()
optionsParsingType
to allow "string"
and custom type like phone
parseForm()
returning radio input value as string instead of boolean or number when the last field does not have a data-type
parseField()
to execute custom parser on each value of an array instead of the array itselfFAQs
A utility to parse complex forms with minimum effort.
The npm package @jalik/form-parser receives a total of 64 weekly downloads. As such, @jalik/form-parser popularity was classified as not popular.
We found that @jalik/form-parser demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.