Repository URL to install this package:
|
Version:
0.9.5 ▾
|
"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