|
|
|
@ -36,7 +36,7 @@ |
|
|
|
|
|
|
|
// Create validation function based on field schema |
|
|
|
const schemaConstraints = schema?.[field]?.constraints |
|
|
|
const validate = createValidatorFromConstraints( |
|
|
|
const validator = createValidatorFromConstraints( |
|
|
|
schemaConstraints, |
|
|
|
validationRules, |
|
|
|
field, |
|
|
|
@ -47,10 +47,11 @@ |
|
|
|
fieldMap[field] = { |
|
|
|
fieldState: makeFieldState( |
|
|
|
field, |
|
|
|
validator, |
|
|
|
defaultValue, |
|
|
|
disabled || fieldDisabled || isAutoColumn |
|
|
|
), |
|
|
|
fieldApi: makeFieldApi(field, defaultValue, validate), |
|
|
|
fieldApi: makeFieldApi(field, defaultValue), |
|
|
|
fieldSchema: schema?.[field] ?? {}, |
|
|
|
} |
|
|
|
|
|
|
|
@ -93,9 +94,11 @@ |
|
|
|
] |
|
|
|
|
|
|
|
// Creates an API for a specific field |
|
|
|
const makeFieldApi = (field, defaultValue, validate) => { |
|
|
|
const makeFieldApi = field => { |
|
|
|
// Sets the value for a certain field and invokes validation |
|
|
|
const setValue = (value, skipCheck = false) => { |
|
|
|
const { fieldState } = fieldMap[field] |
|
|
|
const { defaultValue, validator } = get(fieldState) |
|
|
|
|
|
|
|
// Skip if the value is the same |
|
|
|
if (!skipCheck && get(fieldState).value === value) { |
|
|
|
@ -103,7 +106,7 @@ |
|
|
|
} |
|
|
|
|
|
|
|
const newValue = value == null ? defaultValue : value |
|
|
|
const newError = validate ? validate(newValue) : null |
|
|
|
const newError = validator ? validator(newValue) : null |
|
|
|
|
|
|
|
// Update field state |
|
|
|
fieldState.update(state => { |
|
|
|
@ -127,15 +130,20 @@ |
|
|
|
return !newError |
|
|
|
} |
|
|
|
|
|
|
|
// Clears the value of a certain field back to the initial value |
|
|
|
const clearValue = () => { |
|
|
|
const { fieldState } = fieldMap[field] |
|
|
|
const { defaultValue } = get(fieldState) |
|
|
|
const newValue = initialValues[field] ?? defaultValue |
|
|
|
|
|
|
|
// Update field state |
|
|
|
fieldState.update(state => { |
|
|
|
state.value = newValue |
|
|
|
state.error = null |
|
|
|
return state |
|
|
|
}) |
|
|
|
|
|
|
|
// Update form state |
|
|
|
formState.update(state => { |
|
|
|
state.values = { ...state.values, [field]: newValue } |
|
|
|
delete state.errors[field] |
|
|
|
@ -144,9 +152,37 @@ |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
// Updates the validator rules for a certain field |
|
|
|
const updateValidation = validationRules => { |
|
|
|
const { fieldState } = fieldMap[field] |
|
|
|
const { value, error } = get(fieldState) |
|
|
|
|
|
|
|
// Create new validator |
|
|
|
const schemaConstraints = schema?.[field]?.constraints |
|
|
|
const validator = createValidatorFromConstraints( |
|
|
|
schemaConstraints, |
|
|
|
validationRules, |
|
|
|
field, |
|
|
|
table |
|
|
|
) |
|
|
|
|
|
|
|
// Update validator |
|
|
|
fieldState.update(state => { |
|
|
|
state.validator = validator |
|
|
|
return state |
|
|
|
}) |
|
|
|
|
|
|
|
// If there is currently an error, run the validator again in case |
|
|
|
// the error should be cleared by the new validation rules |
|
|
|
if (error) { |
|
|
|
setValue(value, true) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
setValue, |
|
|
|
clearValue, |
|
|
|
updateValidation, |
|
|
|
validate: () => { |
|
|
|
const { fieldState } = fieldMap[field] |
|
|
|
setValue(get(fieldState).value, true) |
|
|
|
@ -155,13 +191,15 @@ |
|
|
|
} |
|
|
|
|
|
|
|
// Creates observable state data about a specific field |
|
|
|
const makeFieldState = (field, defaultValue, fieldDisabled) => { |
|
|
|
const makeFieldState = (field, validator, defaultValue, fieldDisabled) => { |
|
|
|
return writable({ |
|
|
|
field, |
|
|
|
fieldId: `id-${generateID()}`, |
|
|
|
value: initialValues[field] ?? defaultValue, |
|
|
|
error: null, |
|
|
|
disabled: fieldDisabled, |
|
|
|
defaultValue, |
|
|
|
validator, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|