form.mjs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Composables
  2. import { useProxiedModel } from "./proxiedModel.mjs"; // Utilities
  3. import { computed, inject, markRaw, provide, ref, shallowRef, toRef, watch } from 'vue';
  4. import { consoleWarn, propsFactory } from "../util/index.mjs"; // Types
  5. export const FormKey = Symbol.for('vuetify:form');
  6. export const makeFormProps = propsFactory({
  7. disabled: Boolean,
  8. fastFail: Boolean,
  9. readonly: Boolean,
  10. modelValue: {
  11. type: Boolean,
  12. default: null
  13. },
  14. validateOn: {
  15. type: String,
  16. default: 'input'
  17. }
  18. }, 'form');
  19. export function createForm(props) {
  20. const model = useProxiedModel(props, 'modelValue');
  21. const isDisabled = computed(() => props.disabled);
  22. const isReadonly = computed(() => props.readonly);
  23. const isValidating = shallowRef(false);
  24. const items = ref([]);
  25. const errors = ref([]);
  26. async function validate() {
  27. const results = [];
  28. let valid = true;
  29. errors.value = [];
  30. isValidating.value = true;
  31. for (const item of items.value) {
  32. const itemErrorMessages = await item.validate();
  33. if (itemErrorMessages.length > 0) {
  34. valid = false;
  35. results.push({
  36. id: item.id,
  37. errorMessages: itemErrorMessages
  38. });
  39. }
  40. if (!valid && props.fastFail) break;
  41. }
  42. errors.value = results;
  43. isValidating.value = false;
  44. return {
  45. valid,
  46. errors: errors.value
  47. };
  48. }
  49. function reset() {
  50. items.value.forEach(item => item.reset());
  51. }
  52. function resetValidation() {
  53. items.value.forEach(item => item.resetValidation());
  54. }
  55. watch(items, () => {
  56. let valid = 0;
  57. let invalid = 0;
  58. const results = [];
  59. for (const item of items.value) {
  60. if (item.isValid === false) {
  61. invalid++;
  62. results.push({
  63. id: item.id,
  64. errorMessages: item.errorMessages
  65. });
  66. } else if (item.isValid === true) valid++;
  67. }
  68. errors.value = results;
  69. model.value = invalid > 0 ? false : valid === items.value.length ? true : null;
  70. }, {
  71. deep: true,
  72. flush: 'post'
  73. });
  74. provide(FormKey, {
  75. register: _ref => {
  76. let {
  77. id,
  78. vm,
  79. validate,
  80. reset,
  81. resetValidation
  82. } = _ref;
  83. if (items.value.some(item => item.id === id)) {
  84. consoleWarn(`Duplicate input name "${id}"`);
  85. }
  86. items.value.push({
  87. id,
  88. validate,
  89. reset,
  90. resetValidation,
  91. vm: markRaw(vm),
  92. isValid: null,
  93. errorMessages: []
  94. });
  95. },
  96. unregister: id => {
  97. items.value = items.value.filter(item => {
  98. return item.id !== id;
  99. });
  100. },
  101. update: (id, isValid, errorMessages) => {
  102. const found = items.value.find(item => item.id === id);
  103. if (!found) return;
  104. found.isValid = isValid;
  105. found.errorMessages = errorMessages;
  106. },
  107. isDisabled,
  108. isReadonly,
  109. isValidating,
  110. isValid: model,
  111. items,
  112. validateOn: toRef(props, 'validateOn')
  113. });
  114. return {
  115. errors,
  116. isDisabled,
  117. isReadonly,
  118. isValidating,
  119. isValid: model,
  120. items,
  121. validate,
  122. reset,
  123. resetValidation
  124. };
  125. }
  126. export function useForm(props) {
  127. const form = inject(FormKey, null);
  128. return {
  129. ...form,
  130. isReadonly: computed(() => !!(props?.readonly ?? form?.isReadonly.value)),
  131. isDisabled: computed(() => !!(props?.disabled ?? form?.isDisabled.value))
  132. };
  133. }
  134. //# sourceMappingURL=form.mjs.map