126 lines
3.1 KiB
JavaScript
126 lines
3.1 KiB
JavaScript
// Composables
|
|
import { useProxiedModel } from "./proxiedModel.mjs"; // Utilities
|
|
import { computed, inject, provide, ref, shallowRef, toRef, watch } from 'vue';
|
|
import { consoleWarn, propsFactory } from "../util/index.mjs"; // Types
|
|
export const FormKey = Symbol.for('vuetify:form');
|
|
export const makeFormProps = propsFactory({
|
|
disabled: Boolean,
|
|
fastFail: Boolean,
|
|
readonly: Boolean,
|
|
modelValue: {
|
|
type: Boolean,
|
|
default: null
|
|
},
|
|
validateOn: {
|
|
type: String,
|
|
default: 'input'
|
|
}
|
|
}, 'form');
|
|
export function createForm(props) {
|
|
const model = useProxiedModel(props, 'modelValue');
|
|
const isDisabled = computed(() => props.disabled);
|
|
const isReadonly = computed(() => props.readonly);
|
|
const isValidating = shallowRef(false);
|
|
const items = ref([]);
|
|
const errors = ref([]);
|
|
async function validate() {
|
|
const results = [];
|
|
let valid = true;
|
|
errors.value = [];
|
|
isValidating.value = true;
|
|
for (const item of items.value) {
|
|
const itemErrorMessages = await item.validate();
|
|
if (itemErrorMessages.length > 0) {
|
|
valid = false;
|
|
results.push({
|
|
id: item.id,
|
|
errorMessages: itemErrorMessages
|
|
});
|
|
}
|
|
if (!valid && props.fastFail) break;
|
|
}
|
|
errors.value = results;
|
|
isValidating.value = false;
|
|
return {
|
|
valid,
|
|
errors: errors.value
|
|
};
|
|
}
|
|
function reset() {
|
|
items.value.forEach(item => item.reset());
|
|
}
|
|
function resetValidation() {
|
|
items.value.forEach(item => item.resetValidation());
|
|
}
|
|
watch(items, () => {
|
|
let valid = 0;
|
|
let invalid = 0;
|
|
const results = [];
|
|
for (const item of items.value) {
|
|
if (item.isValid === false) {
|
|
invalid++;
|
|
results.push({
|
|
id: item.id,
|
|
errorMessages: item.errorMessages
|
|
});
|
|
} else if (item.isValid === true) valid++;
|
|
}
|
|
errors.value = results;
|
|
model.value = invalid > 0 ? false : valid === items.value.length ? true : null;
|
|
}, {
|
|
deep: true
|
|
});
|
|
provide(FormKey, {
|
|
register: _ref => {
|
|
let {
|
|
id,
|
|
validate,
|
|
reset,
|
|
resetValidation
|
|
} = _ref;
|
|
if (items.value.some(item => item.id === id)) {
|
|
consoleWarn(`Duplicate input name "${id}"`);
|
|
}
|
|
items.value.push({
|
|
id,
|
|
validate,
|
|
reset,
|
|
resetValidation,
|
|
isValid: null,
|
|
errorMessages: []
|
|
});
|
|
},
|
|
unregister: id => {
|
|
items.value = items.value.filter(item => {
|
|
return item.id !== id;
|
|
});
|
|
},
|
|
update: (id, isValid, errorMessages) => {
|
|
const found = items.value.find(item => item.id === id);
|
|
if (!found) return;
|
|
found.isValid = isValid;
|
|
found.errorMessages = errorMessages;
|
|
},
|
|
isDisabled,
|
|
isReadonly,
|
|
isValidating,
|
|
isValid: model,
|
|
items,
|
|
validateOn: toRef(props, 'validateOn')
|
|
});
|
|
return {
|
|
errors,
|
|
isDisabled,
|
|
isReadonly,
|
|
isValidating,
|
|
isValid: model,
|
|
items,
|
|
validate,
|
|
reset,
|
|
resetValidation
|
|
};
|
|
}
|
|
export function useForm() {
|
|
return inject(FormKey, null);
|
|
}
|
|
//# sourceMappingURL=form.mjs.map
|