Commit 6ba1c321 authored by Dheeraj Joshi's avatar Dheeraj Joshi

Add support for nested elements to Validation directive

Validation directive can now be used with GlInputGroup
and similar other grouped components
parent 5885a1c4
......@@ -33,6 +33,10 @@ const focusFirstInvalidInput = (e) => {
}
};
const getInputElement = (el) => {
return el.querySelector('input') || el;
};
const isEveryFieldValid = (form) => Object.values(form.fields).every(({ state }) => state === true);
const createValidator = (context, feedbackMap) => ({ el, reportInvalidInput = false }) => {
......@@ -91,8 +95,9 @@ export default function initValidation(customFeedbackMap = {}) {
const elDataMap = new WeakMap();
return {
inserted(el, binding, { context }) {
inserted(element, binding, { context }) {
const { arg: showGlobalValidation } = binding;
const el = getInputElement(element);
const { form: formEl } = el;
const validate = createValidator(context, feedbackMap);
......@@ -121,7 +126,8 @@ export default function initValidation(customFeedbackMap = {}) {
validate({ el, reportInvalidInput: showGlobalValidation });
},
update(el, binding) {
update(element, binding) {
const el = getInputElement(element);
const { arg: showGlobalValidation } = binding;
const { validate, isTouched, isBlurred } = elDataMap.get(el);
const showValidationFeedback = showGlobalValidation || (isTouched && isBlurred);
......
......@@ -4,12 +4,18 @@ import validation from '~/vue_shared/directives/validation';
describe('validation directive', () => {
let wrapper;
const createComponent = ({ inputAttributes, showValidation } = {}) => {
const createComponent = ({ inputAttributes, showValidation, template } = {}) => {
const defaultInputAttributes = {
type: 'text',
required: true,
};
const defaultTemplate = `
<form>
<input v-validation:[showValidation] name="exampleField" v-bind="attributes" />
</form>
`;
const component = {
directives: {
validation: validation(),
......@@ -29,11 +35,7 @@ describe('validation directive', () => {
},
};
},
template: `
<form>
<input v-validation:[showValidation] name="exampleField" v-bind="attributes" />
</form>
`,
template: template || defaultTemplate,
};
wrapper = shallowMount(component, { attachTo: document.body });
......@@ -48,6 +50,12 @@ describe('validation directive', () => {
const findForm = () => wrapper.find('form');
const findInput = () => wrapper.find('input');
const setValueAndTriggerValidation = (value) => {
const input = findInput();
input.setValue(value);
input.trigger('blur');
};
describe.each([true, false])(
'with fields untouched and "showValidation" set to "%s"',
(showValidation) => {
......@@ -78,12 +86,6 @@ describe('validation directive', () => {
`(
'with input-attributes set to $inputAttributes',
({ inputAttributes, validValue, invalidValue }) => {
const setValueAndTriggerValidation = (value) => {
const input = findInput();
input.setValue(value);
input.trigger('blur');
};
beforeEach(() => {
createComponent({ inputAttributes });
});
......@@ -129,4 +131,52 @@ describe('validation directive', () => {
});
},
);
describe('with group elements', () => {
const template = `
<form>
<div v-validation:[showValidation]>
<input name="exampleField" v-bind="attributes" />
</div>
</form>
`;
beforeEach(() => {
createComponent({
template,
inputAttributes: {
required: true,
},
});
});
describe('with invalid value', () => {
beforeEach(() => {
setValueAndTriggerValidation('');
});
it('should set correct field state', () => {
expect(getFormData().fields.exampleField).toEqual({
state: false,
feedback: expect.any(String),
});
});
it('should set correct feedback', () => {
expect(getFormData().fields.exampleField.feedback).toBe('Please fill out this field.');
});
});
describe('with valid value', () => {
beforeEach(() => {
setValueAndTriggerValidation('hello');
});
it('set the correct state', () => {
expect(getFormData().fields.exampleField).toEqual({
state: true,
feedback: '',
});
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment