multi-field.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import Field from './_field';
  2. import { useFormContext } from 'react-hook-form';
  3. import { Input } from 'app/design/controls'
  4. import React, { useEffect, useState } from 'react';
  5. import { NeoButton } from 'app/design/controls'
  6. import { useTranslation } from 'react-i18next';
  7. import { View, Row } from 'app/design/view';
  8. import { multiFieldFormValues, multiFieldInitialRows } from 'app/lib/form/field-initial-values';
  9. export default function FormFieldMultiField(props) {
  10. const { t } = useTranslation();
  11. const name = props.name;
  12. const minCount = props.minCount || 2;
  13. const [values, setValues] = useState(() => multiFieldInitialRows(props));
  14. const formContext = useFormContext();
  15. useEffect(() => {
  16. // Rows start equal to the form default — write user edits only.
  17. Object.entries(multiFieldFormValues(name, values)).forEach(([key, val]) => {
  18. if (formContext.getValues(key) !== val) formContext.setValue(key, val);
  19. });
  20. }, [props.name, values]);
  21. const addNew = () => {
  22. setValues(prev => [...prev, { 'id': -Date.now(), value: '' }]);
  23. };
  24. const deleteValue = (id) => {
  25. setValues(prev => prev.filter(item => item.id !== id));
  26. };
  27. return (
  28. <Field {...props} error2={formContext.formState.errors[name]}>
  29. <View className='gap-y-2 sm:gap-y-3 w-full'>
  30. {values.map((value, index) => {
  31. return (
  32. <Row key={`vls${index}`} >
  33. <Input
  34. name={props.name}
  35. onChangeText={(text) => {
  36. setValues(prevValues =>
  37. prevValues.map(item =>
  38. item.id === value.id ? { ...item, value: text } : item
  39. )
  40. );
  41. }}
  42. value={value.value}
  43. />
  44. {index >= minCount && <View className='pl-2'><NeoButton onPress={() => deleteValue(value.id)} controlSize="large" image="X" accessibilityLabel={t('Remove')} /></View>}
  45. {index == minCount - 1 && <View className='pl-2'><NeoButton onPress={addNew} controlSize="large" image="Plus" accessibilityLabel={t('Add')} /></View>}
  46. </Row>
  47. )
  48. })}
  49. </View>
  50. </Field>
  51. );
  52. }