Skip to content

Commit 3464c9a

Browse files
committed
Release 0.11.1
1 parent 96fe160 commit 3464c9a

File tree

11 files changed

+224
-98
lines changed

11 files changed

+224
-98
lines changed

README.md

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,47 @@ export default class Example extends Component {
122122
}
123123
```
124124

125+
## Simple arrays
126+
127+
If you are using fieldset with simple array do not enter the name attribute.
128+
129+
```js
130+
import React, { Component } from 'react';
131+
import Form from 'react-form-controlled';
132+
133+
export default class Example extends Component {
134+
constructor(props, context) {
135+
super(props, context);
136+
137+
this.state = {
138+
items: [123, 222]
139+
};
140+
}
141+
142+
handleChange(state) {
143+
this.setState(state);
144+
}
145+
146+
handleSubmit(state) {
147+
alert(`Hi ${state.users[0].firstName}`);
148+
}
149+
150+
render() {
151+
const formData = this.state;
152+
153+
return (
154+
<Form value={formData} onChange={this.handleChange.bind(this)} onSubmit={this.handleSubmit.bind(this)}>
155+
<fieldset name="items">
156+
<input type="text" />
157+
</fieldset>
158+
159+
<button type="submit">Submit</button>
160+
</Form>
161+
);
162+
}
163+
}
164+
```
165+
125166
## Complex objects
126167

127168
If you want to use complex names you can use dot or array notation.
@@ -237,8 +278,8 @@ export default class Example extends Component {
237278
## Indexes
238279

239280
If you are using arrays with fieldset you want to use indexes.
240-
Index component has one parameter named value.
241-
It is an function and it is optional. You can format your index value with it.
281+
Index component has one parameter named format.
282+
It is a function and it is optional. You can format your index value with it.
242283
Default behavior is: 1. 2. 3. etc...
243284

244285
```js
@@ -273,7 +314,7 @@ export default class Component extends Component {
273314
<Form value={formData} onChange={this.handleChange.bind(this)} onSubmit={this.handleSubmit.bind(this)}>
274315
<fieldset name="users">
275316
<label>
276-
<Index value={(index) => `${index})`} />
317+
<Index format={(index) => `${index})`} />
277318
<input type="text" name="firstName" placeholder="First name" />
278319
</label>
279320
</fieldset>
@@ -285,6 +326,60 @@ export default class Component extends Component {
285326
}
286327
```
287328

329+
## Combination with other components
330+
331+
If you want to disable autoreplace of the standard components like an input, select, textarea etc...
332+
You can disable this behavior with the form parameter replace={false}.
333+
This feature is great if you want to use this library with other 3rd libraries.
334+
You will be able to use Input, Select, Textarea and Fieldset.
335+
336+
```js
337+
import Form, { Input, Select, Textarea, Fieldset } from from 'react-form-controlled';
338+
339+
export default class Component extends Component {
340+
constructor(props, context) {
341+
super(props, context);
342+
343+
this.state = {
344+
users: [{
345+
firstName: 'Zlatko',
346+
}, {
347+
firstName: 'Livia',
348+
}]
349+
};
350+
}
351+
352+
handleChange(state) {
353+
this.setState(state);
354+
}
355+
356+
handleSubmit(state) {
357+
alert(`Hi ${state.users[0].firstName}`);
358+
}
359+
360+
render() {
361+
const formData = this.state;
362+
363+
return (
364+
<Form
365+
value={formData}
366+
replace={false}
367+
onChange={this.handleChange.bind(this)}
368+
onSubmit={this.handleSubmit.bind(this)}>
369+
<Fieldset name="users">
370+
<label>
371+
<Index format={(index) => `${index})`} />
372+
<Input type="text" name="firstName" placeholder="First name" />
373+
</label>
374+
</Fieldset>
375+
376+
<button type="submit">Submit</button>
377+
</Form>
378+
);
379+
}
380+
}
381+
```
382+
288383
# Support for schemas and validation?
289384

290385
Yes, you can use JSON schema as property to the form. Why JSON schema? Because it is a standard.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-form-controlled",
3-
"version": "0.10.5",
3+
"version": "0.11.1",
44
"description": "React controlled form components. The main idea is to make forms as simple as possible.",
55
"author": {
66
"name": "Zlatko Fedor",

src/Element.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ export default class Element extends Component {
77
name: PropTypes.oneOfType([
88
PropTypes.string,
99
PropTypes.number,
10-
]).isRequired,
10+
]),
1111
originalProps: PropTypes.object,
12+
className: PropTypes.string,
1213
};
1314

15+
getPath() {
16+
return this.props.path;
17+
}
18+
1419
render() {
1520
return null;
1621
}

src/Fieldset.jsx

Lines changed: 17 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ import traverse from './utils/traverse';
99
import Input from './Input';
1010
import Select from './Select';
1111
import Textarea from './Textarea';
12-
13-
function isNumeric(value) {
14-
return !isNaN(parseFloat(value)) && isFinite(value);
15-
}
12+
import Index from './Index';
1613

1714
export default class Fieldset extends Element {
1815
static isElement = true;
@@ -21,30 +18,36 @@ export default class Fieldset extends Element {
2118
...Element.propTypes,
2219
onChange: PropTypes.func,
2320
map: PropTypes.bool.isRequired,
21+
index: PropTypes.number,
2422
};
2523

2624
static defaultProps = {
2725
map: true,
2826
};
2927

3028
getValue(name) {
31-
const value = this.props.value || {};
29+
const { value = {} } = this.props;
30+
31+
if (typeof name === 'undefined' || name === null) {
32+
return value;
33+
}
34+
3235
return get(value, name);
3336
}
3437

35-
setValue(name, value) {
38+
setValue(name, value, component) {
3639
const currentValue = this.props.value;
3740
const newState = isArray(currentValue)
3841
? [...this.props.value]
3942
: {...this.props.value};
4043

4144
set(newState, name, value);
4245

43-
this.props.onChange(newState);
46+
this.props.onChange(newState, component);
4447
}
4548

46-
getPath(name) {
47-
if (!name) {
49+
buildPath(name) {
50+
if (typeof name === 'undefined' || name === null) {
4851
return void 0;
4952
}
5053

@@ -57,44 +60,11 @@ export default class Fieldset extends Element {
5760
return this.props.form.props;
5861
}
5962

60-
handleChange(evn) {
61-
const target = evn.target;
62-
if (!target) {
63-
return;
64-
}
65-
66-
const propertyName = target.getAttribute('data-property');
67-
if (!propertyName) {
68-
return;
69-
}
70-
71-
// IE < 10 bug catcher
72-
try {
73-
evn.stopPropagation();
74-
} catch (err) {
75-
console.log(err.message);
76-
}
77-
78-
let value = target.type === 'checkbox'
79-
? !!target.checked
80-
: target.value;
81-
82-
if (target.type === 'number' && isNumeric(value)) {
83-
// fix decimal numbers
84-
const numberValue = Number(value);
85-
if (numberValue.toString() === value) {
86-
value = numberValue;
87-
}
88-
}
89-
90-
this.setValue(propertyName, value);
91-
}
92-
9363
_registerChildren(children, topLevel) {
9464
const { value, map } = this.props;
9565

9666
if (topLevel && map && isArray(value)) {
97-
return value.map((value, index) => {
67+
return value.map((currentValue, index) => {
9868
return this._registerChildren((
9969
<Fieldset name={index} key={index} index={index}>
10070
{children}
@@ -108,24 +78,17 @@ export default class Fieldset extends Element {
10878
return void 0;
10979
}
11080

111-
if (!child.props.name && child.props.name !== 0) {
112-
return cloneElement(child, {
113-
originalProps: child.props,
114-
form: this.props.form || this,
115-
fieldset: this,
116-
});
117-
}
118-
11981
const currentValue = this.getValue(child.props.name);
82+
const currentPath = this.buildPath(child.props.name);
12083

12184
return cloneElement(child, {
12285
originalProps: child.props,
12386
value: typeof child.props.value !== 'undefined' ? child.props.value : currentValue,
12487
currentValue,
12588
form: this.props.form || this,
12689
fieldset: this,
127-
path: this.getPath(child.props.name),
128-
onChange: (value) => this.setValue(child.props.name, value),
90+
path: currentPath,
91+
onChange: (value, component) => this.setValue(child.props.name, value, component),
12992
});
13093
}, (child) => {
13194
const { replace } = this.getFormProps();
@@ -149,7 +112,7 @@ export default class Fieldset extends Element {
149112
const children = this._registerChildren(this.props.children, true);
150113

151114
return (
152-
<fieldset onChange={this.handleChange.bind(this)} name={this.props.name}>
115+
<fieldset name={this.props.name}>
153116
{children}
154117
</fieldset>
155118
);

src/FieldsetIndex.jsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ export default class FieldsetIndex extends Element {
66

77
static propTypes = {
88
...Element.propTypes,
9-
name: PropTypes.string,
9+
format: PropTypes.func,
1010
};
1111

12+
static omg = 123;
13+
1214
render() {
13-
const { fieldset, value, className } = this.props;
15+
const { format, className, fieldset } = this.props;
1416
const index = fieldset.props.index;
1517

16-
if (typeof value === 'function') {
17-
return <span className={className}>{value(index)}</span>;
18+
if (typeof format === 'function') {
19+
return <span className={className}>{format(index)}</span>;
1820
}
1921

20-
return <span className={className}>{value ? value : `${index + 1}.`}</span>;
22+
return <span className={className}>{`${index + 1}.`}</span>;
2123
}
2224
}

src/Form.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ export default class Form extends Fieldset {
3939

4040
const ajv = Ajv(props.ajvOptions);
4141
this.validateData = ajv.compile(props.schema || {});
42+
43+
this.handleSubmit = this.handleSubmit.bind(this);
44+
this.handleChange = this.handleChange.bind(this);
4245
}
4346

4447
getFormProps() {
@@ -130,8 +133,6 @@ export default class Form extends Fieldset {
130133

131134
handleChange(evn) {
132135
this.errors = [];
133-
134-
super.handleChange(evn);
135136
}
136137

137138
render() {
@@ -146,8 +147,8 @@ export default class Form extends Fieldset {
146147
method={this.props.method}
147148
action={this.props.action}
148149
className={this.props.className || 'form'}
149-
onSubmit={this.handleSubmit.bind(this)}
150-
onChange={this.handleChange.bind(this)}>
150+
onSubmit={this.handleSubmit}
151+
onChange={this.handleChange}>
151152
{children}
152153
</form>
153154
);

0 commit comments

Comments
 (0)