form.mjs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Composables
  2. import { useProxiedModel } from "./proxiedModel.mjs"; // Utilities
  3. import { computed, inject, 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. });
  73. provide(FormKey, {
  74. register: _ref => {
  75. let {
  76. id,
  77. validate,
  78. reset,
  79. resetValidation
  80. } = _ref;
  81. if (items.value.some(item => item.id === id)) {
  82. consoleWarn(`Duplicate input name "${id}"`);
  83. }
  84. items.value.push({
  85. id,
  86. validate,
  87. reset,
  88. resetValidation,
  89. isValid: null,
  90. errorMessages: []
  91. });
  92. },
  93. unregister: id => {
  94. items.value = items.value.filter(item => {
  95. return item.id !== id;
  96. });
  97. },
  98. update: (id, isValid, errorMessages) => {
  99. const found = items.value.find(item => item.id === id);
  100. if (!found) return;
  101. found.isValid = isValid;
  102. found.errorMessages = errorMessages;
  103. },
  104. isDisabled,
  105. isReadonly,
  106. isValidating,
  107. isValid: model,
  108. items,
  109. validateOn: toRef(props, 'validateOn')
  110. });
  111. return {
  112. errors,
  113. isDisabled,
  114. isReadonly,
  115. isValidating,
  116. isValid: model,
  117. items,
  118. validate,
  119. reset,
  120. resetValidation
  121. };
  122. }
  123. export function useForm() {
  124. return inject(FormKey, null);
  125. }
  126. //# sourceMappingURL=form.mjs.map