All Downloads are FREE. Search and download functionalities are using the official Maven repository.

components.form.fields.InputDateTimeField.js Maven / Gradle / Ivy

There is a newer version: 0.80.3
Show newest version
import { useEffect, useState } from 'react';
import { useTranslation } from "react-i18next";
import { DesktopDateTimePicker, renderMultiSectionDigitalClockTimeView } from '@mui/x-date-pickers';
import parseISO from 'date-fns/parseISO';
import { isEmptyValue, isValidDate } from "utils/utils";
import { validateField } from "components/form/utils/validate-utils";
import { useFieldInfo } from 'hooks/field';
import { useFormInfo } from 'hooks/form';
import InputError from "components/form/fields/InputError";
import { renderDateDay } from 'components/form/fields/date/DayDate';
import Types from 'types/types';
import { useNotifier } from 'hooks/notification';
import { useAutoSubmitSignal } from 'hooks/autosubmit';
import { useConfig } from 'hooks/config';
import { fieldMinWidthStyle } from 'components/form/utils/field-utils';

function toRuntimeValue(value) {
  try {
    if (value instanceof Date)
      return value.toISOString()
  } catch (error) {
    return null
  }
  return null
}

function toMuiValue(value) {
  try {
    return isEmptyValue(value) ? null : parseISO(value)
  } catch (error) {
    return null
  }
}

const InputDateTimeFieldContent = (props) => {
  const { augProps, fieldProps, info } = useFieldInfo()
  const { setFocus, setViewOpen }      = props
  const { t }                          = useTranslation()
  const formInfo                       = useFormInfo()
  const [error, setError]              = useState(null)
  const [value, setValue]              = useState(toMuiValue(fieldProps.value))
  const notifier                       = useNotifier()
  const {signal}                       = useAutoSubmitSignal()
  const {props: {taskRendering}}       = useConfig()

  delete fieldProps.onChange

  function toHelperText(error) {
    if (info.inMultiple)
      return undefined

    if (fieldProps.error)
      return fieldProps.helperText
    else if (error)
      return t("yup.invalid.datetime")
    else
      return " "
  }

  function handleValidate(e, value) {
    const error = validateField("datetime", fieldProps.required, e, value)
    augProps.setError(error)
  }

  function handleChange(value, context) {
    const { validationError } = context

    augProps.setRuntimeError(undefined)
    setError(validationError)
    setValue(value)
    if (isValidDate(value)) {
      const runtimeValue = toRuntimeValue(value)
      augProps.setValue(runtimeValue)
      handleValidate(null, runtimeValue)
    }
	}

  function handleBlur(e) {
    const val = error ? toRuntimeValue(value) : fieldProps.value 
    if (error || !Types.isValidDate(toMuiValue(val))) {
      augProps.setValue(null)
      setValue(null)
      notifier.error("invalid date in field " + fieldProps.label)
    }

    setFocus(false)
    fieldProps.onBlur(e)
    handleValidate(e, val)
    signal()
  }

  function handleFocus(e) {
    setFocus(true)
    fieldProps.onFocus(e)
  }

  const slotProps = {
    slotProps: {
      textField: (params) => ({
        ...fieldProps,
        onBlur: handleBlur,
        onFocus: handleFocus,
        ...params,

        id: fieldProps.id,
        error:  params.error || fieldProps.error,
        helperText :  toHelperText(params.error),
        style: taskRendering == 'standard' ? fieldMinWidthStyle(formInfo, info.field) : undefined,

        fullWidth: true,
      }),
      actionBar: {actions: ['today','clear', 'cancel', 'accept']},
    }
  }

  // fix for clearing the field
  useEffect(() => {
    if (fieldProps.value != toRuntimeValue(value)) {
      const getValue = () => {
        const newValue = toMuiValue(fieldProps.value)
        return isValidDate(newValue) ? newValue : value
      }
      setValue(getValue())
    }
    if (value == null) 
      augProps.setValue(null)
  }, [fieldProps.value])

  // fix for clearing the field
  useEffect(() => {
    if (value == null)
      augProps.setValue(null)
  }, [value])

  return (
     setViewOpen(true) }
      onClose={() => setViewOpen(false)}

      views={["year", "month","day", "hours", "minutes", "seconds"]}
      viewRenderers={{
        hours: renderMultiSectionDigitalClockTimeView,
        minutes: renderMultiSectionDigitalClockTimeView,
        seconds: renderMultiSectionDigitalClockTimeView,
      }}

      onChange={handleChange}
      {...augProps.inputProps}

      {...slotProps}
    />
  )
}

const InputDateTimeField = (props) => (
  
    
  
)

export default InputDateTimeField




© 2015 - 2024 Weber Informatics LLC | Privacy Policy