Skip to content

Commit f2a1621

Browse files
author
Rúnar Berg
committed
Make filter a setter
As opposed to the second (or first curried) parameter. From now on instead of `formsquare(form, filter)` we will write `formsquare.filter(filter).parse(form)`. closes: #8
1 parent 1431263 commit f2a1621

File tree

6 files changed

+219
-102
lines changed

6 files changed

+219
-102
lines changed

Diff for: README.md

+52-42
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ npm install --save formsquare
2020
```js
2121
import formsquare from "formsquare";
2222

23-
formsquare(form, filter);
23+
formsquare.parse(form);
2424

2525
// or
26-
const parseForm = formsquare(filter);
27-
parseForm(form);
26+
formsquare.filter(myFilter).parse(form);
2827
```
2928

3029
Where `form` is an `HTMLFormElement` (like `document.forms[0]`) and
31-
`filter` is an optional predicate function (like `(el) =>
32-
!el.disabled`) that determines which form elements to include.
30+
`myFilter` is a predicate function (like `el => !el.disabled`) that
31+
determines which form elements to include.
3332

3433
#### commonjs
3534

@@ -109,17 +108,16 @@ Examples
109108
import formsquare from "formsquare";
110109

111110
const form = document.getElementById("my-form");
112-
const filter = (el) => !el.disabled;
111+
const filter = el => !el.disabled;
113112

114-
formsquare(form, filter);
115-
// {"foo": "bar"}
113+
formsquare.filter(filter).parse(form);
114+
//=> {"foo": "bar"}
116115
```
117116

118-
### Currying
117+
### Filters
119118

120-
You can pass only a predicate function to formsquare and be returned
121-
with a new parser that will filter all form elements by that
122-
predicate.
119+
You can call `formsquare.filter` with a predicate be returned a new
120+
parser that will filter all form elements by that predicate.
123121

124122
```html
125123
<form>
@@ -131,18 +129,32 @@ predicate.
131129
<input value="foo" disabled>
132130
<input value="bar">
133131
</form>
132+
133+
<form>
134+
<input value="foo" disabled>
135+
<input value="bar" class="hidden">
136+
<input value="baz">
137+
</form>
134138
```
135139

136140
```js
137141
import formsquare from "formsquare";
138142

139-
const parseForm = formsquare((el) => !el.disabled);
143+
const { parse } = formsquare.filter(el => !el.disabled);
140144

141-
parseForm(document.forms[0]);
142-
// "foo"
145+
parse(document.forms[0]);
146+
//=> "foo"
143147

144-
parseForm(document.forms[1]);
145-
// "bar"
148+
parse(document.forms[1]);
149+
//=> "bar"
150+
151+
// Filters can be chained
152+
153+
formsquare
154+
.filter(el => !el.disabled)
155+
.filter(el => !el.classList.contains("hidden"))
156+
.parse(document.forms[2]);
157+
//=> "baz"
146158
```
147159

148160
### Simple forms
@@ -154,8 +166,8 @@ An empty form will always return `null`
154166
```
155167

156168
```js
157-
formsquare(document.getElementById("empty-form"));
158-
// null
169+
formsquare.parse(document.getElementById("empty-form"));
170+
//=> null
159171
```
160172

161173
A form with a single element without an explicit name gives you a
@@ -169,12 +181,12 @@ singleton value.
169181

170182
```js
171183
const singletonForm = document.getElementById("singleton-form");
172-
formsquare(singletonForm);
173-
// 42
184+
formsquare.parse(singletonForm);
185+
//=> 42
174186

175187
singletonForm[0].type = "text";
176-
formsquare(singletonForm);
177-
// "42"
188+
formsquare.parse(singletonForm);
189+
//=> "42"
178190
```
179191

180192
### Collections of forms
@@ -194,11 +206,11 @@ it will be handled as a single form.
194206
```
195207

196208
```js
197-
formsquare(document.forms);
198-
// {"foo": [2, 42], "bar": 5}
209+
formsquare.parse(document.forms);
210+
//=> {"foo": [2, 42], "bar": 5}
199211

