Skip to content

Commit

Permalink
feat: added unchecked-value prop to the field component
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Dec 14, 2020
1 parent 3a9cc7f commit af910c3
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 6 deletions.
6 changes: 6 additions & 0 deletions packages/vee-validate/src/Field.ts
Expand Up @@ -55,11 +55,16 @@ export const Field = defineComponent({
type: String,
default: undefined,
},
uncheckedValue: {
type: null,
default: undefined,
},
},
setup(props, ctx) {
const rules = toRef(props, 'rules');
const name = toRef(props, 'name');
const label = toRef(props, 'label');
const uncheckedValue = toRef(props, 'uncheckedValue');

const {
errors,
Expand Down Expand Up @@ -88,6 +93,7 @@ export const Field = defineComponent({
: ctx.attrs.value,
// Only for checkboxes and radio buttons
valueProp: ctx.attrs.value,
uncheckedValue,
label,
validateOnValueUpdate: false,
});
Expand Down
16 changes: 12 additions & 4 deletions packages/vee-validate/src/useField.ts
Expand Up @@ -32,6 +32,7 @@ interface FieldOptions {
bails?: boolean;
type?: string;
valueProp?: MaybeReactive<any>;
uncheckedValue?: MaybeReactive<any>;
label?: MaybeReactive<string>;
}

Expand All @@ -51,10 +52,16 @@ let ID_COUNTER = 0;
*/
export function useField(name: MaybeReactive<string>, rules?: RuleExpression, opts?: Partial<FieldOptions>) {
const fid = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;
const { initialValue, validateOnMount, bails, type, valueProp, label, validateOnValueUpdate } = normalizeOptions(
unref(name),
opts
);
const {
initialValue,
validateOnMount,
bails,
type,
valueProp,
label,
validateOnValueUpdate,
uncheckedValue,
} = normalizeOptions(unref(name), opts);

const form = injectWithSelf(FormSymbol);
const {
Expand Down Expand Up @@ -153,6 +160,7 @@ export function useField(name: MaybeReactive<string>, rules?: RuleExpression, op
errorMessage,
type,
valueProp,
uncheckedValue,
checked,
idx: -1,
resetField,
Expand Down
2 changes: 1 addition & 1 deletion packages/vee-validate/src/useForm.ts
Expand Up @@ -148,7 +148,7 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
let newValue = value;
// Single Checkbox
if (fieldInstance?.type === 'checkbox') {
newValue = getFromPath(formValues, field as string) === value ? undefined : value;
newValue = getFromPath(formValues, field as string) === value ? fieldInstance.uncheckedValue : value;
}

setInPath(formValues, field as string, newValue);
Expand Down
28 changes: 27 additions & 1 deletion packages/vee-validate/tests/Field.spec.ts
@@ -1,6 +1,6 @@
import flushPromises from 'flush-promises';
import { defineRule, configure } from '@/vee-validate';
import { mountWithHoc, setValue, dispatchEvent } from './helpers';
import { mountWithHoc, setValue, dispatchEvent, setChecked } from './helpers';
import * as yup from 'yup';
import { ref, Ref } from 'vue';

Expand Down Expand Up @@ -816,4 +816,30 @@ describe('<Field />', () => {
dispatchEvent(input as HTMLInputElement, 'blur');
expect(onBlur).toHaveBeenCalledTimes(1);
});

test('can customize checkboxes unchecked value', async () => {
const spy = jest.fn();
const wrapper = mountWithHoc({
setup() {
return { onSubmit: spy };
},
template: `
<VForm @submit="onSubmit">
<Field name="terms" as="input" type="checkbox" :unchecked-value="false" :value="true" /> Coffee
<button type="submit">Submit</button>
</VForm>
`,
});

await flushPromises();
const input = wrapper.$el.querySelector('input');
setChecked(input, true);
await flushPromises();
setChecked(input, false);
await flushPromises();
wrapper.$el.querySelector('button').click();
await flushPromises();
expect(spy).toHaveBeenCalledWith(expect.objectContaining({ terms: false }), expect.anything());
});
});

0 comments on commit af910c3

Please sign in to comment.