Skip to content

Commit 14ead95

Browse files
FieldsGroup and FieldsArray implemented.
1 parent f598ae0 commit 14ead95

File tree

15 files changed

+400
-88
lines changed

15 files changed

+400
-88
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from "react";
2+
import {
3+
FieldsArrayProps as CoreProps,
4+
FieldsArrayState as CoreState
5+
} from "simplr-forms/contracts";
6+
import { BaseFieldsArray } from "simplr-forms";
7+
8+
export interface FieldsArrayProps extends CoreProps {
9+
}
10+
11+
export interface FieldsArrayState extends CoreState {
12+
}
13+
14+
interface Dictionary {
15+
[key: string]: any;
16+
}
17+
18+
export class FieldsArray extends BaseFieldsArray<FieldsArrayProps, FieldsArrayState> {
19+
public Element: HTMLDivElement;
20+
21+
private setElementRef = (element: HTMLDivElement) => {
22+
this.Element = element;
23+
}
24+
25+
protected HTMLProps() {
26+
let notHTMLProps = ["name", "index", "destroyOnUnmount"];
27+
let newProps: { [id: string]: any } = {};
28+
29+
for (let key in this.props) {
30+
if ((this.props as Dictionary)[key] != null && notHTMLProps.indexOf(key) === -1) {
31+
newProps[key] = (this.props as Dictionary)[key];
32+
}
33+
}
34+
35+
return newProps;
36+
}
37+
38+
render() {
39+
return <div
40+
ref={this.setElementRef}
41+
{...this.HTMLProps() }
42+
>
43+
{this.props.children}
44+
</div>;
45+
}
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from "react";
2+
import {
3+
FieldsGroupProps as CoreProps,
4+
FieldsGroupState as CoreState
5+
} from "simplr-forms/contracts";
6+
import { BaseFieldsGroup } from "simplr-forms";
7+
8+
export interface FieldsGroupProps extends CoreProps {
9+
}
10+
11+
export interface FieldsGroupState extends CoreState {
12+
}
13+
14+
interface Dictionary {
15+
[key: string]: any;
16+
}
17+
18+
export class FieldsGroup extends BaseFieldsGroup<FieldsGroupProps, FieldsGroupState> {
19+
public Element: HTMLDivElement;
20+
21+
private setElementRef = (element: HTMLDivElement) => {
22+
this.Element = element;
23+
}
24+
25+
protected HTMLProps() {
26+
let notHTMLProps = ["name", "destroyOnUnmount"];
27+
let newProps: { [id: string]: any } = {};
28+
29+
for (let key in this.props) {
30+
if ((this.props as Dictionary)[key] != null && notHTMLProps.indexOf(key) === -1) {
31+
newProps[key] = (this.props as Dictionary)[key];
32+
}
33+
}
34+
35+
return newProps;
36+
}
37+
38+
render() {
39+
return <div
40+
ref={this.setElementRef}
41+
{...this.HTMLProps() }
42+
>
43+
{this.props.children}
44+
</div>;
45+
}
46+
}

packages/simplr-forms-dom/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ export * from "./components/text";
33
export * from "./components/submit";
44
export * from "./components/reset";
55
export * from "./components/clear";
6+
export * from "./components/fields-group";
7+
export * from "./components/fields-array";
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
describe("Fields Group Base", () => {
2+
xit("throws when registering an already existing id", () => {
3+
4+
});
5+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from "react";
2+
import {
3+
FieldsArrayProps,
4+
FieldsArrayState,
5+
FieldsArrayPropsObject
6+
} from "../contracts/fields-array";
7+
import { FieldsGroupChildContext } from "../contracts/fields-group";
8+
import { FieldContext } from "../contracts/field";
9+
import { FSHContainer } from "../stores/form-stores-handler";
10+
import { FormStore } from "../stores/form-store";
11+
import * as PropTypes from "prop-types";
12+
13+
export class BaseFieldsArray<TProps extends FieldsArrayProps,
14+
TState extends FieldsArrayState>
15+
extends React.Component<TProps, TState> {
16+
17+
public context: FieldContext;
18+
protected FieldsArrayId: string;
19+
protected get FieldsArrayPropsContext(): FieldsArrayPropsObject {
20+
return {};
21+
}
22+
23+
static contextTypes: PropTypes.ValidationMap<FieldContext> = {
24+
FormId: PropTypes.string,
25+
FormProps: PropTypes.object,
26+
FieldsGroupId: PropTypes.string,
27+
FieldsGroupProps: PropTypes.object
28+
};
29+
30+
protected get FormId(): string {
31+
return this.context.FormId;
32+
}
33+
34+
protected get FormStore(): FormStore {
35+
return FSHContainer.FormStoresHandler.GetStore(this.FormId);
36+
}
37+
38+
static childContextTypes: PropTypes.ValidationMap<FieldsGroupChildContext> = {
39+
FieldsGroupId: PropTypes.string,
40+
FieldsGroupProps: PropTypes.object
41+
};
42+
43+
getChildContext(): FieldsGroupChildContext {
44+
return {
45+
FieldsGroupId: this.FieldsArrayId,
46+
FieldsGroupProps: this.FieldsArrayPropsContext
47+
};
48+
}
49+
50+
componentWillMount() {
51+
this.FieldsArrayId = this.FormStore.GetFieldsGroupId(`${this.props.name}${this.props.index}`, this.context.FieldsGroupId);
52+
if (this.FormStore.GetState().FieldsGroups.has(this.FieldsArrayId)) {
53+
throw new Error(`simplr-forms: FieldsArray '${this.FieldsArrayId}' already exists in form '${this.FormId}'.`);
54+
}
55+
56+
this.FormStore.RegisterFieldsArray(this.FieldsArrayId, this.props.name, this.props.index, this.context.FieldsGroupId);
57+
}
58+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from "react";
2+
import {
3+
FieldsGroupProps,
4+
FieldsGroupState,
5+
FieldsGroupChildContext,
6+
FieldsGroupPropsObject
7+
} from "../contracts/fields-group";
8+
import { FieldContext } from "../contracts/field";
9+
import { FSHContainer } from "../stores/form-stores-handler";
10+
import { FormStore } from "../stores/form-store";
11+
import * as PropTypes from "prop-types";
12+
13+
export class BaseFieldsGroup<TProps extends FieldsGroupProps,
14+
TState extends FieldsGroupState>
15+
extends React.Component<TProps, TState> {
16+
17+
public context: FieldContext;
18+
protected FieldsGroupId: string;
19+
protected get FieldsGroupPropsContext(): FieldsGroupPropsObject {
20+
return {};
21+
}
22+
23+
static contextTypes: PropTypes.ValidationMap<FieldContext> = {
24+
FormId: PropTypes.string,
25+
FormProps: PropTypes.object,
26+
FieldsGroupId: PropTypes.string,
27+
FieldsGroupProps: PropTypes.object
28+
};
29+
30+
protected get FormId(): string {
31+
return this.context.FormId;
32+
}
33+
34+
protected get FormStore(): FormStore {
35+
return FSHContainer.FormStoresHandler.GetStore(this.FormId);
36+
}
37+
38+
static childContextTypes: PropTypes.ValidationMap<FieldsGroupChildContext> = {
39+
FieldsGroupId: PropTypes.string,
40+
FieldsGroupProps: PropTypes.object
41+
};
42+
43+
getChildContext(): FieldsGroupChildContext {
44+
return {
45+
FieldsGroupId: this.FieldsGroupId,
46+
FieldsGroupProps: this.FieldsGroupPropsContext
47+
};
48+
}
49+
50+
componentWillMount() {
51+
this.FieldsGroupId = this.FormStore.GetFieldsGroupId(this.props.name, this.context.FieldsGroupId);
52+
if (this.FormStore.GetState().FieldsGroups.has(this.FieldsGroupId)) {
53+
throw new Error(`simplr-forms: FieldsGroup '${this.FieldsGroupId}' already exists in form '${this.FormId}'.`);
54+
}
55+
56+
this.FormStore.RegisterFieldsGroup(this.FieldsGroupId, this.props.name, this.context.FieldsGroupId);
57+
}
58+
}

packages/simplr-forms/src/abstractions/core-field.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
FieldFormatValueCallback,
99
FieldNormalizeValueCallback,
1010
FieldParseValueCallback,
11-
FieldStateRecord
11+
FieldStoreStateRecord,
12+
FieldContext
1213
} from "../contracts/field";
1314
import * as ValueHelpers from "../utils/value-helpers";
1415
import { FormContextPropsObject } from "../contracts/form";
@@ -20,28 +21,20 @@ import { FSHContainer } from "../stores/form-stores-handler";
2021
import { FieldValidationType } from "../contracts/validation";
2122

2223
export interface CoreFieldState {
23-
Field?: FieldStateRecord;
24+
Field?: FieldStoreStateRecord;
2425
Form?: FormStoreStateRecord;
2526
Value?: FieldValue;
2627
}
2728

28-
export interface ParentContext {
29-
FormId: string;
30-
FormProps: FormContextPropsObject;
31-
FieldsGroupId: string;
32-
// FieldsGroupProps: FieldsGroupContextProps;
33-
}
34-
35-
3629
export abstract class CoreField<TProps extends CoreFieldProps, TState extends CoreFieldState>
3730
extends React.Component<TProps, TState> {
38-
public context: ParentContext;
31+
public context: FieldContext;
3932

40-
static contextTypes: PropTypes.ValidationMap<ParentContext> = {
33+
static contextTypes: PropTypes.ValidationMap<FieldContext> = {
4134
FormId: PropTypes.string,
4235
FormProps: PropTypes.object,
4336
FieldsGroupId: PropTypes.string,
44-
// FieldsGroupProps: PropTypes.object
37+
FieldsGroupProps: PropTypes.object
4538
};
4639

4740
static defaultProps: CoreFieldProps = {
@@ -269,6 +262,7 @@ export abstract class CoreField<TProps extends CoreFieldProps, TState extends Co
269262
const value = this.ProcessValueBeforeStore(this.RawValue);
270263
this.FormStore.RegisterField(
271264
this.FieldId,
265+
this.props.name,
272266
defaultValue,
273267
initialValue,
274268
value,

packages/simplr-forms/src/abstractions/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ export * from "./core-field";
22
export * from "./base-field";
33
export * from "./base-form";
44
export * from "./base-container";
5+
export * from "./base-fields-group";
6+
export * from "./base-fields-array";

packages/simplr-forms/src/actions/form-store.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,35 @@ import { FieldValue } from "../contracts/field";
33
export class StateChanged { }
44

55
export class FieldRegistered {
6-
constructor(private fieldId: string, private initialValue: FieldValue) { }
6+
constructor(private fieldId: string) { }
77

88
public get FieldId() {
99
return this.fieldId;
1010
}
11+
}
12+
13+
export class FieldsGroupRegistered {
14+
constructor(private fieldsGroupId: string) { }
15+
16+
public get FieldsGroupId() {
17+
return this.fieldsGroupId;
18+
}
19+
}
20+
21+
export class FieldsArrayRegistered {
22+
constructor(private fieldsGroupId: string) { }
1123

12-
public get InitialValue() {
13-
return this.initialValue;
24+
public get FieldsArrayId() {
25+
return this.fieldsGroupId;
1426
}
1527
}
1628

1729
export class ValueChanged {
18-
constructor(private fieldId: string, private newValue: FieldValue) { }
30+
constructor(private fieldId: string) { }
1931

2032
public get FieldId() {
2133
return this.fieldId;
2234
}
23-
24-
public get NewValue() {
25-
return this.newValue;
26-
}
2735
}
2836

2937
export class FieldPropsChanged {

packages/simplr-forms/src/contracts/field.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { TypedRecord } from "typed-immutable-record";
22
import { FormErrorRecord } from "./error";
33
import { FieldValidationType } from "./validation";
4+
import { FormContextPropsObject } from "./form";
5+
import { FieldsGroupContextProps } from "./fields-group";
46

57
// Field value can be of any type or undefined
68
export type FieldValue = any | undefined;
@@ -26,7 +28,8 @@ export interface FieldProps extends CoreFieldProps {
2628
value?: FieldValue;
2729
}
2830

29-
export interface FieldState {
31+
export interface FieldStoreState {
32+
Name: string;
3033
DefaultValue: FieldValue;
3134
InitialValue: FieldValue;
3235
Value: FieldValue;
@@ -37,10 +40,18 @@ export interface FieldState {
3740
FieldsGroup?: {
3841
Id: string;
3942
};
40-
Props?: FieldStatePropsRecord;
43+
Props?: FieldStorePropsRecord;
4144
}
4245

43-
export type FieldStateProps = CoreFieldProps & React.Props<any>;
46+
export type FieldStoreProps = CoreFieldProps & React.Props<any>;
4447

45-
export interface FieldStateRecord extends TypedRecord<FieldStateRecord>, FieldState { }
46-
export interface FieldStatePropsRecord extends TypedRecord<FieldStatePropsRecord>, FieldStateProps { }
48+
export interface FieldStoreStateRecord extends TypedRecord<FieldStoreStateRecord>, FieldStoreState { }
49+
50+
export interface FieldStorePropsRecord extends TypedRecord<FieldStorePropsRecord>, FieldStoreProps { }
51+
52+
export interface FieldContext {
53+
FormId: string;
54+
FormProps: FormContextPropsObject;
55+
FieldsGroupId: string;
56+
FieldsGroupProps: FieldsGroupContextProps;
57+
}

0 commit comments

Comments
 (0)