Skip to content

Commit 13c0ff8

Browse files
author
bietkul
committed
Fixed updateOn issues
1 parent a951591 commit 13c0ff8

File tree

3 files changed

+71
-24
lines changed

3 files changed

+71
-24
lines changed

index.d.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ declare abstract class AbstractControl {
6666
statusChanges: Observable<any>;
6767
value: any;
6868
status: string;
69+
/**
70+
* A control is `submitted` if the `handleSubmit` event has been triggered on it.
71+
*/
72+
submitted: boolean;
6973
/**
7074
* A control is `valid` when its `status === VALID`.
7175
*
@@ -174,6 +178,19 @@ declare abstract class AbstractControl {
174178
* Updates value, validity & status of the control & parent
175179
*/
176180
updateValueAndValidity: (opts?: {onlySelf?: boolean, emitEvent?: boolean}) => void;
181+
/**
182+
* Marks the control as `submitted`.
183+
*
184+
* If the control has any children, it will also mark all children as `submitted`
185+
*/
186+
markAsSubmitted: (opts?: {emitEvent?: boolean}) => void;
187+
/**
188+
* Marks the control as `unsubmitted`.
189+
*
190+
* If the control has any children, it will also mark all children as `unsubmitted`.
191+
*
192+
*/
193+
markAsUnsubmitted: (opts?: {emitEvent?: boolean}) => void;
177194
/**
178195
* Marks the control as `touched`.
179196
*
@@ -378,10 +395,6 @@ declare module "react-reactive-form" {
378395
* Length of the control array.
379396
*/
380397
length: number;
381-
/**
382-
* A form array is submitted if the `handleSubmit` event has been triggered on it.
383-
*/
384-
submitted: boolean;
385398
/**
386399
* Get the `AbstractControl` at the given `index` in the array.
387400
*/
@@ -567,10 +580,6 @@ declare module "react-reactive-form" {
567580
validatorOrOpts?: ValidatorFn|ValidatorFn[]|AbstractControlOptions|null,
568581
asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null)
569582
controls: {[key: string]: AbstractControl}
570-
/**
571-
* A form group is submitted if the `handleSubmit` event has been triggered on it.
572-
*/
573-
submitted: boolean;
574583
/**
575584
* Registers a control with the group's list of controls.
576585
*

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-reactive-form",
3-
"version": "1.0.8",
3+
"version": "1.0.9",
44
"description": "Angular like Reactive Forms in React",
55
"keywords": [
66
"forms",

src/model.js

+53-15
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export class AbstractControl {
153153
* a `blur` event on it.
154154
*/
155155
this.touched = false;
156+
this.submitted = false;
156157
/**
157158
* A control is `pristine` if the user has not yet changed
158159
* the value in the UI.
@@ -300,13 +301,13 @@ export class AbstractControl {
300301
updateValueAndValidity(options = {}) {
301302
this.setInitialStatus();
302303
this._updateValue();
303-
const shouldValidate = this.enabled && (this.updateOn === "change" || options.validate);
304+
const shouldValidate = this.enabled && (this.updateOn !== "submit" || this.submitted);
304305
if (shouldValidate) {
305306
this._cancelExistingSubscription();
306307
this.errors = this._runValidator();
307308
this.status = this._calculateStatus();
308309
if (this.status === VALID || this.status === PENDING) {
309-
this._runAsyncValidator(options.emitEvent);
310+
this._runAsyncValidator(true);
310311
}
311312
}
312313
if (options.emitEvent !== false) {
@@ -332,6 +333,39 @@ export class AbstractControl {
332333
this._parent.markAsTouched(opts);
333334
}
334335
}
336+
/**
337+
* Marks the control as `submitted`.
338+
*
339+
* If the control has any children, it will also mark all children as `submitted`
340+
* @param {{emitEvent: Boolean}} opts
341+
* @return {void}
342+
*/
343+
markAsSubmitted(opts = {}) {
344+
this.submitted= true;
345+
346+
this._forEachChild((control) => { control.markAsSubmitted(); });
347+
348+
if (opts.emitEvent !== false) {
349+
this.stateChanges.next();
350+
}
351+
}
352+
/**
353+
* Marks the control as `unsubmitted`.
354+
*
355+
* If the control has any children, it will also mark all children as `unsubmitted`.
356+
*
357+
* @param {{emitEvent: Boolean}} opts
358+
* @return {void}
359+
*/
360+
markAsUnsubmitted(opts = {}) {
361+
this.submitted = false;
362+
363+
this._forEachChild((control) => { control.markAsUnsubmitted({ onlySelf: true }); });
364+
365+
if (opts.emitEvent !== false) {
366+
this.stateChanges.next();
367+
}
368+
}
335369
/**
336370
* Marks the control as `pristine`.
337371
*
@@ -645,14 +679,17 @@ export class FormControl extends AbstractControl {
645679
if(this.updateOn === "blur") {
646680
if(!this.dirty) { this.markAsDirty(); }
647681
if(!this.touched) { this.markAsTouched(); }
648-
this.setValue(this._pendingValue, { validate: true });
682+
this.setValue(this._pendingValue);
649683
} else if(this.updateOn === "submit") {
650684
this._pendingTouched = true;
651685
this._pendingDirty = true;
652686
} else {
687+
const emitChangeToView = !this.touched;
653688
if(!this.dirty) { this.markAsDirty(); }
654689
if(!this.touched) { this.markAsTouched(); }
655-
this.stateChanges.next();
690+
if(emitChangeToView) {
691+
this.stateChanges.next();
692+
}
656693
}
657694
};
658695
/**
@@ -728,7 +765,8 @@ export class FormControl extends AbstractControl {
728765
if (this._pendingDirty) this.markAsDirty();
729766
if (this._pendingTouched) this.markAsTouched();
730767
if (this._pendingChange) {
731-
this.setValue(this._pendingValue, {validate: true});
768+
this.setValue(this._pendingValue);
769+
this._pendingChange = false;
732770
return true;
733771
}
734772
}
@@ -740,16 +778,15 @@ export class FormGroup extends AbstractControl {
740778
super(coerceToValidator(validatorOrOpts),
741779
coerceToAsyncValidator(asyncValidator, validatorOrOpts));
742780
this.controls = controls;
743-
this.submitted = false;
744781
this.validatorOrOpts = validatorOrOpts;
745782
this._initObservables();
746783
this._setUpdateStrategy(validatorOrOpts);
747784
this._setUpControls();
748785
this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
749786
this.handleSubmit = (e) => {
750-
e.preventDefault();
751-
this.submitted = true;
752-
if(!this._syncPendingControls()) { this.updateValueAndValidity({ validate: true }) }
787+
if(e) { e.preventDefault(); }
788+
if(!this.submitted) { this.markAsSubmitted({ emitEvent: false }); }
789+
if(!this._syncPendingControls()) { this.updateValueAndValidity()};
753790
}
754791
}
755792
/**
@@ -851,6 +888,7 @@ export class FormGroup extends AbstractControl {
851888
control.reset(value[name], {onlySelf: true, emitEvent: options.emitEvent});
852889
});
853890
this.updateValueAndValidity(options);
891+
this.markAsUnsubmitted();
854892
this._updatePristine(options);
855893
this._updateTouched(options);
856894
}
@@ -982,7 +1020,7 @@ export class FormGroup extends AbstractControl {
9821020
let subtreeUpdated = this._reduceChildren(false, (updated, child) => {
9831021
return child._syncPendingControls() ? true : updated;
9841022
});
985-
if (subtreeUpdated) this.updateValueAndValidity({onlySelf: true});
1023+
if (subtreeUpdated) this.updateValueAndValidity();
9861024
return subtreeUpdated;
9871025
}
9881026
}
@@ -992,16 +1030,15 @@ export class FormArray extends AbstractControl {
9921030
coerceToValidator(validatorOrOpts),
9931031
coerceToAsyncValidator(asyncValidator, validatorOrOpts));
9941032
this.controls = controls;
995-
this.submitted = false;
9961033
this.validatorOrOpts = validatorOrOpts;
9971034
this._initObservables();
9981035
this._setUpdateStrategy(validatorOrOpts);
9991036
this._setUpControls();
10001037
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
10011038
this.handleSubmit = (e) => {
1002-
e.preventDefault();
1003-
this.submitted = true;
1004-
if(!this._syncPendingControls()) { this.updateValueAndValidity({ validate: true }) }
1039+
if(e) { e.preventDefault(); }
1040+
if(!this.submitted) { this.markAsSubmitted({ emitEvent: false }); }
1041+
if(!this._syncPendingControls()) { this.updateValueAndValidity()};
10051042
}
10061043
}
10071044
/**
@@ -1111,6 +1148,7 @@ export class FormArray extends AbstractControl {
11111148
control.reset(value[index], {onlySelf: true, emitEvent: options.emitEvent});
11121149
});
11131150
this.updateValueAndValidity(options);
1151+
this.markAsUnsubmitted();
11141152
this._updatePristine(options);
11151153
this._updateTouched(options);
11161154
}
@@ -1132,7 +1170,7 @@ export class FormArray extends AbstractControl {
11321170
let subtreeUpdated = this.controls.reduce((updated, child) => {
11331171
return child._syncPendingControls() ? true : updated;
11341172
}, false);
1135-
if (subtreeUpdated) this.updateValueAndValidity({onlySelf: true});
1173+
if (subtreeUpdated) this.updateValueAndValidity();
11361174
return subtreeUpdated;
11371175
}
11381176

0 commit comments

Comments
 (0)