Custom form elements

Often there are cases that software need custom/not standard form components like typeahead or custom date picker etc. To create custom form component you need to implement CustomFormElement interface which has two properties:

  • onElementValueChange - Observable that should sent ElementValueChangeEvent when component value changes

  • onStateValueChange - Observable that is notified when state value is changed

So custom element might look like this:

export class ComplexFormElementComponent extends React.Component<CustomFormElementProps, any> implements CustomFormElement {

    private inputElement = React.createRef<HTMLInputElement>()
    private takeUntil = new Subject<any>();

    onElementValueChange = new Subject<ElementValueChangeEvent>();
    onStateValueChange = new Subject<any>();

    complexElement: string;

    constructor(props: any) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.listenToStateChange();
    }

    componentWillUnmount() {
        this.takeUntil.next();
        this.takeUntil.unsubscribe();
    }

    listenToStateChange() {
        this.onStateValueChange
            .pipe(takeUntil(this.takeUntil))
            .subscribe(state => {
                this.inputElement.current.value = state;
            });
    }

    handleChange(event: React.ChangeEvent<HTMLInputElement>) {
        this.onElementValueChange.next({
            target: this,
            value: event.target.value
        });

        event.stopPropagation();
    }

    render() {
        return (
            <div>
                <input type="text" form-ignore="true" ref={this.inputElement} onChange={this.handleChange} />
            </div>
        );
    }
}

Make sure to add form-ignore attribute on elements to skip them from standard form binding.

Last updated