formik#useField JavaScript Examples

The following examples show how to use formik#useField. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RadioButton.js    From UltimateApp with MIT License 6 votes vote down vote up
RadioButton = ({ fieldName, label, values, labels, ...props }) => {
  const [field, meta] = useField(fieldName);

  const renderButton = (possibleValue, index) => {
    const selectedStyle = field.value === possibleValue ? styles.selectedButton : undefined;
    const onPress = () => {
      field.onChange(fieldName)(possibleValue);
    };
    return (
      <TouchableOpacity
        style={[styles.button, selectedStyle]}
        key={index}
        onPress={onPress}
        testID={`input-${fieldName}-${possibleValue}`}
      >
        <Text style={styles.buttonText}>{labels[index]}</Text>
      </TouchableOpacity>
    );
  };

  return (
    <View style={styles.group}>
      <Text style={styles.label}>{label}</Text>
      {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
      <View style={styles.buttons}>{values.map(renderButton)}</View>
    </View>
  );
}
Example #2
Source File: FormControls.js    From declaratie with Apache License 2.0 6 votes vote down vote up
FCK = ({ children, hasError, ...props }) => {
  const [field, meta] = useField({ ...props, type: "checkbox" });
  return (
    <>
      <Label style={{ border: hasError ? "1px solid red" : "" }}>
        <Checkbox hasError={Boolean(meta.touched && meta.error)} checked={field.checked} />
        <Input type="checkbox" {...field} {...props} />
        {children}
      </Label>
    </>
  );
}
Example #3
Source File: form.js    From stacker.news with MIT License 6 votes vote down vote up
export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra, handleChange, inline, ...props }) {
  // React treats radios and checkbox inputs differently other input types, select, and textarea.
  // Formik does this too! When you specify `type` to useField(), it will
  // return the correct bag of props for you
  const [field] = useField({ ...props, type: 'checkbox' })
  return (
    <BootstrapForm.Group className={groupClassName}>
      {hiddenLabel && <BootstrapForm.Label className='invisible'>{label}</BootstrapForm.Label>}
      <BootstrapForm.Check
        custom
        id={props.id || props.name}
        inline={inline}
      >
        <BootstrapForm.Check.Input
          {...field} {...props} type='checkbox' onChange={(e) => {
            field.onChange(e)
            handleChange && handleChange(e.target.checked)
          }}
        />
        <BootstrapForm.Check.Label className='d-flex'>
          <div className='flex-grow-1'>{label}</div>
          {extra &&
            <div className={styles.checkboxExtra}>
              {extra}
            </div>}
        </BootstrapForm.Check.Label>
      </BootstrapForm.Check>
    </BootstrapForm.Group>
  )
}
Example #4
Source File: form.js    From stacker.news with MIT License 6 votes vote down vote up
export function MarkdownInput ({ label, groupClassName, ...props }) {
  const [tab, setTab] = useState('write')
  const [, meta] = useField(props)

  useEffect(() => {
    !meta.value && setTab('write')
  }, [meta.value])

  return (
    <FormGroup label={label} className={groupClassName}>
      <div className={`${styles.markdownInput} ${tab === 'write' ? styles.noTopLeftRadius : ''}`}>
        <Nav variant='tabs' defaultActiveKey='write' activeKey={tab} onSelect={tab => setTab(tab)}>
          <Nav.Item>
            <Nav.Link eventKey='write'>write</Nav.Link>
          </Nav.Item>
          <Nav.Item>
            <Nav.Link eventKey='preview' disabled={!meta.value}>preview</Nav.Link>
          </Nav.Item>
          <a
            className='ml-auto text-muted d-flex align-items-center'
            href='https://guides.github.com/features/mastering-markdown/' target='_blank' rel='noreferrer'
          >
            <Markdown width={18} height={18} />
          </a>
        </Nav>
        <div className={tab !== 'write' ? 'd-none' : ''}>
          <InputInner
            {...props}
          />
        </div>
        <div className={tab !== 'preview' ? 'd-none' : 'form-group'}>
          <div className={`${styles.text} form-control`}>
            {tab === 'preview' && <Text>{meta.value}</Text>}
          </div>
        </div>
      </div>
    </FormGroup>
  )
}
Example #5
Source File: index.js    From AED-Map with MIT License 6 votes vote down vote up
MySelect = ({
  label,
  labelTitle,
  options,
  variant,
  classes,
  ...props
}) => {
  const [field] = useField(props);
  const inputLabel = useRef(null);
  const [labelWidth, setLabelWidth] = useState(0);

  useEffect(() => {
    setLabelWidth(inputLabel.current.offsetWidth);
  }, []);

  return (
    <FormControl className={classes} variant={variant}>
      <InputLabel id={label} ref={inputLabel}>
        {labelTitle}
      </InputLabel>
      <Select
        labelId={label}
        labelWidth={labelWidth}
        {...field}
        {...props}
      >
        {options.map(option => (
          <MenuItem key={option} value={option}>
            {option || <em>всі</em>}
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}
Example #6
Source File: index.js    From AED-Map with MIT License 6 votes vote down vote up
MyInputBase = props => {
  const [field] = useField(props);

  return (
    <InputBase
      className="text-input"
      {...field}
      {...props}
    />
  );
}
Example #7
Source File: index.js    From AED-Map with MIT License 6 votes vote down vote up
MyTextField = props => {
  const [field, meta] = useField(props);
  const classes = useStyles();

  return (
    <TextField
      className={classes.textField}
      helperText={meta.touched ? meta.error : ''}
      error={meta.touched && Boolean(meta.error)}
      {...field}
      {...props}
    />
  );
}
Example #8
Source File: FormikField.js    From supportal-frontend with MIT License 6 votes vote down vote up
FormikField = ({ name, error, ...rest }) => {
  const [field, meta] = useField(name);
  const Component = name !== 'state' ? TextInput : SelectInput;
  const fieldError = error || (meta.touched && meta.error ? meta.error : null);
  const props = {
    id: `formik-field-${name}`,
    error: fieldError,
    required: true,
    ...field,
    ...rest,
  };
  if (name === 'state') {
    props.options = [
      '',
      ...Object.entries(stateHash)
        .sort(([a], [b]) => `${a}`.localeCompare(b))
        .map(([value, label]) => ({
          value,
          label: `${value} - ${label}`,
        })),
    ];
  }
  return <Component {...props} />;
}
Example #9
Source File: Input.js    From UltimateApp with MIT License 6 votes vote down vote up
Input = ({ fieldName, label, required, multiline, ...props }) => {
  const [isFocused, setIsFocused] = useState(false);
  const [field, meta] = useField(fieldName);

  const borderColor = isFocused ? styles.focusedInput : meta.error && meta.touched ? styles.errorInput : undefined;
  const multilineProps = multiline ? { multiline: true, numberOfLines: 3, textAlignVertical: 'top' } : undefined;

  return (
    <View style={styles.group}>
      <View style={styles.label}>
        {required && <Text style={styles.error}>* </Text>}
        <Text>{label}</Text>
      </View>
      <View style={[styles.input, borderColor]}>
        {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
        <TextInput
          testID={`input-${fieldName}`}
          onChangeText={field.onChange(fieldName)}
          value={field.value?.toString()}
          onFocus={() => setIsFocused(true)}
          onBlur={() => setIsFocused(false)}
          {...multilineProps}
          {...props}
        />
      </View>
    </View>
  );
}
Example #10
Source File: Checkbox.js    From UltimateApp with MIT License 6 votes vote down vote up
Checkbox = ({ fieldName, label, values, labels, ...props }) => {
  const [field, meta, helpers] = useField(fieldName);

  const renderCheckbox = (possibleValue, index) => {
    const selected = field.value.includes(possibleValue);

    const onPress = () => {
      const existingValueIndex = field.value.findIndex((v) => v === possibleValue);
      if (existingValueIndex === -1) {
        helpers.setValue([...field.value, possibleValue]);
      } else {
        helpers.setValue(field.value.filter((value, index) => index !== existingValueIndex));
      }
    };

    return (
      <NativeCheckbox
        checked={field.value.includes(possibleValue)}
        onPress={onPress}
        key={index}
        testID={`input-${fieldName}-${possibleValue}`}
        title={labels[index]}
        containerStyle={styles.checkbox}
        textStyle={styles.checkboxText}
        checkedColor={theme.MAIN_COLOR}
      />
    );
  };

  return (
    <View style={styles.group}>
      <Text style={styles.label}>{label}</Text>
      {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
      <View style={styles.wrapper}>{values.map(renderCheckbox)}</View>
    </View>
  );
}
Example #11
Source File: FormikMuiFields.js    From reddish with MIT License 6 votes vote down vote up
TextInput = ({
  placeholder,
  label,
  type,
  required,
  fullWidth,
  InputProps,
  multiline,
  rows,
  rowsMax,
  variant,
  size,
  disabled,
  ...props
}) => {
  const [field, meta] = useField(props);
  const errorText = meta.error && meta.touched ? meta.error : '';

  return (
    <TextField
      placeholder={placeholder}
      label={label}
      type={type}
      InputProps={InputProps}
      required={required}
      fullWidth
      multiline={multiline}
      rows={rows}
      rowsMax={rowsMax}
      variant={variant}
      size={size}
      disabled={disabled}
      {...field}
      helperText={errorText}
      error={!!errorText}
    />
  );
}
Example #12
Source File: FormTextArea.jsx    From hrms-project-frontend with MIT License 6 votes vote down vote up
export default function FormTextArea({
  name,
  label = toHeaderCase(name),
  rows = 3,
  className,
  disabled,
}) {
  const [field, meta] = useField(name);

  return (
    <div className={`mb-3 ${className}`}>
      <label htmlFor={`${name}-textarea`} className='form-label fw-bold'>
        {label}
      </label>
      <div className='input-group has-validation'>
        <textarea
          {...field}
          {...{ name, rows }}
          id={`${name}-textarea`}
          className={`form-control ${
            meta.touched && !!meta.error ? "is-invalid" : ""
          }`}
          aria-describedby={`${name}-textarea`}
          disabled={disabled}
        />
        {meta.touched && !!meta.error ? (
          <div id={`${name}-textarea`} className='invalid-feedback'>
            {toSentenceCase(meta.error)}
          </div>
        ) : null}
      </div>
    </div>
  );
}
Example #13
Source File: FormInput.jsx    From hrms-project-frontend with MIT License 6 votes vote down vote up
export default function FormInput({
  type,
  name,
  label = toHeaderCase(name),
  placeholder = `Please enter ${toHeaderCase(name)}`,
  className,
  render,
}) {
  const [field, meta] = useField(name);

  return (
    <div className='mb-3'>
      {label && (
        <label htmlFor={`${name}-input`} className='form-label fw-bold'>
          {label}
        </label>
      )}
      <div className='input-group has-validation'>
        <input
          {...field}
          {...{ name, placeholder }}
          type={type}
          id={`${name}-input`}
          className={`form-control ${className} ${
            meta.touched && !!meta.error ? "is-invalid" : ""
          }`}
          aria-describedby={`${name}-input`}
        />
        {render}
        {meta.touched && !!meta.error ? (
          <div id={`${name}-input`} className='invalid-feedback'>
            {toSentenceCase(meta.error)}
          </div>
        ) : null}
      </div>
    </div>
  );
}
Example #14
Source File: FormFileInput.jsx    From hrms-project-frontend with MIT License 6 votes vote down vote up
export default function FormFileInput({
  name,
  accept,
  label = toHeaderCase(name),
  className,
  render,
}) {
  const [, meta, helper] = useField(name);

  return (
    <div className='mb-3'>
      {label && (
        <label htmlFor={`${name}-file-input`} className='form-label fw-bold'>
          {label}
        </label>
      )}
      <div className='input-group has-validation'>
        <input
          {...{ name, accept }}
          type='file'
          onChange={(e) => helper.setValue(e.currentTarget.files[0])}
          id={`${name}-file-input`}
          className={`form-control ${className} ${
            meta.touched && !!meta.error ? "is-invalid" : ""
          }`}
          aria-describedby={`${name}-file-input`}
        />
        {render}
        {meta.touched && !!meta.error ? (
          <div id={`${name}-file-input`} className='invalid-feedback'>
            {toSentenceCase(meta.error)}
          </div>
        ) : null}
      </div>
    </div>
  );
}
Example #15
Source File: submit-profile-form.js    From proof-of-humanity-web with MIT License 6 votes vote down vote up
function UpdateTotalCost({ totalCost }) {
  const { web3 } = useWeb3();
  const totalCostRef = useRef(totalCost);
  const field = useField("contribution");
  const setValue = field[2].setValue;
  useEffect(() => {
    if (totalCost && totalCostRef.current !== web3.utils.fromWei(totalCost)) {
      totalCostRef.current = web3.utils.fromWei(totalCost);
      setValue(totalCostRef.current);
    }
  }, [totalCost, setValue, web3.utils]);
  return null;
}
Example #16
Source File: AnimationInput.js    From UltimateApp with MIT License 5 votes vote down vote up
Input = ({ fieldName, label, required, ...props }) => {
  const [isFocused, setIsFocused] = useState(false);
  const [field, meta, helpers] = useField(fieldName);
  const navigation = useNavigation();

  const goToEditAnimation = () => {
    navigation.navigate('DrillEditorAnimationPage', {
      animation: field.value,
      onAnimationChange,
    });
  };

  const onAnimationChange = (animation) => {
    helpers.setValue(animation);
  };

  return (
    <View style={styles.group}>
      <View style={styles.label}>
        {required && <Text style={styles.error}>* </Text>}
        <Text>{label}</Text>
      </View>
      <View style={styles.buttons}>
        <Button
          onPress={() => goToEditAnimation()}
          text={field.value ? I18n.t('shared.form.animationInput.edit') : I18n.t('shared.form.animationInput.add')}
          small
          light
          style={styles.button}
          testID="editAnimation"
        />
        {field.value && (
          <Button
            onPress={() => onAnimationChange(undefined)}
            text={I18n.t('shared.form.animationInput.clear')}
            small
            light
            testID="deleteAnimation"
            style={styles.button}
          />
        )}
      </View>
      {meta.error && meta.touched && <Text style={styles.error}>{meta.error}</Text>}
    </View>
  );
}
Example #17
Source File: FormikMuiFields.js    From reddish with MIT License 5 votes vote down vote up
RadioInput = ({ label, ...props }) => {
  const [field] = useField(props);
  return <FormControlLabel {...field} control={<Radio />} label={label} />;
}
Example #18
Source File: DefaultSelect.js    From react-eclipsefdn-members with Eclipse Public License 2.0 5 votes vote down vote up
DefaultSelect = (props) => {
  const [, meta] = useField(props.field.name);

  const handleSelect = (option, action) => {
    if (option && action !== 'clear') {
      props.form.setFieldValue(props.field.name, option);
      // If changing the selected working group, reset the participation level value
      if (
        props.participationLevel &&
        option.value !== props.field.value.value
      ) {
        props.form.setFieldValue(props.participationLevel, '');
      }
    }

    if (action.action === 'clear') {
      props.form.setFieldValue(props.field.name, '');
      // reset the participation level value when clearing the working group select field
      if (props.participationLevel) {
        props.form.setFieldValue(props.participationLevel, '');
      }
    }
  };

  return (
    <Select
      aria-labelledby={props.ariaLabel}
      isClearable
      isSearchable
      options={props.options}
      value={props.field.value || ''}
      onChange={(option, action) => {
        handleSelect(option, action);
      }}
      onBlur={props.form.handleBlur(props.field.name)} // Inherit the handleBlur from formik
      className="margin-bottom-10 form-group"
      styles={generateCustomStyles(false, meta.error)}
      theme={selectTheme}
    />
  );
}
Example #19
Source File: FormSelect.jsx    From hrms-project-frontend with MIT License 5 votes vote down vote up
export default function FormSelect({
  name,
  options,
  placeholder = `Select ${toHeaderCase(name)}`,
  label = toHeaderCase(name),
  className,
  search = true,
}) {
  const [filterText, setFilterText] = useState(""),
    [fieldLabel, setFieldLabel] = useState("");

  const [, meta, helper] = useField(name);

  const setField = (value, label) => {
    helper.setValue(value);
    setFieldLabel(label);
  };

  return (
    <div className={`mb-3 ${className}`}>
      {label && (
        <label htmlFor={`${name}Select`} className='form-label fw-bold'>
          {label}
        </label>
      )}

      <div className='dropdown'>
        <button
          className='position-relative btn btn-white dropdown-toggle w-100 d-flex justify-content-between align-items-center'
          type='button'
          id={`${name}-select`}
          data-bs-toggle='dropdown'
          aria-expanded='false'
        >
          {!!meta.error ? <div className='select-input-invalid-feedback'></div> : null}
          {fieldLabel || placeholder}
        </button>

        <ul className='dropdown-menu w-100 p-2 rounded' aria-labelledby={`${name}-select`}>
          {search && (
            <div className='input-group mb-2'>
              <span className='input-group-text' id={`${name}-search-input-icon`}>
                <i className='bi bi-search' />
              </span>
              <input
                type='text'
                name='filterText'
                className='form-control'
                placeholder='Search'
                aria-describedby={`${name}-search-input-icon`}
                aria-label='Username'
                autoComplete='off'
                onChange={(e) => setFilterText(e.target.value)}
              />
            </div>
          )}

          {options
            .filter((o) => o.label.toLowerCase().includes(filterText.toLowerCase()))
            .map((option, index) => (
              <li
                key={index}
                onClick={() => setField(option.value, option.label)}
                className={`dropdown-item cursor-pointer ${fieldLabel === option ? "active" : ""}`}
              >
                {option.label}
              </li>
            ))}
        </ul>
        {!!meta.error ? <div className='text-danger ms-1'>{toSentenceCase(meta.error)}</div> : null}
      </div>
    </div>
  );
}
Example #20
Source File: index.js    From realworld with MIT License 5 votes vote down vote up
export function TagsInput(props) {
  const [value, setValue] = useState('');

  const component = useQuery(TagsInputQuery, {
    returnPartialData: true,
  });

  const [field, , helpers] = useField(props);

  const handleRemove = tag => {
    helpers.setValue(field.value.filter(id => id !== tag.id));
  };

  return (
    <>
      <p>
        <input
          type="text"
          className="form-control"
          placeholder="Press enter to add tag to list"
          list="tags"
          id={props.id}
          name={field.name}
          onBlur={field.onBlur}
          value={value}
          onKeyDown={event => {
            if (event.key === 'Enter') {
              event.preventDefault();
              const tag = component.data.tags.find(
                tag => tag.name === event.currentTarget.value
              );
              if (tag?.id) {
                if (field.value.includes(tag.id) === false) {
                  helpers.setValue(field.value.concat(tag.id));
                  setValue('');
                  event.currentTarget.blur();
                  event.currentTarget.focus();
                }
              } else {
                // TODO: create tag and refetch TagsInputQuery
              }
            }
          }}
          onChange={event => {
            event.preventDefault();
            setValue(event.currentTarget.value);
          }}
        />
        <datalist id="tags">
          {(component.data?.tags ?? []).map(tag => (
            <option value={tag.name} key={tag.id} />
          ))}
        </datalist>
      </p>
      <div className="tag-list">
        {field.value.map(id => (
          <TagsInputTag id={id} key={id} onRemoveTag={handleRemove} />
        ))}
      </div>
    </>
  );
}
Example #21
Source File: form.js    From stacker.news with MIT License 5 votes vote down vote up
function InputInner ({
  prepend, append, hint, showValid, onChange, overrideValue,
  innerRef, storageKeyPrefix, ...props
}) {
  const [field, meta, helpers] = props.readOnly ? [{}, {}, {}] : useField(props)
  const formik = props.readOnly ? null : useFormikContext()

  const storageKey = storageKeyPrefix ? storageKeyPrefix + '-' + props.name : undefined

  useEffect(() => {
    if (overrideValue) {
      helpers.setValue(overrideValue)
      if (storageKey) {
        localStorage.setItem(storageKey, overrideValue)
      }
    } else if (storageKey) {
      const draft = localStorage.getItem(storageKey)
      if (draft) {
        // for some reason we have to turn off validation to get formik to
        // not assume this is invalid
        helpers.setValue(draft, false)
      }
    }
  }, [overrideValue])

  return (
    <>
      <InputGroup hasValidation>
        {prepend && (
          <InputGroup.Prepend>
            {prepend}
          </InputGroup.Prepend>
        )}
        <BootstrapForm.Control
          onKeyDown={(e) => {
            if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) {
              formik?.submitForm()
            }
          }}
          ref={innerRef}
          {...field} {...props}
          onChange={(e) => {
            field.onChange(e)

            if (storageKey) {
              localStorage.setItem(storageKey, e.target.value)
            }

            if (onChange) {
              onChange(formik, e)
            }
          }}
          isInvalid={meta.touched && meta.error}
          isValid={showValid && meta.initialValue !== meta.value && meta.touched && !meta.error}
        />
        {append && (
          <InputGroup.Append>
            {append}
          </InputGroup.Append>
        )}
        <BootstrapForm.Control.Feedback type='invalid'>
          {meta.touched && meta.error}
        </BootstrapForm.Control.Feedback>
      </InputGroup>
      {hint && (
        <BootstrapForm.Text>
          {hint}
        </BootstrapForm.Text>
      )}
    </>
  )
}
Example #22
Source File: form.js    From proof-of-humanity-web with MIT License 5 votes vote down vote up
export function Field({ label, as = Input, sx, name, info, ...rest }) {
  const validationSchema = useContext(ValidationSchemaContext);
  const field = useField(name);
  const [{ onChange }, { touched, error, initialValue }, { setValue }] = field;
  const showError = touched && error;
  return (
    <Label onClick={(event) => event.preventDefault()}>
      {typeof label === "function" ? label({ field }) : label}
      <Box
        sx={{
          marginTop: 1,
          position: "relative",
          ...(as === Checkbox && { display: "flex" }),
        }}
      >
        <_Field
          className={showError ? "error" : undefined}
          as={as}
          sx={{
            ":focus": {
              boxShadow(theme) {
                return `0 0 6px ${alpha("highlight", 0.25)(theme)}`;
              },
            },
            ...(typeof sx === "function" ? sx({ field }) : sx),
          }}
          name={name}
          onChange={(event) => {
            try {
              event.target.value = reach(validationSchema, name).render(
                event.target.value
              );
              onChange(event);
            } catch {
              onChange(event);
            }
          }}
          {...rest}
        />
        {as === Checkbox && info && (
          <Text variant="forms.field.info" sx={{ marginLeft: 2 }}>
            {info}
          </Text>
        )}
        {as === Input && showError && (
          <X
            variant="forms.field.error.icon"
            sx={{
              position: "absolute",
              right: 2,
              top: "50%",
              transform: "translateY(-50%)",
            }}
            onClick={(event) => {
              event.preventDefault();
              setValue(initialValue);
            }}
          />
        )}
      </Box>
      {as !== Checkbox && info && (
        <Text variant="forms.field.info">{info}</Text>
      )}
      <Text variant="forms.field.error">
        <ErrorMessage name={name} />
      </Text>
    </Label>
  );
}
Example #23
Source File: FormControls.js    From declaratie with Apache License 2.0 5 votes vote down vote up
FTF = props => {
  // useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
  // which we can spread on <input> and also replace ErrorMessage entirely.
  const [field, meta] = useField(props);
  return <TextField hasError={Boolean(meta.touched && meta.error)} {...field} {...props} />;
}
Example #24
Source File: CustomAsyncSelect.js    From react-eclipsefdn-members with Eclipse Public License 2.0 4 votes vote down vote up
CustomAsyncSelect = (props) => {
  const {
    organizationName,
    organizationAddress,
    organizationTwitter,
  } = formField;
  const [field, meta] = useField(props.field.name); // or props.field, must contain name key

  /**
   * @param option -
   *        the option you are selecting
   * @param action -
   *        type ActionTypes = | 'clear' | 'create-option' | 'deselect-option' | 'pop-value' | 'remove-value' | 'select-option' | 'set-value'
   * Please refer to: https://react-select.com/props#prop-types
   *
   * option.__isNew__ defines wether the option is from the option list or input by the user
   */
  const handleSelect = (option, action) => {
    if (option && !option.__isNew__ && action !== 'clear') {
      if (props.srcData === companies) {
        let country = {
          label: option.address.country,
          value: option.address.country,
        };

        // Prefill existing data to selected companies
        props.form.setFieldValue(organizationName.name, option);
        props.form.setFieldValue(
          organizationAddress.address.name,
          option.address
        );
        props.form.setFieldValue(organizationAddress.country.name, country);
        props.form.setFieldValue(
          organizationTwitter.name,
          option.twitterHandle
        );
      }
    }

    if (action.action === 'clear') {
      // Clear prefilled data when clear the selection
      if (props.srcData === companies) {
        // Need to reset the fields one by one, because the organization
        // is a nested field, which cannot be reset to a string

        // If you do: `setFieldValue('organization', '')`, will get
        // warning claiming that `Warning: A component is changing a
        // controlled input to be uncontrolled. This is likely caused
        // by the value changing from a defined to undefined, which
        // should not happen`;

        // !!! And We do not want to reset the Id Field !!!

        // Another way to reset is: (these require you get the exsiting org Id)

        /**
         * setFieldValue('organization', {
         *    id: existing id,
         *    legalName: '',
         *    address: {
         *      id: '',
         *      street: '',
         *      city: '',
         *      provinceOrState: '',
         *      country: '',
         *      postalCode: ''
         *    }
         *    twitterHandle: ''
         * })
         *
         *
         * Or
         * import { initialValues } from '../../formModels/formFieldModel'
         * setFieldValue('organization', initialValues.organization)
         * setFieldValue('organization.id', existing id)
         * **/

        props.form.setFieldValue(organizationName.name, '');
        props.form.setFieldValue(organizationAddress.street.name, '');
        props.form.setFieldValue(organizationAddress.city.name, '');
        props.form.setFieldValue(organizationAddress.provinceOrState.name, '');
        props.form.setFieldValue(organizationAddress.country.name, '');
        props.form.setFieldValue(organizationAddress.postalCode.name, '');
        props.form.setFieldValue(organizationTwitter.name, '');
      }
    }

    if (option && option.__isNew__) {
      // When create new organization that are not in our data
      props.form.setFieldValue(organizationName.name, option);
    }
  };

  const promiseOptions = async (inputValue) => {
    // Will use this if the api supports search
    // if(inputValue) {
    //   src_data = src_data + `?search=${inputValue}`
    // }

    let src_data;

    switch (props.srcData) {
      // This is currently using a fake data in public/companies.json
      case companies:
        src_data = 'companies.json';
        if (inputValue) {
          return fetch(src_data, { headers: FETCH_HEADER })
            .then((resp) => resp.json())
            .then((data) => {
              if (data.companies) {
                return data.companies.map((item) => ({
                  value: item.legalName,
                  label: item.legalName,
                  address: item.address,
                  twitterHandle: item.twitterHandle,
                }));
              }
            });
        } else return [];

      default:
        return [];
    }
  };

  return (
    <AsyncCreatable
      {...field} // Inherit field props
      aria-labelledby={props.ariaLabel}
      isClearable
      isSearchable
      cacheOptions
      defaultOptions
      loadOptions={promiseOptions}
      defaultValue={props.field.value || ''}
      onChange={(option, action) => {
        handleSelect(option, action);
      }}
      onBlur={props.form.handleBlur(props.field.name)} // Inherit the handleBlur from formik
      styles={generateCustomStyles(true, meta.error)}
      theme={selectTheme}
      noOptionsMessage={() => 'Type to Search...'}
      className="margin-bottom-10 form-group"
    />
  );
}