Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
ui-component-library / dist / forms / form / ObserverForm.js
Size: Mime:
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var ObserverForm_1;
/* eslint-disable brace-style */
// modules
const react_1 = __importDefault(require("react"));
const exotic_1 = require("exotic");
const mobx_react_1 = require("xmobx/mobx-react");
const ObserverInput_1 = __importDefault(require("src/forms/input/ObserverInput"));
const deps_1 = require("../deps");
const FormState_1 = __importDefault(require("./FormState"));
const _elements_1 = require("./_elements");
const _fixture_1 = require("./_fixture");
const deps_2 = require("./deps");
/**
 * @todo https://www.w3.org/TR/wai-aria/states_and_properties#aria-errormessage
 *
 *
 * @note need to add refs like in my example, or pass in states
 * @todo - finish
 * @type {React.Component}
 * @type {Observer}
 * @type {CommonAbstractInterface}
 */
const handleCancel = event => {
    // event.persist()
    // log(event)
    event.preventDefault();
    log(this);
};
let ObserverForm = ObserverForm_1 = class ObserverForm extends react_1.default.Component {
    /**
     * @param {React.Props} props
     * @description @modifies this.state
     */
    constructor(props) {
        super(props);
        // @todo renderProps
        // @note - extend to easily change
        this.Form = _elements_1.FormElement;
        this.Input = ObserverInput_1.default;
        this.SubmitButton = _elements_1.SubmitButton;
        this.CancelButton = _elements_1.CancelButton;
        this.shouldResetFormOnUnmount = false;
        /**
         * should have a simple object with wording & classnames, one property
         * @todo could also pass these in via defaultProps
         */
        this.defaultSubmitButtonLabel = _fixture_1.wording.submit;
        this.defaultCancelButtonLabel = _fixture_1.wording.cancel;
        /**
         * state...
         */
        this.isSubmitButtonNeeded = true;
        this.isCancelButtonNeeded = false;
        this.handleCancel = handleCancel;
        /**
         * onInvalid
         * onInput
         *
         * @todo - should put all validationType: toArray()
         */
        // @todo - on FormState
        // @action
        // eslint-disable-next-line
        this.validateInputItem = item => {
            console.log('validateInputItem', item);
            const { isHidden, validationType, value, errorMessageFor, type } = item;
            // @todo - dedupe the other place & split out
            if (!exotic_1.isSafe(isHidden) && exotic_1.isSafe(validationType)) {
                if (validationType === 'month' || validationType === 'year') {
                    if (this.state.validateExpiryDate(item) === false) {
                        this.state.hasAllValidInputs = false;
                        item.errorMessage = deps_1.errorMessage(errorMessageFor);
                        item.isValidInput = false;
                    }
                }
                else if (validationType === 'creditcard' || validationType === 'securitycode') {
                    if (this.state.validateCreditCard(item) === false) {
                        this.state.hasAllValidInputs = false;
                        item.errorMessage = deps_1.errorMessage(errorMessageFor);
                        item.isValidInput = false;
                    }
                }
                else if (validationType === 'confirmPassword') {
                    if (this.state.validateConfirmPassword(item) === false) {
                        this.state.hasAllValidInputs = false;
                    }
                }
                else if (type === 'groupElements') {
                    item.props.elementList.forEach(this.validateInputItem);
                }
                else {
                    const hasPassedValidation = (item.isEnabled) ? deps_1.isValid(value, validationType) : true;
                    if (hasPassedValidation === false) {
                        /**
                         * @todo @standard validationMessage
                         */
                        item.errorMessage = deps_1.errorMessage(errorMessageFor);
                        item.isValidInput = false;
                        // item.setIsValid(false)
                        this.state.hasAllValidInputs = false;
                        this.goToTop();
                    }
                    else {
                        item.isValidInput = true;
                    }
                }
            }
        };
        /**
         * @action
         * @todo - debounce
         */
        this.validateForm = () => {
            // @todo - should calling this.state.validate(), this.state.isValid()
            // Resetting the form validation state
            this.state.hasAllValidInputs = true;
            this.state.inputsList.forEach(this.validateInputItem);
            return this.state.hasAllValidInputs;
        };
        /**
         * @todo - using super when it's a bound fn may not work?
         * @listens onSubmit
         */
        // eslint-disable-next-line
        this.goToTop = () => {
            let topOffset = 0;
            const element = document.getElementById('topHeader');
            const headerOffset = (element.offsetHeight) / 2;
            const target = this.state.form && (this.state.form.offsetTop);
            if (target === 0) {
                topOffset = headerOffset;
            }
            else {
                topOffset = target - headerOffset;
            }
            document.body.scrollTop = topOffset;
            document.documentElement.scrollTop = topOffset;
        };
        this.handleSubmit = (event) => {
            if (this.validateForm()) {
                const serialized = this.state.toSerialized();
                console.log('[form] valid & serialized: ', serialized);
                this.onSubmitValid(serialized);
                return serialized;
            }
            else {
                console.log('[form] Form has invalid inputs!');
                const serialized = {
                    hasError: true,
                };
                this.onSubmitError(serialized);
                return serialized;
            }
        };
        this.onCancelClick = event => {
            event.preventDefault();
            if (this.props.onHandleCancel) {
                this.props.onHandleCancel(this.props, this.props.cancelState);
            }
            else {
                this.handleCancel(event);
            }
        };
        this.renderInput = (item, index) => {
            const instantiated = this._toInput(item, index);
            // log('renderingInput', {
            //   item,
            //   index,
            //   instantiated,
            //   self: this,
            // })
            /**
             * @todo - should be on the input state.......
             */
            // const handleClick = submitEvent => {
            //   submitEvent.persist()
            //   log(submitEvent)
            // }
            const attributes = {};
            if (this.classList.input) {
                attributes.className = this.classList.input;
            }
            if (instantiated.isEnabled) {
                return (react_1.default.createElement(this.Input, Object.assign({ key: instantiated.name || instantiated.identifier || index, state: instantiated }, attributes, instantiated)));
            }
            else {
                return '';
            }
        };
        /**
         * @private
         * @inheritdoc
         * @description compat
         *              so it returns the inputState
         *              will deprecate when not using .map
         */
        this._onPrefil = inputState => this.onPrefil(inputState) || inputState;
        this._onInputInit = (input, index) => {
            const inputState = this._toInput(input, index);
            this.onInputInit(inputState);
        };
        this._toInput = (input, index) => {
            return deps_2.isInputState(input) ? input : deps_2.toInputStateAt(this.state, index);
        };
        // @caution
        this.classList = this.classList || {};
        this.state = props.state;
        if (!exotic_1.isSafe(this.state) || Object.keys(this.state).length <= 0) {
            console.warn('did not pass state prop - use defaultProps');
            this.state = new FormState_1.default(props);
        }
        if (exotic_1.isFunction(this.state.setProps)) {
            this.state.setProps(props);
        }
        else {
            console.warn('!!! FORM MISSING SETPROPS !!!');
        }
    }
    // classList: ObserverFormClassListType
    /**
     * @param {Array} list
     * @return {Form}
     */
    static from(list) {
        let inputList = list;
        if (exotic_1.isArray(list)) {
            inputList = {
                inputList: list,
            };
        }
        const state = new FormState_1.default(inputList);
        return function FormFrom(props) {
            return react_1.default.createElement(ObserverForm_1, Object.assign({ state: state }, props));
        };
    }
    /**
     * @tutorial https://mobx.js.org/refguide/create-transformer.html
     * @description Lifecycle event hook
     * @listens onSubmit
     * @see handleSubmit
     */
    onSubmitValid(serialized) {
        //
    }
    /**
     * @description Lifecycle event hook
     * @listens onSubmit
     * @see handleSubmit
     */
    onSubmitError(serialized) {
        //
    }
    renderInputList() {
        // console.log('total list', this.state.inputList)
        // log('renderingInputList', {
        //   list: this.state.list,
        //   self: this,
        // })
        //
        // wonder if there is something amis with rehydrating it
        return this.state.inputsList.map(this.renderInput);
    }
    /**
     * @see componentWillMount
     * @listens componentWillMount
     * @event prefil
     */
    onPrefil(inputState) {
        //
    }
    onInputInit(input, index) {
        //
    }
    /**
     * @todo put prefil as action on state
     * @todo do a timeout loader
     *
     * !!!!!! changed from componentWillMount => componentDidMount
     *
     * @name onPrefil
     * @name prefilItem
     * @name prefilInputItem
     * @name prefilInput
     */
    componentDidMount() {
        console.debug('[forms] componentDidMount');
        // don't want to assign to state
        let inputsList = this.state.inputsList;
        // this causes many issues?
        inputsList = inputsList.map(this._toInput);
        // call the action
        this.state.setInputsList(inputsList);
        if (exotic_1.isFunction(this.onPrefil)) {
            inputsList = inputsList.map(this._onPrefil);
            this.state.setInputsList(inputsList);
        }
        if (exotic_1.isFunction(this._onInputInit)) {
            inputsList.forEach(this._onInputInit);
        }
    }
    componentWillReceiveProps(prevProps, nextProps) {
        this.classList = deps_2.toClassList(this);
    }
    componentWillUnmount() {
        console.debug('[forms] componentWillUnmount');
        if (exotic_1.isTrue(this.shouldResetFormOnUnmount)) {
            this.state.inputsList.map(this.resetFormState);
        }
        // remove subscribers, make  backup
        // this.state.__INPUTS_LIST = JSON.stringify(this.inputsList, null, 2)
        // this.state.inputsList = []
    }
    resetFormState(inputState) {
        // To reset textbox
        if (inputState.type !== 'button') {
            inputState.setValue('');
            inputState.isValidInput = true;
        }
        // To reset groupElements
        if (inputState.elementList.length > 0) {
            inputState.elementList.forEach(inputElement => {
                if (inputElement.type !== 'button') {
                    inputElement.setValue('');
                    inputElement.isValidInput = true;
                }
            });
        }
        // To reset the 'show password' state
        if (inputState.name === 'password') {
            inputState.type = 'password';
        }
    }
    render() {
        // log('ObserverForm', this)
        // console.log('testing123')
        // @todo if it is not here, or in another lifecycle method, it won't show when state updates
        // @example promocodes
        // but when it is here, dangerous for updates
        // this.classList = toClassList(this)
        const classList = deps_2.toClassList(this);
        const { isSubmitButtonNeeded, isCancelButtonNeeded, onSubmit, formId, } = this;
        // @todo - this should be computed just once, at mount...
        const listView = this.renderInputList();
        // has to be dom element to render ref to element
        return (react_1.default.createElement(this.Form
        // data-is-valid={this.state.hasAllValidInputs}
        // isValid={this.state.hasAllValidInputs}
        , { "aria-invalid": this.state.hasAllValidInputs === false, setRef: this.state.setFormReference, className: classList.form, handleSubmit: onSubmit, formId: formId },
            listView,
            react_1.default.createElement("div", { className: classList.buttonGroup },
                isSubmitButtonNeeded && (react_1.default.createElement(this.SubmitButton, { type: 'submit', className: classList.submitButton, onClick: this.handleSubmit, onSubmit: this.handleSubmit, "data-qa": this.submitDataQa }, this.defaultSubmitButtonLabel)),
                isCancelButtonNeeded && (react_1.default.createElement(this.CancelButton, { className: classList.cancelButton, onClick: this.onCancelClick, "data-qa": this.cancelDataQa }, this.defaultCancelButtonLabel)))));
    }
};
// @todo should deprecate
ObserverForm.FormState = FormState_1.default;
ObserverForm.Form = _elements_1.FormElement;
ObserverForm = ObserverForm_1 = __decorate([
    mobx_react_1.observer
], ObserverForm);
exports.ObservableForm = ObserverForm;
exports.Form = ObserverForm;
exports.ObserverForm = ObserverForm;
exports.default = ObserverForm;
//# sourceMappingURL=ObserverForm.js.map