Skip to content

Commit 953b665

Browse files
Controlled mechanism implemented and onChange types for Field and Form updated.
1 parent c6d1a66 commit 953b665

File tree

9 files changed

+83
-31
lines changed

9 files changed

+83
-31
lines changed

packages/simplr-forms-dom/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "simplr-forms-dom",
3-
"version": "4.0.1-alpha.2",
3+
"version": "4.0.1-alpha.3",
44
"description": "DOM components for simplr-forms.",
55
"repository": "SimplrJS/simplr-forms",
66
"homepage": "https://github.com/SimplrJS/simplr-forms",
@@ -57,11 +57,12 @@
5757
"@types/react": "^15.0.24",
5858
"@types/prop-types": "^15.5.1",
5959
"immutable": "^3.8.1",
60-
"simplr-forms": "^4.0.1-alpha.2",
60+
"simplr-forms": "^4.0.1-alpha.3",
6161
"typed-immutable-record": "0.0.6",
6262
"react": "^15.5.4",
6363
"react-dom": "^15.5.4",
64-
"prop-types": "^15.5.8"
64+
"prop-types": "^15.5.8",
65+
"tslib": "^1.7.1"
6566
},
6667
"jest": {
6768
"setupTestFrameworkScriptFile": "./node_modules/jest-enzyme/lib/index.js",

packages/simplr-forms-dom/src/components/text.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ import * as React from "react";
22
import { FieldValue } from "simplr-forms/contracts";
33
import { DomFieldProps } from "../contracts/field";
44

5-
import { BaseDomField, BaseDomFieldState } from "../abstractions/base-dom-field";
6-
import { FieldOnChangeCallback } from "../contracts/field";
5+
import {
6+
BaseDomField,
7+
BaseDomFieldState
8+
} from "../abstractions/base-dom-field";
9+
import {
10+
FieldOnChangeCallback,
11+
FieldOnChangeInternalCallback
12+
} from "../contracts/field";
13+
14+
export type TextOnChangeCallback = FieldOnChangeCallback<HTMLInputElement>;
715

816
/**
917
* Override the differences between extended interfaces.
10-
*
11-
* @export
12-
* @interface Props
13-
* @extends {CoreContracts.FieldProps}
14-
* @extends {React.HTMLProps<HTMLInputElement>}
1518
*/
1619
export interface TextProps extends DomFieldProps, React.HTMLProps<HTMLInputElement> {
1720
name: string;
1821
onFocus?: React.EventHandler<React.FocusEvent<HTMLInputElement>>;
1922
onBlur?: React.EventHandler<React.FocusEvent<HTMLInputElement>>;
20-
onChange?: FieldOnChangeCallback<HTMLInputElement>;
23+
onChange?: TextOnChangeCallback & FieldOnChangeInternalCallback;
2124
ref?: any;
2225

2326
defaultValue?: FieldValue;
@@ -30,9 +33,13 @@ export class Text extends BaseDomField<TextProps, BaseDomFieldState> {
3033
}
3134

3235
protected OnChangeHandler: React.FormEventHandler<HTMLInputElement> = (event) => {
33-
this.OnValueChange(this.GetValueFromEvent(event));
34-
35-
const newValue = this.FormStore.GetField(this.FieldId).Value;
36+
let newValue: string | undefined;
37+
if (!this.IsControlled) {
38+
this.OnValueChange(this.GetValueFromEvent(event));
39+
newValue = this.FormStore.GetField(this.FieldId).Value;
40+
} else {
41+
newValue = this.GetValueFromEvent(event);
42+
}
3643

3744
if (this.props.onChange != null) {
3845
this.props.onChange(event, newValue, this.FieldId, this.FormId);

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ import {
66
} from "simplr-forms/contracts";
77
import { FormStore } from "simplr-forms/stores";
88

9-
export interface FieldOnChangeCallback<TElement> extends React.EventHandler<React.FormEvent<TElement>> {
10-
(event: React.FormEvent<TElement> | undefined, newValue: FieldValue, fieldId: string, formId: string): void;
9+
export interface FieldOnChangeInternalCallback {
10+
(event: React.FormEvent<any>, ...parameters: any[]): void;
11+
}
12+
13+
export interface FieldOnChangeCallback<TElement> {
14+
(event: React.FormEvent<TElement>, newValue: FieldValue, fieldId: string, formId: string): void;
1115
}
1216

1317
export interface DomFieldProps extends FieldProps {

packages/simplr-forms-dom/src/contracts/form.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@ import { FormProps as CoreFormProps } from "simplr-forms/contracts";
44
import { FormStore } from "simplr-forms/stores";
55
import {
66
FieldOnChangeCallback,
7+
FieldOnChangeInternalCallback,
78
DomFieldTemplateCallback
89
} from "../contracts/field";
910

10-
export interface FormOnSubmitCallback extends React.FormEventHandler<HTMLFormElement> {
11+
export interface FormOnSubmitInternalCallback {
12+
(event: React.FormEvent<HTMLFormElement>, ...parameters: any[]): void | Promise<never> | FormError | string;
13+
}
14+
15+
export interface FormOnSubmitCallback {
1116
(event: React.FormEvent<HTMLFormElement>, store: FormStore): void | Promise<never> | FormError | string;
1217
}
1318

1419
export interface FormProps extends CoreFormProps, React.HTMLProps<HTMLFormElement> {
15-
onSubmit?: FormOnSubmitCallback;
16-
onChange?: FieldOnChangeCallback<any>;
20+
onSubmit?: FormOnSubmitCallback & FormOnSubmitInternalCallback;
21+
onChange?: FieldOnChangeCallback<any> & FieldOnChangeInternalCallback;
1722
preventSubmitDefaultAndPropagation?: boolean;
1823
template?: DomFieldTemplateCallback;
1924
// tslint:disable-next-line:max-line-length

packages/simplr-forms-dom/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"declaration": true,
1212
"pretty": true,
1313
"strict": true,
14+
"noEmitHelpers": true,
1415
"lib": [
1516
"dom",
1617
"dom.iterable",

packages/simplr-forms/package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "simplr-forms",
3-
"version": "4.0.1-alpha.2",
3+
"version": "4.0.1-alpha.3",
44
"description": "Shared simplr-forms logic.",
55
"repository": "SimplrJS/simplr-forms",
66
"homepage": "https://github.com/SimplrJS/simplr-forms",
@@ -53,18 +53,19 @@
5353
"webpack": "^2.5.1"
5454
},
5555
"dependencies": {
56+
"@types/fbemitter": "^2.0.32",
57+
"@types/flux": "^3.0.1",
58+
"@types/prop-types": "^15.5.1",
59+
"@types/react": "^15.0.22",
60+
"@types/react-dom": "^15.5.0",
5661
"action-emitter": "^0.2.1",
5762
"fbemitter": "^2.1.1",
5863
"immutable": "^3.8.1",
59-
"typed-immutable-record": "^0.0.6",
64+
"prop-types": "^15.5.8",
6065
"react": "15.5.4",
6166
"react-dom": "^15.5.4",
62-
"prop-types": "^15.5.8",
63-
"@types/fbemitter": "^2.0.32",
64-
"@types/flux": "^3.0.1",
65-
"@types/prop-types": "^15.5.1",
66-
"@types/react": "^15.0.22",
67-
"@types/react-dom": "^15.5.0"
67+
"tslib": "^1.7.1",
68+
"typed-immutable-record": "^0.0.6"
6869
},
6970
"jest": {
7071
"setupTestFrameworkScriptFile": "./node_modules/jest-enzyme/lib/index.js",

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ export interface BaseFieldState extends CoreFieldState {
99
}
1010

1111
export abstract class BaseField<TProps extends FieldProps, TState extends BaseFieldState> extends CoreField<TProps, TState> {
12+
componentWillReceiveProps(nextProps: FieldProps): void {
13+
super.componentWillReceiveProps(nextProps);
14+
15+
if (this.IsControlled) {
16+
const newValue = this.ProcessValueBeforeStore(this.props.value);
17+
this.FormStore.UpdateFieldValue(this.FieldId, newValue);
18+
}
19+
}
20+
1221
protected abstract get RawDefaultValue(): FieldValue;
1322

1423
protected get RawInitialValue(): FieldValue {
@@ -19,6 +28,29 @@ export abstract class BaseField<TProps extends FieldProps, TState extends BaseFi
1928
return this.props.value;
2029
}
2130

31+
protected get IsControlled(): boolean {
32+
return this.props.value !== undefined;
33+
}
34+
35+
protected get ControlledValue(): FieldValue {
36+
return this.props.value;
37+
}
38+
39+
protected get Value(): FieldValue {
40+
if (this.IsControlled) {
41+
return this.ControlledValue;
42+
}
43+
44+
// If state is defined
45+
if (this.state != null && this.state.Value != null) {
46+
// Return its value
47+
return this.state.Value;
48+
}
49+
50+
// Return default value
51+
return this.RawDefaultValue;
52+
}
53+
2254
protected get Disabled(): boolean | undefined {
2355
// FormStore can only enforce disabling
2456
if (this.FormStore.GetState().Disabled === true) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,13 @@ export abstract class CoreField<TProps extends CoreFieldProps, TState extends Co
115115
/**
116116
* Is field currently controlled.
117117
*/
118-
protected get IsControlled(): boolean {
119-
return false;
120-
}
118+
protected abstract get IsControlled(): boolean;
121119

122120
/**
123121
* Current or default field value.
124122
*/
125123
protected get Value(): FieldValue {
126-
// If field is defined
124+
// If state is defined
127125
if (this.state != null && this.state.Value != null) {
128126
// Return its value
129127
return this.state.Value;
@@ -133,6 +131,8 @@ export abstract class CoreField<TProps extends CoreFieldProps, TState extends Co
133131
return this.RawDefaultValue;
134132
}
135133

134+
protected abstract get ControlledValue(): FieldValue;
135+
136136
protected ProcessValueBeforeStore(value: FieldValue): FieldValue {
137137
// Parse and normalize value
138138
if (value != null) {

packages/simplr-forms/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"declaration": true,
1212
"pretty": true,
1313
"strict": true,
14+
"noEmitHelpers": true,
1415
"lib": [
1516
"dom",
1617
"dom.iterable",

0 commit comments

Comments
 (0)