Skip to content

Commit

Permalink
fix(common): validate dynamically added number input (#263)
Browse files Browse the repository at this point in the history
* fix: validate dynamically added number input

* test(common): update tests
  • Loading branch information
pablo-abc authored Aug 29, 2023
1 parent 7a4250a commit 0a99410
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 30 deletions.
12 changes: 12 additions & 0 deletions .changeset/curly-scissors-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@felte/common': patch
'@felte/core': patch
'@felte/element': patch
'felte': patch
'@felte/preact': patch
'@felte/react': patch
'@felte/solid': patch
'@felte/vanilla': patch
---

Fix dynamically added number input not validating unless touched
6 changes: 2 additions & 4 deletions packages/common/src/utils/domUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,9 @@ export function addAttrsFromFieldset(fieldSet: HTMLFieldSetElement): void {
}

/** @ignore */
export function getInputTextOrNumber(
el: FormControl
): string | number | undefined {
export function getInputTextOrNumber(el: FormControl): string | number | null {
if (el.type.match(/^(number|range)$/)) {
return !el.value ? undefined : +el.value;
return !el.value ? null : +el.value;
} else {
return el.value;
}
Expand Down
15 changes: 6 additions & 9 deletions packages/common/tests/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,15 @@ describe('test', () => {
lastName: '',
bio: '',
picture: undefined,
age: undefined,
age: null,
},
extra: {
pictures: [],
},
preferences: [],
multiple: {
extraText: ['', '', ''],
extraNumber: [undefined, undefined, undefined],
extraNumber: [null, null, null],
extraFiles: [undefined, undefined, undefined],
extraCheckbox: [false, false, false],
extraPreference: [[], [], []],
Expand Down Expand Up @@ -577,11 +577,8 @@ describe('test', () => {
select: '1',
multipleSelect: ['1', '2'],
};
const {
formElement,
selectElement,
multipleSelectElement,
} = createSignupForm();
const { formElement, selectElement, multipleSelectElement } =
createSignupForm();

setForm(formElement, {
...formData,
Expand Down Expand Up @@ -684,12 +681,12 @@ describe('test', () => {
});

expect(getInputTextOrNumber(textElement)).to.equal('');
expect(getInputTextOrNumber(numberElement)).to.equal(undefined);
expect(getInputTextOrNumber(numberElement)).to.equal(null);

textElement.value = 'test';
numberElement.value = 'test';
expect(getInputTextOrNumber(textElement)).to.equal('test');
expect(getInputTextOrNumber(numberElement)).to.equal(undefined);
expect(getInputTextOrNumber(numberElement)).to.equal(null);

numberElement.value = '42';
expect(getInputTextOrNumber(numberElement)).to.equal(42);
Expand Down
6 changes: 2 additions & 4 deletions packages/core/src/create-form-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,8 @@ export function createFormAction<Data extends Obj>({
const updateAddedNodes = debounce(() => {
_getCurrentExtenders().forEach((extender) => extender.destroy?.());
_setCurrentExtenders(extender.map(callExtender('UPDATE')));
const {
defaultData: newDefaultData,
defaultTouched: newDefaultTouched,
} = getFormDefaultValues<Data>(node);
const { defaultData: newDefaultData, defaultTouched: newDefaultTouched } =
getFormDefaultValues<Data>(node);
data.update(($data) => _defaultsDeep<Data>($data, newDefaultData));
touched.update(($touched) => {
return _defaultsDeep($touched, newDefaultTouched);
Expand Down
23 changes: 10 additions & 13 deletions packages/core/src/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,8 @@ export function createDerivedFactory<StoreExt = Record<string, any>>(
? storeOrStores
: [storeOrStores];
const values: any[] = new Array(stores.length);
const derivedStore: PossibleWritable<R> & StoreExt = storeFactory(
initialValue
);
const derivedStore: PossibleWritable<R> & StoreExt =
storeFactory(initialValue);

const storeSet = derivedStore.set as Writable<R>['set'];
const storeSubscribe = derivedStore.subscribe;
Expand Down Expand Up @@ -287,15 +286,12 @@ export function createStores<Data extends Obj, StoreExt = Record<string, any>>(
_cloneDeep(initialErrors)
);

const [
filteredWarnings,
startFilteredWarnings,
stopFilteredWarnings,
] = derived(
[warnings as Readable<Errors<Data>>, touched as Readable<Touched<Data>>],
filterWarnings,
_cloneDeep(initialWarnings)
);
const [filteredWarnings, startFilteredWarnings, stopFilteredWarnings] =
derived(
[warnings as Readable<Errors<Data>>, touched as Readable<Touched<Data>>],
filterWarnings,
_cloneDeep(initialWarnings)
);

// This is necessary since, on the first run, validations
// have not run yet. We assume the form is not valid in the first calling
Expand Down Expand Up @@ -460,7 +456,8 @@ export function createStores<Data extends Obj, StoreExt = Record<string, any>>(
filteredErrors.set = publicErrorsSetter;
(filteredErrors as PartialWritableErrors<Data>).update = publicErrorsUpdater;
filteredWarnings.set = publicWarningsSetter;
(filteredWarnings as PartialWritableErrors<Data>).update = publicWarningsUpdater;
(filteredWarnings as PartialWritableErrors<Data>).update =
publicWarningsUpdater;

return {
data: data as KeyedWritable<Data> & StoreExt,
Expand Down

1 comment on commit 0a99410

@vercel
Copy link

@vercel vercel bot commented on 0a99410 Aug 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.