Skip to content

Commit

Permalink
fix: set() will apply input function also to initial and `defau…
Browse files Browse the repository at this point in the history
…lt` props

`set()` will apply `input` function also to `initial` and `default` props.

fix: #519
  • Loading branch information
foxhound87 committed Apr 4, 2023
1 parent 72f4a8b commit 97c276a
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 32 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 5.10.1 (next)
- `set()` will apply `input` function also to `initial` and `default` props.
- Fix: #519

# 5.10.0 (next)
- Introduced Field `trim()` method.
- Introduced `validateTrimmedValue` form option.
Expand All @@ -14,7 +18,7 @@ Fix: using `autoTrimValue` option will not trigger `onChange` Event Hook

- Introduced `inputMode` Field property.
- Introduced `autoTrimValue` form option (can be also enabled on single field).
Fix: #283
- Fix: #283

# 5.8.0 (next)

Expand Down
25 changes: 16 additions & 9 deletions src/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export default class Base implements BaseInterface {
.find(
(s: any) =>
s.charAt(structPath.length) === "." ||
s.substr(structPath.length, 2) === "[]" ||
s.substring(structPath.length, structPath.length + 2) === "[]" ||
s === structPath
);

Expand Down Expand Up @@ -384,12 +384,15 @@ export default class Base implements BaseInterface {
return _.transform(
$fields,
(check: any, field: any) => {
if (!field.fields.size || props.exceptions.includes(prop)) {
if (!field.fields.size || props.exceptions.includes(prop) || !_.isArray(field.initial)) {
check.push(field[prop]);
}

const $deep = this.deepCheck(type, prop, field.fields);
check.push(checkPropOccurrence({ type, data: $deep }));
check.push(checkPropOccurrence({
data: this.deepCheck(type, prop, field.fields),
type,
}));

return check;
},
[]
Expand Down Expand Up @@ -533,8 +536,7 @@ export default class Base implements BaseInterface {
if (prop === FieldPropsEnum.value) value = field.$output(value);

delete obj[field.key];
// if (removeProp) return obj;

if (removeProp) return obj;
const removeNullishValuesInArrays = this.state.options.get(OptionsEnum.removeNullishValuesInArrays, this);

return Object.assign(obj, {
Expand Down Expand Up @@ -563,14 +565,19 @@ export default class Base implements BaseInterface {
allowedProps(AllowedFieldPropsTypes.editable, [prop]);
const deep = (_.isObject(data) && prop === FieldPropsEnum.value) || _.isPlainObject(data);
if (deep && this.hasNestedFields) return this.deepSet(prop, data, "", true);
// else _.set(this, `$${prop}`, data);
if (prop === FieldPropsEnum.value) {
(this as any).value = parseInput((this as any).$input, {

if (([
FieldPropsEnum.value,
FieldPropsEnum.initial,
FieldPropsEnum.default,
] as string[]).includes(prop)) {
(this as any)[prop] = parseInput((this as any).$input, {
separated: data,
});
} else {
_.set(this, `$${prop}`, data);
}

return;
}

Expand Down
5 changes: 1 addition & 4 deletions src/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,9 @@ export default class Field extends Base implements FieldInterface {

getComputedProp(key: string): any {
if (this.incremental || this.hasNestedFields) {
const $val =
key === FieldPropsEnum.value
return (key === FieldPropsEnum.value)
? this.get(key, false)
: untracked(() => this.get(key, false));

return !_.isEmpty($val) ? $val : [];
}

// @ts-ignore
Expand Down
2 changes: 1 addition & 1 deletion src/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export default class Form extends Base implements FormInterface {
invalidate(message: string | null = null): void {
this.debouncedValidation.cancel();
this.each((field) => field.debouncedValidation.cancel());
this.validator.error = message || this.state.options.get(OptionsEnum.defaultGenericError);
this.validator.error = message || this.state.options.get(OptionsEnum.defaultGenericError) || true;
}

showErrors(show: boolean = true): void {
Expand Down
4 changes: 3 additions & 1 deletion src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ export const props: PropsGroupsInterface = {
FieldPropsEnum.validatedWith,
],
exceptions: [
// FieldPropsEnum.hasError,
// FieldPropsEnum.isValid,
FieldPropsEnum.isDirty,
FieldPropsEnum.isPristine
FieldPropsEnum.isPristine,
],
occurrences: {
isDirty: FieldPropsOccurrence.some,
Expand Down
12 changes: 6 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const checkPropOccurrence = ({ type, data }: any): boolean => {
return $check(data);
};

const hasProps = ($type: any, $data: any) => {
const hasProps = ($type: string, $data: any): boolean => {
let $props;
switch ($type) {
case AllowedFieldPropsTypes.computed:
Expand Down Expand Up @@ -75,7 +75,7 @@ const hasProps = ($type: any, $data: any) => {
/**
Check Allowed Properties
*/
const allowedProps = (type: string, data: string[]) => {
const allowedProps = (type: string, data: string[]): void => {
if (hasProps(type, data)) return;
const $msg = "The selected property is not allowed";
throw new Error(`${$msg} (${JSON.stringify(data)})`);
Expand All @@ -84,7 +84,7 @@ const allowedProps = (type: string, data: string[]) => {
/**
Throw Error if undefined Fields
*/
const throwError = (path: string, fields: any, msg: null | string = null) => {
const throwError = (path: string, fields: any, msg: null | string = null): void => {
if (!_.isNil(fields)) return;
const $msg = _.isNil(msg) ? "The selected field is not defined" : msg;
throw new Error(`${$msg} (${path})`);
Expand All @@ -110,13 +110,13 @@ const isArrayOfStrings = (struct: any): boolean =>
const isArrayOfObjects = (fields: any): boolean =>
_.isArray(fields) && _.every(fields, _.isPlainObject);

const $getKeys = (fields: any) =>
const getKeys = (fields: any) =>
_.union(..._.map(_.values(fields), (values) => _.keys(values)));

const hasUnifiedProps = ({ fields }: any) =>
!isArrayOfStrings({ fields }) && hasProps(AllowedFieldPropsTypes.editable, $getKeys(fields));
!isArrayOfStrings({ fields }) && hasProps(AllowedFieldPropsTypes.editable, getKeys(fields));

const hasSeparatedProps = (initial: any) =>
const hasSeparatedProps = (initial: any): boolean =>
hasSome(initial, props.separated) || hasSome(initial, props.validation);

const allowNested = (field: any, strictProps: boolean): boolean =>
Expand Down
2 changes: 2 additions & 0 deletions tests/data/_.fixes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import $544 from "./forms/fixes/form.544";
import $454 from "./forms/fixes/form.454";
import $518 from "./forms/fixes/form.518";
import $376 from "./forms/fixes/form.376";
import $519 from "./forms/fixes/form.519";

import $585 from "./forms/fixes/form.585";
import $531 from "./forms/fixes/form.531";
Expand Down Expand Up @@ -80,6 +81,7 @@ export default {
$454,
$518,
$376,
$519,

$585,
$531,
Expand Down
10 changes: 5 additions & 5 deletions tests/data/forms/fixes/form.518.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ const values = {
};

const disabled = {
any: {
type: false,
other: true,
}
}
'any.type': false,
'any.other': true,
};

const rules = {
any: {
Expand All @@ -52,6 +50,8 @@ class NewForm extends Form {
it("form isValid should be false", () => expect(form.isValid).to.be.equal(false));
it("form hasError should be false", () => expect(form.hasError).to.be.equal(true));

it("form `$('any').disabled` should be false", () => expect(form.$('any').disabled).to.be.equal(false));

it("form `$('any.other').isValid` should be true", () => expect(form.$('any.other').isValid).to.be.equal(true));
it("form `$('any.type').isValid` should be false", () => expect(form.$('any.type').isValid).to.be.equal(false));

Expand Down
77 changes: 77 additions & 0 deletions tests/data/forms/fixes/form.519.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { expect } from "chai";
import validatorjs from "validatorjs";
import { Form } from "../../../../src";
import FormInterface from "../../../../src/models/FormInterface";
import { ValidationPlugins } from "../../../../src/models/ValidatorInterface";
import vjf from "../../../../src/validators/VJF";
import dvr from "../../../../src/validators/DVR";

const plugins: ValidationPlugins = {
vjf: vjf(),
dvr: dvr(validatorjs)
};

const weekValidator = ({ field, form }) => {
// form.invalidate(); // <--- need to work without calling invalidate()
return [false, "Error ..."];
};

const fields = [
{
name: "week",
label: "week",
validators: [weekValidator],
fields: [
{
name: "MONDAY",
label: "MONDAY",
disabled: true,
fields: [
{
name: "start",
label: "start",
// validators: [timeValidator]
},
{
name: "end",
label: "end",
// validators: [timeValidator]
}
],
},
{
name: "TUESDAY",
label: "TUESDAY",
disabled: true,
fields: [
{
name: "start",
label: "start"
},
{
name: "end",
label: "end"
}
],
}
// ...other days
]
}
];

const hooks = {
onInit(form) {
form.submit();
},
};

export default new Form({ fields }, {
plugins,
hooks,
name: '$519',
options: {
validateOnInit: true,
showErrorsOnInit: true,
retrieveOnlyEnabledFieldsValues: true,
validateDisabledFields: false
}});
24 changes: 22 additions & 2 deletions tests/fixes.props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('Check Fixes $Q nested paths check', () => {
expect($.$Q.$('incident').$(0).$('options').path).to.be.equal('incident.0.options'));
});

describe('Check Fixes $Q1 checks', () => {
describe('Check Fixes $Q1', () => {
it('$Q1 tags hasNestedFields should be true', () =>
expect($.$Q1.$('tags').hasNestedFields).to.be.true);

Expand All @@ -137,11 +137,31 @@ describe('Check Fixes $Q1 checks', () => {
expect($.$Q1.$('other.nested').value).to.be.equal('nested-value'));
});

describe('Check Fixes $Q2 checks', () => {
describe('Check Fixes $Q2', () => {
it('$Q2 tags hasNestedFields should be false', () =>
expect($.$Q2.$('tags').hasNestedFields).to.be.false);

it('$Q2 tags hasInitialNestedFields should be false', () =>
expect($.$Q2.$('tags').hasInitialNestedFields).to.be.false);
});


describe('Check Fixes $519', () => {
it('$519 form isValid should be false', () =>
expect($.$519.isValid).to.be.false);
it('$519 form hasError should be true', () =>
expect($.$519.hasError).to.be.true);
it('$519 week isValid should be false', () =>
expect($.$519.$('week').isValid).to.be.false);
it('$519 week hasError should be true', () =>
expect($.$519.$('week').hasError).to.be.true);

it('$519 week error should be "Error ..."', () =>
expect($.$519.$('week').error).to.be.equal("Error ..."));

it('$519 form values() should be equal to { week: {} }', () =>
expect($.$519.values()).to.be.deep.equal({ week: {} }));

it('$519 week value should be equal to empty object', () =>
expect($.$519.$('week').value).to.be.deep.equal({}));
});
2 changes: 1 addition & 1 deletion tests/fixes.values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,4 +803,4 @@ describe('#615, not to add nested array item', () => {
expect($form.select('a.0.b.c', null, false)).not.to.be.undefined
expect($form.select('a.0.b.c.0', null, false)).to.be.undefined
})
})
})
4 changes: 2 additions & 2 deletions tests/nested.submit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ describe('Nested Form Manual submit()', () => {
it('$R.submit() should call onSuccess callback', (done) => {
$.$R.$('members').submit().then((instance) => {
expect(instance.submitted).to.equal(1);
expect(instance.hasError).to.be.false; // eslint-disable-line
expect(instance.isValid).to.be.true; // eslint-disable-line
expect(instance.hasError).to.be.false;
expect(instance.isValid).to.be.true;
done();
});
});
Expand Down

0 comments on commit 97c276a

Please sign in to comment.