Layout

Form package provides FormElement and FieldWrapper components that allow creating horizontal and vertical form layouts. They are designed to work with the components from the Label package and any editors.

Vertical Layout

Vertical layout can be enabled by wrapping the form content inside the FormElement component, and each of the editors inside the FieldWrapper component. The following example uses the components from the Labels package to enhance the editor with label, error and hint texts.

import React from 'react';
import ReactDOM from 'react-dom';
import { Form, Field, FormElement, FieldWrapper } from '@progress/kendo-react-form';
import { Input } from '@progress/kendo-react-inputs';
import { Label, Error, Hint, FloatingLabel } from '@progress/kendo-react-labels';

const emailRegex = new RegExp(/\S+@\S+\.\S+/);
const emailValidator = (value) => (emailRegex.test(value) ? "" : "Please enter a valid email.");
const LabelEmailInput = (fieldRenderProps) => {
    const { validationMessage, visited, label, id, valid, ...others } = fieldRenderProps;
    const showValidationMessage = visited && validationMessage;
    return (
        <FieldWrapper>
            <Label editorId={id} editorValid={valid}>{label}</Label>
            <Input valid={valid} type={'email'} id={id} {...others} />
            {
                !showValidationMessage &&
                    <Hint>Enter your personal email address.</Hint>
            }
            {
                showValidationMessage &&
                    <Error>{validationMessage}</Error>
            }
        </FieldWrapper>
    );
};
const FloatingLabelEmailInput = (fieldRenderProps) => {
    const { validationMessage, visited, label, id, valid, value, ...others } = fieldRenderProps;
    const showValidationMessage = visited && validationMessage;
    return (
        <FieldWrapper>
            <FloatingLabel label={label} editorValue={value} editorValid={valid} editorId={id}>
                <Input value={value} valid={valid} type={'email'} id={id} {...others} />
            </FloatingLabel>
            {
                !showValidationMessage &&
                    <Hint>Enter your personal email address.</Hint>
            }
            {
                showValidationMessage &&
                    <Error>{validationMessage}</Error>
            }
        </FieldWrapper>
    );
};
const App = () => {
    const handleSubmit = (dataItem) => alert(JSON.stringify(dataItem, null, 2));
    return (
        <Form
            onSubmit={handleSubmit}
            render={(formRenderProps) => (
                <FormElement style={{maxWidth: 650}}>
                     <Field
                        id={'email'}
                        name={'email'}
                        label={'Email (Regular Label)'}
                        component={LabelEmailInput}
                        validator={emailValidator}
                    />
                    <Field
                        id={'secondEmail'}
                        name={'secondemail'}
                        label={'Email (Floating Label)'}
                        component={FloatingLabelEmailInput}
                        validator={emailValidator}
                    />
                    <div className="k-form-buttons">
                        <button
                            type={'submit'}
                            className="k-button"
                            disabled={!formRenderProps.allowSubmit}
                        >
                            Submit
                        </button>
                    </div>
                </FormElement>
            )}
        />
    );
};
ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);

Horizontal Layout

Horizontal layout can be enabled by using the setup from the vertical layout and setting the horizontal option of the FormElement component to true. Additionally, if you use the Label component to label the edtor, you need to wrap the editor and error messages in div element with k-form-field-wrap CSS class.

import React from 'react';
import ReactDOM from 'react-dom';
import { Form, Field, FormElement, FieldWrapper } from '@progress/kendo-react-form';
import { Input } from '@progress/kendo-react-inputs';
import { Label, Error, Hint, FloatingLabel } from '@progress/kendo-react-labels';

const emailRegex = new RegExp(/\S+@\S+\.\S+/);
const emailValidator = (value) => (emailRegex.test(value) ? "" : "Please enter a valid email.");
const LabelEmailInput = (fieldRenderProps) => {
    const { validationMessage, visited, label, id, valid, ...others } = fieldRenderProps;
    const showValidationMessage = visited && validationMessage;
    return (
        <FieldWrapper>
            <Label editorId={id} editorValid={valid}>{label}</Label>
            <div className={'k-form-field-wrap'}>
                <Input valid={valid} type={'email'} id={id} {...others} />
                {
                    !showValidationMessage &&
                        <Hint>Enter your personal email address.</Hint>
                }
                {
                    showValidationMessage &&
                        <Error>{validationMessage}</Error>
                }
            </div>
        </FieldWrapper>
    );
};
const FloatingLabelEmailInput = (fieldRenderProps) => {
    const { validationMessage, visited, label, id, valid, value, ...others } = fieldRenderProps;
    const showValidationMessage = visited && validationMessage;
    return (
        <FieldWrapper>
            <div className={'k-form-field-wrap'}>
                <FloatingLabel label={label} editorValue={value} editorValid={valid} editorId={id}>
                    <Input value={value} valid={valid} type={'email'} id={id} {...others} />
                </FloatingLabel>
                {
                    !showValidationMessage &&
                        <Hint>Enter your personal email address.</Hint>
                }
                {
                    showValidationMessage &&
                        <Error>{validationMessage}</Error>
                }
            </div>
        </FieldWrapper>
    );
};
const App = () => {
    const handleSubmit = (dataItem) => alert(JSON.stringify(dataItem, null, 2));
    return (
        <Form
            onSubmit={handleSubmit}
            render={(formRenderProps) => (
                <FormElement horizontal={true} style={{maxWidth: 650}}>
                    <Field
                        id={'email'}
                        name={'email'}
                        label={'Email (Regular Label)'}
                        component={LabelEmailInput}
                        validator={emailValidator}
                    />
                    <Field
                        id={'secondEmail'}
                        name={'secondemail'}
                        label={'Email (Floating Label)'}
                        component={FloatingLabelEmailInput}
                        validator={emailValidator}
                    />
                    <div className="k-form-buttons">
                        <button
                            type={'submit'}
                            className="k-button"
                            disabled={!formRenderProps.allowSubmit}
                        >
                            Submit
                        </button>
                    </div>
                </FormElement>
            )}
        />
    );
};
ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);