ng-form-helper
Version:
Feature set to use in your angular form
392 lines (384 loc) • 12.4 kB
JavaScript
import { HostListener, Directive, ElementRef, forwardRef, Input, Renderer2, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
/**
* @fileoverview added by tsickle
* Generated from: lib/form-field.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @abstract
*/
class FormFieldDirective {
constructor() {
this.oldState = {
cursorStart: 0,
cursorEnd: 0,
value: ''
};
// These are for angular use
this.isDisabled = false;
this.onChange = (/**
* @param {...?} arg
* @return {?}
*/
(...arg) => void (0));
this.onTouch = (/**
* @return {?}
*/
() => void (0));
}
/**
* @return {?}
*/
ngOnInit() {
this.oldState.value = this.element.nativeElement.value;
}
/**
* @return {?}
*/
onKeyDown() {
this.oldState.cursorStart = this.element.nativeElement.selectionStart;
this.oldState.cursorEnd = this.element.nativeElement.selectionEnd;
}
/**
* @return {?}
*/
onBlur() {
this.onTouch();
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
/** @type {?} */
const normalizedValue = value == null ? '' : value;
this.oldState.value = normalizedValue;
this.onChange(value);
this.renderer.setProperty(this.element.nativeElement, 'value', normalizedValue);
}
/**
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.renderer.setProperty(this.element.nativeElement, 'disabled', isDisabled);
this.isDisabled = isDisabled;
}
/**
* @protected
* @param {?} event
* @return {?}
*/
getValueFromKeyboardEvent(event) {
/** @type {?} */
const el = event.target && (/** @type {?} */ (event.target)) || null;
return el && el.value || '';
}
/**
* @protected
* @param {?} start
* @param {?=} end
* @return {?}
*/
setCursorPosition(start, end = start) {
/** @type {?} */
const el = this.element.nativeElement;
/** @type {?} */
const type = el.getAttribute('type');
el.setAttribute('type', 'text');
el.selectionStart = start;
el.selectionEnd = end;
el.setAttribute('type', type);
}
/**
* @return {?}
*/
resetField() {
this.onChange(this.oldState.value);
this.writeValue(this.oldState.value);
this.setCursorPosition(this.oldState.cursorStart, this.oldState.cursorEnd);
}
/**
* @param {?} value
* @return {?}
*/
updateFieldValue(value) {
this.writeValue(value);
this.oldState.value = value;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouch = fn;
}
}
FormFieldDirective.propDecorators = {
onKeyDown: [{ type: HostListener, args: ['keydown',] }],
onBlur: [{ type: HostListener, args: ['blur',] }]
};
/**
* @fileoverview added by tsickle
* Generated from: lib/field-mask.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class FieldMaskDirective extends FormFieldDirective {
/**
* @param {?} element
* @param {?} renderer
*/
constructor(element, renderer) {
super();
this.element = element;
this.renderer = renderer;
/**
* The mask can't contain numbers
*/
this.MASK_SHOULD_NOT_HAVE_NUMBERS = /[0-8]/gi;
this.MASK_MUST_FINISH_WITH_A_NUMBER = /\d$/;
this.generatedMaskConfig = {};
}
/**
* @param {?} formFieldMask
* @return {?}
*/
set setFormFieldMask(formFieldMask) {
this.generatedMaskConfig = this.generateMaskConfig(formFieldMask);
}
/**
* @private
* @param {?} formFieldMask
* @return {?}
*/
generateMaskConfig(formFieldMask) {
if (this.MASK_SHOULD_NOT_HAVE_NUMBERS.test(formFieldMask)) {
throw new Error(`Can't generate mask: "${formFieldMask}". Invalid charactere found.
You should not use numeric character to compose the field mask.`);
}
if (!this.MASK_MUST_FINISH_WITH_A_NUMBER.test(formFieldMask)) {
throw new Error(`Can't generate mask: "${formFieldMask}". Invalid format found.
The mask must finish with a numeric character (9).`);
}
/** @type {?} */
const generatedMaskConfig = {};
/** @type {?} */
const decomposeGivenMask = formFieldMask.match(/(9+|[^9]+)/g);
if (!decomposeGivenMask) {
throw new Error(`Can't generate mask: "${formFieldMask}". Invalid format found.
You must have at least one 9 character in the mask.`);
}
/** @type {?} */
const isNumeric = /^\d+$/;
/** @type {?} */
let composeMask = '';
/** @type {?} */
let numberMapper = '';
/** @type {?} */
let numberGroup = 1;
/** @type {?} */
let numericLength = 0;
decomposeGivenMask.forEach((/**
* @param {?} textGroup
* @return {?}
*/
textGroup => {
if (isNumeric.test(textGroup)) {
numericLength += textGroup.length;
composeMask += `\$${numberGroup++}`;
/** @type {?} */
const currentNumberMapper = `${numberMapper}([0-9]{1,${textGroup.length}})`;
numberMapper += `([0-9]{${textGroup.length}})`;
generatedMaskConfig[String(numericLength)] = {
valueStructure: new RegExp(currentNumberMapper, 'g'),
maskStructure: composeMask
};
return;
}
composeMask += textGroup;
}));
return generatedMaskConfig;
}
/**
* @private
* @param {?} currentValue
* @return {?}
*/
getPartialMask(currentValue) {
/** @type {?} */
const lengths = Object.keys(this.generatedMaskConfig);
/** @type {?} */
let length = lengths.find((/**
* @param {?} maxLength
* @return {?}
*/
maxLength => currentValue.length <= Number(maxLength)));
length = length || lengths.pop() || '';
/** @type {?} */
const maskConfig = this.generatedMaskConfig[length];
return {
valueStructure: maskConfig.valueStructure,
maskStructure: maskConfig.maskStructure,
maxLength: Number(length)
};
}
/**
* @param {?} event
* @return {?}
*/
onInput(event) {
/** @type {?} */
const currentMaskedValue = this.getValueFromKeyboardEvent(event);
// this validation is here for IE11 or lower... it emmits the input event for anything
// and create a loop
if (currentMaskedValue === this.oldState.value) {
return;
}
/** @type {?} */
const currentValue = currentMaskedValue.replace(/[^0-9]/g, '');
/** @type {?} */
const maskConfig = this.getPartialMask(currentValue);
if (currentValue.length > maskConfig.maxLength) {
this.resetField();
return;
}
/** @type {?} */
const maskedValue = currentValue.replace(maskConfig.valueStructure, maskConfig.maskStructure);
this.updateFieldValue(maskedValue);
}
}
FieldMaskDirective.decorators = [
{ type: Directive, args: [{
selector: '[formFieldMask]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => FieldMaskDirective)),
multi: true
}
]
},] }
];
/** @nocollapse */
FieldMaskDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 }
];
FieldMaskDirective.propDecorators = {
setFormFieldMask: [{ type: Input, args: ['formFieldMask',] }],
onInput: [{ type: HostListener, args: ['input', ['$event'],] }]
};
/**
* @fileoverview added by tsickle
* Generated from: lib/regexed-field.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class RegexedFieldDirective extends FormFieldDirective {
/**
* @param {?} element
* @param {?} renderer
*/
constructor(element, renderer) {
super();
this.element = element;
this.renderer = renderer;
this.regexRule = /(?:)/;
}
/**
* @param {?} regex
* @return {?}
*/
set setRegex(regex) {
this.regexRule = new RegExp(regex);
}
/**
* @param {?} event
* @return {?}
*/
onInput(event) {
/** @type {?} */
const value = this.getValueFromKeyboardEvent(event);
// this validation is here for IE11 or lower... it emmits the input event for anything
// and create a loop
if (value === this.oldState.value) {
return;
}
if (this.regexRule.test(value)) {
/** @type {?} */
const cursorInitialPosition = this.element.nativeElement.selectionStart;
this.updateFieldValue(value);
this.setCursorPosition(cursorInitialPosition);
return;
}
this.resetField();
}
}
RegexedFieldDirective.decorators = [
{ type: Directive, args: [{
selector: '[formRegexedField]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => RegexedFieldDirective)),
multi: true
}
]
},] }
];
/** @nocollapse */
RegexedFieldDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 }
];
RegexedFieldDirective.propDecorators = {
setRegex: [{ type: Input, args: ['formRegexedField',] }],
onInput: [{ type: HostListener, args: ['input', ['$event'],] }]
};
/**
* @fileoverview added by tsickle
* Generated from: lib/form-helper.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class FormHelperModule {
}
FormHelperModule.decorators = [
{ type: NgModule, args: [{
imports: [
FormsModule
],
declarations: [
FieldMaskDirective,
RegexedFieldDirective
],
exports: [
FieldMaskDirective,
RegexedFieldDirective
]
},] }
];
/**
* @fileoverview added by tsickle
* Generated from: public-api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: ng-form-helper.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { FieldMaskDirective, FormHelperModule, RegexedFieldDirective, FormFieldDirective as ɵa };
//# sourceMappingURL=ng-form-helper.js.map