200-
[...document.forms].map(formsquare(() => true));
201-
// [{"foo": 2, "bar": 5}, {"foo": 42}]
212+
[...document.forms].map(formsquare.parse);
213+
//=> [{"foo": 2, "bar": 5}, {"foo": 42}]
202214
```
203215

204216
### Checkboxes
@@ -215,8 +227,8 @@ attribute:
215227

216228
```js
217229
const checkboxForm = document.getElementById("checkbox-form");
218-
formsquare(checkboxForm);
219-
// [false, true]
230+
formsquare.parse(checkboxForm);
231+
//=> [false, true]
220232
```
221233

222234
Checkboxes with explicit values are handled differently:
@@ -225,17 +237,17 @@ Checkboxes with explicit values are handled differently:
225237
checkboxForm[0].value = "false";
226238
checkboxForm[1].value = "on";
227239

228-
formsquare(checkboxForm);
229-
// ["on"]
240+
formsquare.parse(checkboxForm);
241+
//=> ["on"]
230242
```
231243

232244
And if no checkbox is checked, you will get the empty array:
233245

234246
```js
235247
checkboxForm[1].checked = false;
236248

237-
formsquare(checkboxForm);
238-
// []
249+
formsquare.parse(checkboxForm);
250+
//=> []
239251
```
240252

241253
### Files
@@ -254,15 +266,13 @@ Granted that a user uploaded the file `foo.txt` conatining the text
254266
`foo`:
255267

256268
```js
257-
formsquare(document.forms[0]).then((file) => {
258-
console.log(file);
259-
});
260-
261-
// {
262-
// "body": "Zm9v",
263-
// "name": "foo.txt",
264-
// "type": "text/plain"
265-
// }
269+
await formsquare.parse(document.forms[0]);
270+
271+
//=> {
272+
// body: "Zm9v",
273+
// name: "foo.txt",
274+
// type: "text/plain",
275+
// }
266276
```
267277

268278
Alternatives

Diff for: examples/index.html

+42-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
<title>Formsquare examples</title>
66
<style>
77
.example output {
8+
display: block;
89
font-family: monospace;
10+
max-width: 100%;
11+
overflow-x: auto;
912
white-space: pre;
1013
}
1114
</style>
@@ -31,7 +34,7 @@ <h3>Basic</h3>
3134

3235
const div = document.getElementById("readme-example-basic");
3336
const form = div.querySelector("form");
34-
const obj = formsquare(form, el => !el.disabled);
37+
const obj = formsquare.filter(el => !el.disabled).parse(form);
3538
const output = div.querySelector("output");
3639

3740
output.textContent = JSON.stringify(obj);
@@ -53,16 +56,16 @@ <h3>Basic (no module)</h3>
5356
{
5457
const div = document.getElementById("readme-example-basic-nomodule");
5558
const form = div.querySelector("form");
56-
const obj = formsquare(form, el => !el.disabled);
59+
const obj = formsquare.filter(el => !el.disabled).parse(form);
5760
const output = div.querySelector("output");
5861

5962
output.textContent = JSON.stringify(obj);
6063
}
6164
</script>
6265
</div>
6366

64-
<div class="example" id="readme-example-curry">
65-
<h3>Curry</h3>
67+
<div class="example" id="readme-example-filters">
68+
<h3>Filters</h3>
6669

6770
<form>
6871
<input value="foo">
@@ -74,21 +77,34 @@ <h3>Curry</h3>
7477
<input value="bar">
7578
</form>
7679

80+
<form>
81+
<input value="foo" disabled>
82+
<input value="bar" class="hidden">
83+
<input value="baz">
84+
</form>
85+
7786
<output></output>
7887

7988
<script type="module">
8089
import formsquare from "/dist/module/formsquare.js";
8190

82-
const div = document.getElementById("readme-example-curry");
83-
const parseForm = formsquare(el => !el.disabled);
84-
91+
const { parse } = formsquare.filter(el => !el.disabled);
92+
const div = document.getElementById("readme-example-filters");
8593
const forms = div.querySelectorAll("form");
8694
const output = div.querySelector("output");
95+
const parsed = [];
96+
97+
parsed.push(parse(forms[0]));
98+
parsed.push(parse(forms[1]))
99+
100+
parsed.push(
101+
formsquare
102+
.filter(el => !el.disabled)
103+
.filter(el => !el.classList.contains("hidden"))
104+
.parse(forms[2]),
105+
);
87106

88-
output.textContent = [...forms]
89-
.map(parseForm)
90-
.map(JSON.stringify)
91-
.join("\n");
107+
output.textContent = parsed.map(JSON.stringify).join("\n");
92108
</script>
93109
</div>
94110

@@ -104,7 +120,7 @@ <h3>Empty</h3>
104120

105121
const div = document.getElementById("readme-example-empty");
106122
const form = div.querySelector("form");
107-
const obj = formsquare(form);
123+
const obj = formsquare.parse(form);
108124
const output = div.querySelector("output");
109125

