Skip to content

Commit 4a65261

Browse files
author
Patrick Sachs
authored
Merge pull request #11 from PatrickSachs/2
core version 2
2 parents 377ea90 + dd9e84f commit 4a65261

File tree

8 files changed

+161
-22
lines changed

8 files changed

+161
-22
lines changed

packages/bulma/src/TextArea/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from "react";
22
import ValidationResult from "@react-formilicious/core/validators/ValidationResult";
3-
import { TextArea as CoreTextArea } from "@react-formilicious/core/inputs";
43

54
export default class TextArea extends React.Component {
65
static getDefaultValue() {
@@ -23,7 +22,7 @@ export default class TextArea extends React.Component {
2322
<div className="field">
2423
<label className="label">{name}</label>
2524
<div className="contol">
26-
<CoreTextArea
25+
<textarea
2726
className="textarea"
2827
onChange={e => onChange(e.target.value)}
2928
disabled={waiting}

packages/bulma/src/TextField/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from "react";
22
import ValidationResult from "@react-formilicious/core/validators/ValidationResult";
3-
import { Input } from "@react-formilicious/core/inputs";
43

54
export default class TextField extends React.Component {
65
static getDefaultValue() {
@@ -27,7 +26,7 @@ export default class TextField extends React.Component {
2726
<div className="field">
2827
<label className="label">{name}</label>
2928
<div className="contol">
30-
<Input
29+
<input
3130
className="input"
3231
onChange={e => onChange(e.target.value)}
3332
type={this.getType(mode)}

packages/core/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this library will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this library adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## 2.0.1
8+
9+
* Objects can now be nested(e.g. the field key `key1.key2` will correctly traverse the object chain) @PatrickSachs.
10+
11+
## 2.0.0
12+
13+
* Removed async field return values for now @PatrickSachs.
14+
715
## 1.0.3
816

917
* Fixed a bug that would not update fields when changing form data after intialization @PatrickSachs.

packages/core/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@react-formilicious/core",
3-
"version": "1.0.3",
3+
"version": "2.0.1",
44
"description": "Easy to use, modular and simply delicious forms for React. 📝",
55
"author": "PatrickSachs",
66
"license": "MIT",

packages/core/src/helpers/at.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Finds a property in an object. Property can be nested by using ".".
3+
* @param {string | string[]} path The path of the property.
4+
* @param {any} obj The object to get the property in.
5+
*/
6+
const at = (path, obj) => {
7+
if (path === "" || Array.isArray(path) && path.length === 0) {
8+
return obj;
9+
}
10+
path = Array.isArray(path) ? path : path.split(".");
11+
for (let i = 0; i < path.length; i++) {
12+
obj = obj && obj[path[i]];
13+
}
14+
return obj;
15+
}
16+
17+
/**
18+
* Puts an object into an object. MUTATES THE OBJECT.
19+
* @param {string | string[]} path The path of the property.
20+
* @param {any} obj The object to put the property in.
21+
*/
22+
export const putAt = (path, obj, value) => {
23+
if (path === "" || Array.isArray(path) && path.length === 0) {
24+
return value;
25+
}
26+
const root = obj;
27+
path = Array.isArray(path) ? path : path.split(".");
28+
for (let i = 0; i < path.length - 1; i++) {
29+
const newObj = obj[path[i]];
30+
if (newObj === null || typeof newObj !== "object") {
31+
newObj = {};
32+
obj[path[i]] = newObj;
33+
}
34+
obj = newObj;
35+
}
36+
obj[path[path.length - 1]] = value;
37+
return root;
38+
};
39+
40+
export default at;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import at, { putAt } from "./at";
2+
3+
const getObj = () => ({
4+
key1: 1,
5+
key2: 2,
6+
key3: 3,
7+
key4: {
8+
key1: 4,
9+
key2: {
10+
key1: 5,
11+
key2: 6
12+
},
13+
key3: 7
14+
}
15+
});
16+
17+
const run = () => {
18+
describe(at.name, () => {
19+
test("root", () => {
20+
const input = "";
21+
const obj = getObj();
22+
const result = at(input, obj);
23+
expect(result).toEqual(obj);
24+
});
25+
26+
test("non existant", () => {
27+
const input = "test";
28+
const obj = getObj();
29+
const result = at(input, obj);
30+
expect(result).toEqual(undefined);
31+
});
32+
33+
test("1 layer", () => {
34+
const input = "key1";
35+
const obj = getObj();
36+
const result = at(input, obj);
37+
expect(result).toEqual(1);
38+
});
39+
40+
test("2 layer", () => {
41+
const input = "key4.key1";
42+
const obj = getObj();
43+
const result = at(input, obj);
44+
expect(result).toEqual(4);
45+
});
46+
47+
test("3 layer", () => {
48+
const input = "key4.key2.key2";
49+
const obj = getObj();
50+
const result = at(input, obj);
51+
expect(result).toEqual(6);
52+
});
53+
});
54+
55+
describe(putAt.name, () => {
56+
test("root", () => {
57+
const input = "";
58+
const obj = getObj();
59+
const result = putAt(input, obj, "value");
60+
expect(result).toEqual("value");
61+
});
62+
63+
test("non existant", () => {
64+
const input = "test";
65+
const obj = getObj();
66+
const result = putAt(input, obj, "value");
67+
const shouldBe = getObj();
68+
shouldBe.test = "value";
69+
expect(result).toEqual(shouldBe);
70+
});
71+
72+
test("1 layer", () => {
73+
const input = "key1";
74+
const obj = getObj();
75+
const result = putAt(input, obj, "value");
76+
const shouldBe = getObj();
77+
shouldBe.key1 = "value";
78+
expect(result).toEqual(shouldBe);
79+
});
80+
81+
test("2 layer", () => {
82+
const input = "key4.key1";
83+
const obj = getObj();
84+
const result = putAt(input, obj, "value");
85+
const shouldBe = getObj();
86+
shouldBe.key4.key1 = "value";
87+
expect(result).toEqual(shouldBe);
88+
});
89+
90+
test("3 layer", () => {
91+
const input = "key4.key2.key2";
92+
const obj = getObj();
93+
const result = putAt(input, obj, "value");
94+
const shouldBe = getObj();
95+
shouldBe.key4.key2.key2 = "value";
96+
expect(result).toEqual(shouldBe);
97+
});
98+
});
99+
};
100+
101+
run();

packages/core/src/index.js

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import makePromise from "./helpers/makePromise";
44
import { sanitizeValidationResult, sanitizeOnSubmitResult } from "./logic/validators/sanitization";
55
import ValidationResult from "./validators/ValidationResult";
66
import { mustResolveWithin } from "./helpers/timeout";
7+
import at, { putAt } from "./helpers/at";
78
import defaultButtons from "./defaultButtons";
89
import { runValidator } from "./logic/validators/validation";
910
import filterObject, { isNotUndefined } from "./helpers/filterObject";
@@ -120,7 +121,7 @@ export default class Form extends React.Component {
120121
if (field && field.value !== undefined) return field.value;
121122
const element = this.getElement(key);
122123
if (!element.ignoreData) {
123-
const initialValue = this.props.data[key] || this.state.initialData[key];
124+
const initialValue = at(key, this.props.data) || at(key, this.state.initialData);
124125
if (initialValue !== undefined) return initialValue;
125126
}
126127
return element.type.getDefaultValue();
@@ -143,9 +144,7 @@ export default class Form extends React.Component {
143144

144145
getFlatDataStructure() {
145146
const { elements } = this.props;
146-
return elements.reduce((acc, element) => {
147-
return { ...acc, [element.key]: this.getFieldValue(element.key) };
148-
}, {});
147+
return elements.reduce((acc, element) => putAt(element.key, acc, this.getFieldValue(element.key)), {});
149148
}
150149

151150
onChange() {
@@ -169,17 +168,17 @@ export default class Form extends React.Component {
169168
return true;
170169
}
171170

172-
async onChangeField(key, rawValue) {
171+
async onChangeField(key, value) {
173172
if (this.state.waiting) {
174-
console.warn("[react-formilicious]", "Tried to update field \"" + key + "\" with the following value while form was in waiting state.", rawValue);
173+
console.warn("[react-formilicious]", "Tried to update field \"" + key + "\" with the following value while form was in waiting state.", value);
175174
return;
176175
}
177176
const { fieldTimeout = 3000 } = this.props;
178177
const element = this.getElement(key);
179178
const field = await this.putFieldValue(key, {
180-
version: this.getFieldVersion(key) + 1
179+
version: this.getFieldVersion(key) + 1,
180+
value: value
181181
});
182-
let value = field.value;
183182
try {
184183
await mustResolveWithin((async () => {
185184
// First set the field to pending, then let's start the work.
@@ -188,19 +187,12 @@ export default class Form extends React.Component {
188187
validated: "pending",
189188
message: null
190189
});
191-
value = await makePromise(rawValue);
192-
// Once the field value has been resolved, set it to the field, and then start validating.
193-
this.fieldMustBeVersion(key, field.version);
194-
await this.putFieldValue(key, {
195-
value: value
196-
});
197190
const validation = await runValidator(element.validator, value, this.getFlatDataStructure());
198191
// Once we have validated put the result into the field.
199192
this.fieldMustBeVersion(key, field.version);
200193
await this.putFieldValue(key, {
201194
validated: validation.validated,
202-
message: validation.message,
203-
value: value
195+
message: validation.message
204196
});
205197
})(), fieldTimeout);
206198
// Fire the onChange event

0 commit comments

Comments
 (0)