1.0.1 • Published 4 years ago

react-easy-form-state v1.0.1

Weekly downloads
3
License
MIT
Repository
github
Last release
4 years ago

With react-easy-form-state you can easily create a form with everything you need:

  • input components (text, select, datepicker, checkbox)
  • field validation
  • internationalization
  • server submission with response handling and errors handling
  • loading overlay

Example with Spring Boot server in https://github.com/radmonteiro/ReactEasyFormStateExample

Simple form example in https://codesandbox.io/s/react-easy-form-state-example-br5gj

Container

FormStateProvider

<FormStateProvider validations={validations} 
                   catalogs={catalogs} 
                   messages={messages} 
                   locale={'en'} 
                   dateFormat={'dd/MM/yyyy'} 
>

    ...

</FormStateProvider>
PropertyTypeDescription
initialState{ }If you want to give intial values for the fields.
catalogs{ }Object with catalogs for SelectInput and
messages{ }Object for internationalization.
localestringLocale to select the messages we want.
validations Validation for 'validator' dependency.
urlSubmitstringUrl to submit form data.
dateFormatstringDate format for datepickers (default is 'yyyy-MM-dd').
successMessagestringAlert message for valid submission (default is 'Success').
loaderMsgstringMessage for loader (default is 'Submitting').
hideSubmitAlertsbooleanIf you do not want alerts with success or error messages after submit.
hideLoaderbooleanIf you do not want an overlay loader.
handleNewStatefunctionIf you need to handle the state after server response.
handleServerErrorsfunctionIf your server responds with errors in a different format than it is handled by this container, you should provide this function to convert your server errors in an object with the structure { message: \, fields: {invalid: \, focus: \, errorMessage: \} }.
handleResponseDatafunctionOverrides the handleResponseData default function. This is the function that will handle data response from server. The default function calls handleNewState and handleServerErrors, so if you redefine this function, the handleNewState and handleServerErrors functions will not be called.
onSubmitfunctionOverrides the FormStateProvider onSubmit function.

Properties messages and locale are optional. You don't need to use these if you do not want internationalization, then when you call Input components from this lib you need to use labelText and tooltipText. If you want internationalization use label and tooltip.

The default handleServerErrors function can read the errors in server response if the data object has the following structure:

{
    errors: {
        errorMessage : <STRING>, 
        fields : { 
            <FIELD_NAME>: <STRING>, 
            ...
        }
    }
}

For example:

{
    errors: {
        errorMessage : 'Please correct field errors', 
        fields : { 
            email: 'Invalid email'
            password: 'Password is not strong'
        }
    }
}

Submission default handler functions

handleServerErrors:

handleServerErrorsDefault = data => {

    /**
     * Handle server validation errors
     */
    if(Object.keys(data.errors).length > 0) {

        let focusOnField = true;

        let validationErrors = {};
        Object.keys(data.errors.fields).forEach(el => {
            let val = {
                invalid: true,
                focus: focusOnField,
                errorMessage: data.errors.fields[el]
            }
            focusOnField = false;

            validationErrors[el] = val;
        })


        delete data.errors;

        return {
            message: data.errors.message,
            fields: validationErrors
        }
    }

    return {
        message: '',
        fields: {}
    };

}

####handleResponseData:

handleResponseDataDefault = ( {setState, setValidationErrors, afterHandleResponse, handleServerErrors} ) => data => {

    handleServerErrors = handleServerErrors ?? handleServerErrorsDefault;

    if (data.urlRedirect) {
        window.location.href = data.urlRedirect;
        return;
    }

    let serverErrors = handleServerErrors(data);

    setValidationErrors(serverErrors);

    /**
     * Replace state with values sent from server
     */
    setState(prevState => {
        let newState = {
            ...prevState,
            ...data
        }

        afterHandleResponse(newState);

        return newState;

    });

};

Components

ButtonSubmit

<ButtonSubmit labelText={'Submit'} />

Required properties:

  • label or labelText
PropertyTypeDescription
labelstringButton label message id.
labelTextstringButton label in text.
readOnlybooleanDefines HTML \ readonly attribute.
disabledbooleanDefines HTML \ disabled attribute.
onClickfunctionHandler function called before form submission. Optional, only if you need some customized handling. If you need to override the form onSubmit use FormStateProvider onSubmit property.

TextInput

<TextInput labelText={'Name'}
           name={'name'}
/>

Required properties:

  • name
  • label or labelText
PropertyTypeDescription
namestringInput name, this will be the property name in the state.
labelstringField label message id. Use this instead of labelText when you want internationalization.
labelTextstringField label in text. Use this instead of label if you do not want internationalization.
placeholderstringInput placeholder.
tooltipstringTooltip message id. Use this instead of tooltipText when you want internationalization.
tooltipTextstringTooltip text. Use this instead of tooltip if you do not want internationalization.
readOnlybooleanDefines HTML \ readonly attribute.
disabledbooleanDefines HTML \ disabled attribute.
onChangefunctionIf you need extra handling besides setting state to the form state.
initialValuestringInitial field value.
visiblebooleanFalse to hide this input. Default value is true.