110126
output.textContent = JSON.stringify(obj);
@@ -128,10 +144,10 @@ <h3>Singleton</h3>
128144
const output = div.querySelector("output");
129145
const strings = [];
130146

131-
strings.push(JSON.stringify(formsquare(form)));
147+
strings.push(JSON.stringify(formsquare.parse(form)));
132148

133149
form[0].type = "text";
134-
strings.push(JSON.stringify(formsquare(form)));
150+
strings.push(JSON.stringify(formsquare.parse(form)));
135151

136152
output.textContent = strings.join("\n");
137153
</script>
@@ -155,11 +171,11 @@ <h3>Checkboxes</h3>
155171
const output = div.querySelector("output");
156172
const strings = [];
157173

158-
strings.push(JSON.stringify(formsquare(form)));
174+
strings.push(JSON.stringify(formsquare.parse(form)));
159175

160176
form[0].value = "false";
161177
form[1].value = "on"
162-
strings.push(JSON.stringify(formsquare(form)));
178+
strings.push(JSON.stringify(formsquare.parse(form)));
163179

164180
output.textContent = strings.join("\n");
165181
</script>
@@ -180,7 +196,7 @@ <h3>Week</h3>
180196
const div = document.getElementById("readme-example-week");
181197
const form = div.querySelector("form");
182198
const output = div.querySelector("output");
183-
const string = JSON.stringify(formsquare(form));
199+
const string = JSON.stringify(formsquare.parse(form));
184200

185201
output.textContent = string;
186202
</script>
@@ -202,8 +218,12 @@ <h3>Files</h3>
202218
const form = div.querySelector("form");
203219
const output = div.querySelector("output");
204220

205-
formsquare(form).then((data) => {
206-
output.textContent = JSON.stringify(data);
221+
form.addEventListener("input", event => {
222+
formsquare
223+
.parse(form)
224+
.then((data) => {
225+
output.textContent = JSON.stringify(data);
226+
});
207227
});
208228
</script>
209229
</div>
@@ -225,13 +245,14 @@ <h3>Collections of forms</h3>
225245
<script type="module">
226246
import formsquare from "/dist/module/formsquare.js";
227247

248+
const { parse } = formsquare;
228249
const div = document.getElementById("readme-example-form-collection");
229250
const forms = div.querySelectorAll("form");
230251
const output = div.querySelector("output");
231252
const strings = [];
232253

233-
strings.push(JSON.stringify(formsquare(forms)));
234-
strings.push(JSON.stringify([...forms].map(formsquare(() => true))));
254+
strings.push(JSON.stringify(parse(forms)));
255+
strings.push(JSON.stringify([...forms].map(parse)));
235256

236257
output.textContent = strings.join("\n");
237258
</script>

Diff for: src/formsquare.js

+30-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
1+
// @flow
2+
13
import { formElements } from "./elements.js";
24
import parse from "./parser.js";
35

4-
import { constant, filter } from "./utils.js";
6+
import { allPass, filter } from "./utils.js";
7+
8+
interface Formsquare {
9+
filter((HTMLElement) => boolean): Formsquare;
10+
parse(HTMLFormElement | Array<HTMLFormElement>): any;
11+
}
12+
13+
function newFormsquare({
14+
filters = [],
15+
}: {
16+
filters?: Array<(HTMLElement) => boolean>,
17+
} = {}): Formsquare {
18+
const formsquare: any = Object.create(null);
19+
20+
Object.defineProperty(formsquare, "filter", {
21+
value(p: HTMLElement => boolean): Formsquare {
22+
return newFormsquare({ filters: [...filters, p] });
23+
},
24+
});
525

6-
export default function formsquare(form, includeEl = constant(true)) {
7-
if (typeof form === "function") {
8-
// Curry.
9-
return f => formsquare(f, form);
10-
}
26+
Object.defineProperty(formsquare, "parse", {
27+
value(form: HTMLFormElement | Array<HTMLFormElement>): any {
28+
const elements = filter(allPass(filters), formElements(form));
1129

12-
const elements = filter(includeEl, formElements(form));
30+
return parse(elements);
31+
},
32+
});
1333

14-
return parse(elements);
34+
return formsquare;
1535
}
36+
37+
export default newFormsquare();

Diff for: src/module.js

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
// @flow
2+
13
export { default } from "./formsquare.js";

0 commit comments

Comments
 (0)