Skip to content

Commit

Permalink
fix: run validation on value change closes #4251
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed May 10, 2023
1 parent a210ae6 commit 09d5596
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/fast-jars-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vee-validate': patch
---

fix: run validation on value change closes #4251
13 changes: 1 addition & 12 deletions packages/vee-validate/src/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,6 @@ const FieldImpl = defineComponent({
ctx.emit('update:modelValue', value.value);
};

const handleInput = (e: any) => {
if (!hasCheckedAttr(ctx.attrs.type)) {
value.value = normalizeEventValue(e);
}
};

const onInputHandler = function handleInputWithModel(e: any) {
handleInput(e);
ctx.emit('update:modelValue', value.value);
};

const fieldProps = computed(() => {
const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } =
resolveValidationTriggers(props);
Expand Down Expand Up @@ -218,7 +207,7 @@ const FieldImpl = defineComponent({
validate: validateField,
resetField,
handleChange: onChangeHandler,
handleInput: onInputHandler,
handleInput: e => onChangeHandler(e, false),
handleReset,
handleBlur,
setTouched,
Expand Down
13 changes: 5 additions & 8 deletions packages/vee-validate/src/useField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,7 @@ function _useField<TValue = unknown>(
// Common input/change event handler
function handleChange(e: unknown, shouldValidate = true) {
const newValue = normalizeEventValue(e) as TValue;

setValue(newValue, false);
if (!validateOnValueUpdate && shouldValidate) {
validateWithStateMutation();
}
setValue(newValue, shouldValidate);
}

// Runs the initial validation
Expand Down Expand Up @@ -257,13 +253,14 @@ function _useField<TValue = unknown>(
validateValidStateOnly();
}

function setValue(newValue: TValue, validate = true) {
function setValue(newValue: TValue, shouldValidate = true) {
value.value = newValue;
if (!validate) {
if (!shouldValidate) {
validateValidStateOnly();
return;
}

const validateFn = validateOnValueUpdate ? validateWithStateMutation : validateValidStateOnly;
const validateFn = shouldValidate ? validateWithStateMutation : validateValidStateOnly;
validateFn();
}

Expand Down
38 changes: 38 additions & 0 deletions packages/vee-validate/tests/useField.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -832,4 +832,42 @@ describe('useField()', () => {
await flushPromises();
expect(name?.textContent).toBe('second');
});

test('handle change validates the field by default', async () => {
let field!: FieldContext;
const validator = vi.fn(val => (val ? true : REQUIRED_MESSAGE));
mountWithHoc({
setup() {
field = useField('field', validator);
},
template: `<div></div>`,
});

await flushPromises();
expect(validator).toHaveBeenCalledTimes(1);
expect(field.errorMessage.value).toBe(undefined);
field.handleChange('');
await flushPromises();
expect(field.errorMessage.value).toBe(REQUIRED_MESSAGE);
});

test('handle change can be configured to not validate the field', async () => {
let field!: FieldContext;
const validator = vi.fn(val => (val ? true : REQUIRED_MESSAGE));
mountWithHoc({
setup() {
field = useField('field', validator, { validateOnValueUpdate: false });
},
template: `<div></div>`,
});

await flushPromises();
expect(validator).toHaveBeenCalledTimes(1);
expect(field.errorMessage.value).toBe(undefined);
field.handleChange('', false);
await flushPromises();

expect(validator).toHaveBeenCalledTimes(2);
expect(field.errorMessage.value).toBe(undefined);
});
});

0 comments on commit 09d5596

Please sign in to comment.