SelectInput

<SelectInput labelText={'Type'}
             name={'type'}
/>

Required properties:

  • name
  • label or labelText
  • catalog: required if it was not passed in the catalogs property of the FormStateProvider
PropertyTypeDescription
labelstringField label message id. Use this instead of labelText when you want internationalization.
labelTextstringField label in text. Use this instead of label if you do not want internationalization.
namestringInput name, this will be the property name in the state.
tooltipstringTooltip message id. Use this instead of tooltipText when you want internationalization.
tooltipTextstringTooltip text. Use this instead of tooltip if you do not want internationalization.
tooltipTextstringTooltip text.
disabledbooleanDefines HTML \ disabled attribute.
onChangefunctionIf you need extra handling besides setting state to the form state.
catalog {id: '', text: ''}, ... Dropdown options. If you passed the catalog in FormStateProvider catalogs property, this is not required.
initialValuestring (catalog option id)Initial value.
visiblebooleanFalse to hide this input. Default value is true.

SelectRadioInput

<SelectRadioInput labelText={'Gender'}
                  name={'gender'}
/>

Required properties:

  • name
  • label or labelText
  • catalog: required if it was not passed in the catalogs property of the FormStateProvider
PropertyTypeDescription
labelstringField label message id. Use this instead of labelText when you want internationalization.
labelTextstringField label in text. Use this instead of label if you do not want internationalization.
namestringInput name, this will be the property name in the state.
tooltipstringTooltip message id. Use this instead of tooltipText when you want internationalization.
tooltipTextstringTooltip text. Use this instead of tooltip if you do not want internationalization.
catalog {id: '', text: ''}, ... Radio options. If you passed the catalog in FormStateProvider catalogs property, this is not required.
onChangefunctionIf you need extra handling besides setting state to the form state.
visiblebooleanFalse to hide this input. Default value is true.

DatePickerInput

<DatePickerInput labelText={'Birthday'}
                 name={'birthday'}
/>

Required properties:

  • name
  • label or labelText
PropertyTypeDescription
labelstringField label message id. Use this instead of labelText when you want internationalization.
labelTextstringField label in text. Use this instead of label if you do not want internationalization.
namestringInput name, this will be the property name in the state.
tooltipstringTooltip message id. Use this instead of tooltipText when you want internationalization.
tooltipTextstringTooltip text. Use this instead of tooltip if you do not want internationalization.
onChangefunctionIf you need extra handling besides setting state to the form state.
visiblebooleanFalse to hide this input. Default value is true.

HiddenInput

<HiddenInput name={'some'}
             value={'someValue'}
/>

Required properties:

  • name
  • value
PropertyTypeDescription
namestringInput name, this will be the property name in the state.
valueanyInput value form data.

Field Validation

For validation it is used the 'validator' dependency, so you can use 'validator' methods like 'isEmpty', or you can implement your own methods. See the example below.

Example

export const SimpleExampleApp = () => {


    const urlSubmit = 'example-url'

    const validateLength = (value) => {
        return value.length > 3;
    };

    const validations =
        [
            {
                field: 'name',
                method: 'isEmpty',
                validWhen: false,
                errorMessage: 'Required'
            },
            {
                field: 'name',
                method: validateLength,
                validWhen: true,
                errorMessage: 'Invalid length'
            }
        ];

    const [isAdmin, setIsAdmin] = React.useState(false);

    const onChangeType = value => {
        setIsAdmin(value === 'admin');
    }

    const catalogs = {
        type: [
            {id: 'admin', text: 'Administrator'},
            {id: 'normal', text: 'Normal user'}
        ],
        gender: [
            {id: 'M', text: 'Male'},
            {id: 'F', text: 'Female'}
        ]
    }

    return (

        <>

            <FormStateProvider urlSubmit={urlSubmit} validations={validations} catalogs={catalogs} messages={messages} locale={'en'} dateFormat={'dd/MM/yyyy'}>

                <TextInput label={'input.name'}
                                name={'name'}
                           tooltip={'tooltip.name'}
                />

                <TextInput labelText={'Email'}
                                name={'email'}
                />

                <SelectInput labelText={'Type'}
                                  name={'type'}
                                  onChange={onChangeType}
                />

                <TextInput labelText={'Password'}
                                name={'password'}
                                visible={isAdmin}
                />


                <SelectRadioInput labelText={'Gender'}
                             name={'gender'}

                />


                <DatePickerInput labelText={'Birthday'}
                                 name={'birthday'}

                />

                <HiddenInput name={'birthday'}
                             value={'some hidden value'}
                />



                <CheckboxInput labelText={'Accept conditions'}
                               name={'acceptConditions'}
                />

                <ButtonSubmit labelText={'Submit'} />



            </FormStateProvider>
        </>
    )
};