UNPKG

ng2-simple-forms

Version:

A simple(ish) module for creating accessible, reactive forms.

926 lines 227 kB
import * as tslib_1 from "tslib"; import { Subject } from 'rxjs/Subject'; import { Component, EventEmitter, Input, Output, Directive, ElementRef, Renderer2, ViewChild, NgModule } from '@angular/core'; import { FormArray, FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { toWords } from 'number-to-words'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormElement = /** @class */ (function () { /** * @param {?} data */ function FormElement(data) { var _this = this; this.setArrayValues = function (data) { _this.formArrayValue.next(data); }; this.setConfig = function (property, value) { _this.config[property] = value; return _this; }; this.getConfig = function (property) { return _this.config[property]; }; this.setProperty = function (property, value) { _this[property] = value; return _this; }; this.setAccessibility = function (property, value) { _this.accessibilityConfig[property] = value; return _this; }; this.setStyle = function (property, value) { _this.stylesConfig[property] = value; return _this; }; this.getStyle = function (property) { return _this.stylesConfig[property]; }; this.getAccessibility = function (property) { return _this.accessibilityConfig[property]; }; this.getTestId = function (optionValue) { return optionValue ? _this.inputId + "_" + optionValue + "_" + _this.type : _this.inputId + "_" + _this.type; }; this.inputId = data.inputId; this.type = data.type; this.subType = data.subType; this.label = data.label; this.required = data.required; this.minLength = data.minLength; this.maxLength = data.maxLength; this.regex = data.regex; this.helpText = data.helpText; this.errorText = data.errorText; this.options = data.options; this.optionGroups = data.optionGroups; this.optionObjects = data.optionObjects; this.config = data.config || {}; this.accessibilityConfig = data.accessibilityConfig || {}; this.stylesConfig = data.stylesConfig || {}; this.formArrayControls = data.formArrayControls; this.formArrayValue = data.formArrayValue || new Subject(); this.formArraySingularName = data.formArraySingularName; } return FormElement; }()); var ComponentValue = /** @class */ (function () { /** * @param {?} data */ function ComponentValue(data) { this.inputId = data.inputId; this.value = data.value; this.isValid = data.isValid; } return ComponentValue; }()); var ElementOption = /** @class */ (function () { /** * @param {?} data */ function ElementOption(data) { this.value = data.value; this.display = data.display; } return ElementOption; }()); var ElementOptionGroup = /** @class */ (function () { /** * @param {?} data */ function ElementOptionGroup(data) { this.groupName = data.groupName; this.options = data.options; } return ElementOptionGroup; }()); var ObjectGroup = /** @class */ (function () { /** * @param {?} data */ function ObjectGroup(data) { this.groupName = data.groupName; this.objects = data.objects; } return ObjectGroup; }()); /** * FormDetails object for unwrapped forms * \@TODO - refer to this as a loose form? Does that make more sense? Who knows! 🙈 */ var FormDetails = /** @class */ (function () { /** * @param {?=} data */ function FormDetails(data) { var _this = this; // Get an element by its inputId this.get = function (inputId) { var /** @type {?} */ foundElement; _this.elements.forEach(function (element) { if (element.inputId === inputId) { foundElement = element.element; } }); return foundElement; }; // Set config on a particular element by its inputId this.setConfig = function (inputId, propertyName, value) { var /** @type {?} */ foundElement = _this.get(inputId); foundElement.setConfig(propertyName, value); _this.elements.forEach(function (element) { if (element.inputId === foundElement.inputId) { element.element = foundElement; } }); return _this; }; // Set style on a particular element by its inputId this.setStyle = function (inputId, propertyName, value) { var /** @type {?} */ foundElement = _this.get(inputId); foundElement.setStyle(propertyName, value); _this.elements.forEach(function (element) { if (element.inputId === foundElement.inputId) { element.element = foundElement; } }); return _this; }; // Set style for all elements in the formDetails this.setGlobalStyle = function (propertyName, value) { _this.elements.forEach(function (element) { var /** @type {?} */ elementTmp = element.element; elementTmp.setStyle(propertyName, value); element.element = elementTmp; }); return _this; }; // Set accessibility on a particular element by its inputId this.setAccessibility = function (inputId, propertyName, value) { var /** @type {?} */ foundElement = _this.get(inputId); foundElement.setAccessibility(propertyName, value); _this.elements.forEach(function (element) { if (element.inputId === foundElement.inputId) { element.element = foundElement; } }); return _this; }; this.elements = data ? data.elements : []; this.formGroup = data ? data.formGroup : undefined; } return FormDetails; }()); /** * @record */ var Elements = /** @class */ (function () { function Elements() { } return Elements; }()); Elements.Text = 'text'; Elements.Select = 'select'; Elements.Checkbox = 'checkbox'; Elements.Radio = 'radio'; Elements.Password = 'password'; Elements.Datepicker = 'date'; Elements.Range = 'range'; Elements.Textarea = 'textarea'; Elements.ObjectSelector = 'object'; Elements.FormArray = 'formArray'; var Properties = /** @class */ (function () { function Properties() { } return Properties; }()); Properties.InputId = 'inputId'; Properties.Required = 'required'; Properties.MinLength = 'minLength'; Properties.MaxLength = 'maxLength'; Properties.Regex = 'regex'; Properties.HelpText = 'helpText'; Properties.ErrorText = 'errorText'; Properties.Options = 'options'; Properties.OptionGroups = 'optionGroups'; /** * @record */ var Config = /** @class */ (function () { function Config() { } return Config; }()); Config.RequiredMarker = 'requiredMarker'; Config.ReadOnly = 'readOnly'; Config.ObjectDisplayProperty = 'objectDisplayProperty'; Config.ObjectGroupProperty = 'objectGroupProperty'; Config.ShouldGroupObjects = 'shouldGroupObjects'; /** * @record */ var Accessibility = /** @class */ (function () { function Accessibility() { } return Accessibility; }()); Accessibility.AriaLabel = 'ariaLabel'; Accessibility.AriaDescribedBy = 'ariaDescribedBy'; Accessibility.AriaLabelledBy = 'ariaLabelledBy'; Accessibility.AriaReadOnly = 'ariaReadOnly'; /** * @record */ var Styles = /** @class */ (function () { function Styles() { } return Styles; }()); Styles.ElementWrapper = 'wrapperCssClass'; Styles.GroupLabel = 'groupLabelCssClass'; Styles.ElementLabel = 'elementLabelCssClass'; Styles.ElementInput = 'elementInputCssClass'; Styles.Fieldset = 'fieldsetCssClass'; Styles.Legend = 'legendCssClass'; Styles.OptionLabel = 'optionLabelCssClass'; /** * @record */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormComponent = /** @class */ (function () { function FormComponent() { this.hideClear = false; this.formOptions = { wrapperCssClass: '', // Allows you to pass a custom CSS class to apply to the form wrapper container formElementCssClass: '', // Allows you to pass a custom CSS class to apply to each form element in the form buttonCssClass: '', // Allows you to pass a customer CSS class to apply to each button in the form submitButtonLabel: 'Submit', // Allows you to modify the submit button text clearButtonLabel: 'Clear' // Allows you to modify the clear button text }; this.changeEmitter = new EventEmitter(); this.submitEmitter = new EventEmitter(); } /** * @return {?} */ FormComponent.prototype.ngOnInit = function () { var _this = this; this.form.formGroup.valueChanges.subscribe(function (data) { _this.changeEmitter.emit(data); }); this.form.elements = this.form.elements.map(function (element) { return { inputId: element.inputId, element: _this.setElementConfig(element.element) }; }); if (this.defaultFormData) { this.form.formGroup.setValue(this.defaultFormData); } }; /** * @param {?} element * @return {?} */ FormComponent.prototype.setElementConfig = function (element) { element.setConfig('wrapperCssClass', this.formOptions.formElementCssClass); element.setConfig('formElementCssClass', this.formOptions.formElementCssClass); return element; }; /** * @return {?} */ FormComponent.prototype.submit = function () { if (this.form.formGroup.valid) { this.submitEmitter.emit(this.form.formGroup.getRawValue()); return; } }; /** * @return {?} */ FormComponent.prototype.clear = function () { this.form.formGroup.reset(); }; /** * @return {?} */ FormComponent.prototype.isValid = function () { return this.form.formGroup.valid; }; return FormComponent; }()); FormComponent.decorators = [ { type: Component, args: [{ selector: 'app-form', template: "<app-form-wrapper [wrapperCssClass]=\"formOptions.wrapperCssClass\">\n <h1>{{ formTitle }}</h1>\n <h2>{{ formSubtitle }}</h2>\n <app-form-element\n *ngFor=\"let element of form.elements\"\n [formGroup]=\"form.formGroup\"\n [formElement]=\"element.element\">\n </app-form-element>\n <span class=\"controls\">\n <button\n class=\"{{ formOptions.buttonCssClass || 'btn btn-primary' }}\"\n [ngClass]=\"{ 'disabled' : !isValid() }\"\n (click)=\"submit()\">\n {{ formOptions.submitButtonLabel || 'Submit' }}\n </button>\n <button *ngIf=\"!hideClear\" class=\"{{ formOptions.buttonCssClass || 'btn btn-primary' }}\" (click)=\"clear()\">{{ formOptions.clearButtonLabel || 'Clear' }}</button>\n </span>\n</app-form-wrapper>\n", styles: ["h2{\n font-size:12px;\n color:#5b6b8c;\n margin-top:-20px; }\n.controls{\n margin-top:15px;\n display:block; }\n.disabled{\n background-color:lightgray;\n color:black;\n cursor:not-allowed; }\n"] },] }, ]; /** @nocollapse */ FormComponent.ctorParameters = function () { return []; }; FormComponent.propDecorators = { "formTitle": [{ type: Input },], "formSubtitle": [{ type: Input },], "form": [{ type: Input },], "hideClear": [{ type: Input },], "formOptions": [{ type: Input },], "defaultFormData": [{ type: Input },], "formData": [{ type: Output },], "changeEmitter": [{ type: Output },], "submitEmitter": [{ type: Output },], }; /** * @record */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var ErrorMessageComponent = /** @class */ (function () { function ErrorMessageComponent() { } /** * @return {?} */ ErrorMessageComponent.prototype.ngOnInit = function () { }; return ErrorMessageComponent; }()); ErrorMessageComponent.decorators = [ { type: Component, args: [{ selector: 'app-error-message', template: "<span role=\"alert\" [attr.aria-expanded]=\"true\" class=\"error-text\">{{ message }}</span>\n", styles: [".error-text{\n display:block;\n position:absolute;\n background-color:#e3272e;\n font-size:12px;\n color:white;\n padding:5px 10px;\n text-align:center;\n border-radius:5px;\n z-index:2;\n bottom:-32px;\n left:25%;\n min-width:50%;\n min-height:40px; }\n .error-text::after{\n content:\" \";\n position:absolute;\n bottom:100%;\n left:50%;\n margin-left:-5px;\n border-width:5px;\n border-style:solid;\n border-color:transparent transparent #e3272e transparent; }\n"] },] }, ]; /** @nocollapse */ ErrorMessageComponent.ctorParameters = function () { return []; }; ErrorMessageComponent.propDecorators = { "message": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormElementComponent = /** @class */ (function () { function FormElementComponent() { } /** * @return {?} */ FormElementComponent.prototype.ngOnInit = function () { }; return FormElementComponent; }()); FormElementComponent.decorators = [ { type: Component, args: [{ selector: 'app-form-element', template: "<div *ngIf=\"formElement\" [ngSwitch]=\"formElement.type.toLowerCase()\">\n <!-- TEXT INPUT FIELD -->\n <app-text-input\n *ngSwitchCase=\"'text'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\"\n ></app-text-input>\n <!-- TEXT AREA FIELD -->\n <app-text-area\n *ngSwitchCase=\"'textarea'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\"\n ></app-text-area>\n <!-- DATE PICKER FIELD -->\n <app-date-picker\n *ngSwitchCase=\"'date'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-date-picker>\n <!-- PASSWORD INPUT FIELD -->\n <app-password-input\n *ngSwitchCase=\"'password'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-password-input>\n <!-- SELECT INPUT FIELD -->\n <app-dropdown-question\n *ngSwitchCase=\"'select'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-dropdown-question>\n <!-- CHECKBOX GROUP FIELD -->\n <app-checkbox\n *ngSwitchCase=\"'checkbox'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-checkbox>\n <!-- RADIO GROUP FIELD -->\n <app-radio-question\n *ngSwitchCase=\"'radio'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-radio-question>\n <!-- RANGE FIELD -->\n <app-range\n *ngSwitchCase=\"'range'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-range>\n <!-- OBJECT SELECTOR -->\n <app-object-selector\n *ngSwitchCase=\"'object'\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-object-selector>\n <!-- FORM ARRAY -->\n <app-form-array-element\n *ngSwitchCase=\"'formarray'\"\n [formValue]=\"formElement.formArrayValue\"\n [formGroup]=\"formGroup\"\n [elementData]=\"formElement\">\n </app-form-array-element>\n</div>\n", styles: [""] },] }, ]; /** @nocollapse */ FormElementComponent.ctorParameters = function () { return []; }; FormElementComponent.propDecorators = { "formGroup": [{ type: Input },], "formElement": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormWrapperComponent = /** @class */ (function () { function FormWrapperComponent() { } /** * @return {?} */ FormWrapperComponent.prototype.ngOnInit = function () { }; return FormWrapperComponent; }()); FormWrapperComponent.decorators = [ { type: Component, args: [{ selector: 'app-form-wrapper', template: "<div class=\"{{wrapperCssClass || 'default-theme'}}\">\n <ng-content></ng-content>\n</div>\n", styles: [".form-wrapper{\n background-color:white;\n padding:30px;\n border-radius:8px;\n margin-bottom:30px; }\n"] },] }, ]; /** @nocollapse */ FormWrapperComponent.ctorParameters = function () { return []; }; FormWrapperComponent.propDecorators = { "wrapperCssClass": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var SimpleFormBuilder = /** @class */ (function () { function SimpleFormBuilder() { } /** * Get Validators from FormElement definition properties * @param {?} element * @return {?} */ SimpleFormBuilder.getValidators = function (element) { var /** @type {?} */ validators = []; if (element.required) { validators.push(Validators.required); } if (element.minLength) { var /** @type {?} */ minLength = typeof element.minLength === 'number' ? element.minLength : parseInt(element.minLength, 10); validators.push(Validators.minLength(minLength)); } if (element.maxLength) { var /** @type {?} */ maxLength = typeof element.maxLength === 'number' ? element.maxLength : parseInt(element.maxLength, 10); validators.push(Validators.maxLength(maxLength)); } if (element.regex) { validators.push(Validators.pattern(element.regex)); } return validators; }; /** * Create a FormGroup from a list FormElement definitions * @param {?} formElements * @return {?} */ SimpleFormBuilder.toFormGroup = function (formElements) { var /** @type {?} */ formGroup = {}; formElements.forEach(function (element) { if (element.type === Elements.FormArray) { var /** @type {?} */ arrayControls = element.formArrayControls; var /** @type {?} */ arrayGroup_1 = {}; arrayControls.forEach(function (arrayElement) { arrayGroup_1[arrayElement.inputId] = ['', SimpleFormBuilder.getValidators(arrayElement)]; }); formGroup[element.inputId] = new FormArray([SimpleFormBuilder.formBuilder.group(arrayGroup_1)]); } else { formGroup[element.inputId] = ['', SimpleFormBuilder.getValidators(element)]; } }); return SimpleFormBuilder.formBuilder.group(formGroup); }; /** * Create a 'FormDetails' * Takes a group of FormElements, and returns an * Unwrapped form object of formGroup, and * { inputId: string, element: FormElement } array. * @param {?} formElements * @return {?} */ SimpleFormBuilder.toFormDetails = function (formElements) { var /** @type {?} */ unwrappedForm = new FormDetails(); unwrappedForm.elements = formElements.map(function (item) { return ({ inputId: item.inputId, element: item }); }); unwrappedForm.formGroup = SimpleFormBuilder.toFormGroup(formElements); return unwrappedForm; }; /** * Create a form from JSON * @param {?} jsonValue * @return {?} */ SimpleFormBuilder.fromJson = function (jsonValue) { var /** @type {?} */ elements = jsonValue.map(function (value) { return new FormElement(value); }); return SimpleFormBuilder.toFormDetails(elements); }; /** * Simple wrapper to create a FormElement with basic * attributes * @param {?} type * @param {?} label * @param {?=} options * @param {?=} config * @return {?} */ SimpleFormBuilder.createElement = function (type, label, options, config) { if (options === void 0) { options = {}; } var /** @type {?} */ elementInputId; if (options && !options.inputId) { elementInputId = SimpleFormBuilder.toInputId(label); } else { elementInputId = options.inputId; } var /** @type {?} */ element = new FormElement({ inputId: elementInputId, type: type, label: label, config: config }); return SimpleFormBuilder.setOptions(element, options); }; /** * @param {?} element * @param {?} options * @return {?} */ SimpleFormBuilder.setOptions = function (element, options) { Object.getOwnPropertyNames(options).forEach(function (optionKey) { element.setProperty(optionKey, options[optionKey]); }); return element; }; /** * @param {?} str * @return {?} */ SimpleFormBuilder.toInputId = function (str) { var /** @type {?} */ words = str.split(' '); var /** @type {?} */ mutated = words.map(function (word, index) { // If it is the first word make sure to lowercase all the chars. if (index === 0) { return word.toLowerCase(); } // If it is not the first word only upper case the first char and lowercase the rest. return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }); return mutated.join(''); }; return SimpleFormBuilder; }()); SimpleFormBuilder.formBuilder = new FormBuilder(); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var ElementBaseComponent = /** @class */ (function () { function ElementBaseComponent() { this.changeEmitter = new EventEmitter(); this.isFocussed = false; } /** * @return {?} */ ElementBaseComponent.prototype.ngOnInit = function () { }; /** * @return {?} */ ElementBaseComponent.prototype.initElement = function () { this.getFormGroup(); this.setElementStyles(); }; /** * @return {?} */ ElementBaseComponent.prototype.getId = function () { var /** @type {?} */ id = this.elementData.getConfig('arrayIndex') ? this.elementData.inputId + "_" + this.elementData.getConfig('arrayIndex') : "" + this.elementData.inputId; return this.elementData.inputId; }; /** * @return {?} */ ElementBaseComponent.prototype.setElementStyles = function () { this.elementWrapperClass = this.elementData.getStyle(Styles.ElementWrapper); this.elementGroupLabelClass = this.elementData.getStyle(Styles.GroupLabel); this.elementLabelClass = this.elementData.getStyle(Styles.ElementLabel); this.elementInputClass = this.elementData.getStyle(Styles.ElementInput); this.elementFieldsetClass = this.elementData.getStyle(Styles.Fieldset); this.elementLegendClass = this.elementData.getStyle(Styles.Legend); this.elementOptionLabelClass = this.elementData.getStyle(Styles.OptionLabel); }; /** * Emit a ComponentValue when this element value changes * (Used when an element is rendered as single element without a FormGroup) * @return {?} */ ElementBaseComponent.prototype.emit = function () { var _this = this; this.formGroup.valueChanges.subscribe(function (value) { _this.changeEmitter.emit(new ComponentValue({ inputId: _this.elementData.inputId, value: value[_this.elementData.inputId], isValid: _this.formGroup.valid })); }); }; /** * Get the relevent data about this element * (Used for accessibility directive) * @param {?=} option * @return {?} */ ElementBaseComponent.prototype.getElementData = function (option) { return { elementData: this.elementData, formGroup: this.formGroup, option: option }; }; /** * Get this elements LabelConfig as an object to pass to LabelComponent * @return {?} */ ElementBaseComponent.prototype.getLabelConfig = function () { return /** @type {?} */ ({ isFocussed: this.isFocussed, elementData: this.elementData, inputHasValue: this.hasValue(), requiredMarker: this.getRequiredMarker(), inputIsInvalid: this.invalid(), inputIsValid: this.valid(), testId: this.elementData.getTestId() }); }; /** * Get the default FormGroup for this element * (If part of a form, use forms Formgroup, else, create a FormGroup for JUST this element) * @return {?} */ ElementBaseComponent.prototype.getFormGroup = function () { this.formGroup = this.formGroup ? this.formGroup : this.toOwnFormgroup(); this.elementData.setProperty('formGroup', this.formGroup); this.emit(); }; /** * Create a single element FormGroup from this element * @return {?} */ ElementBaseComponent.prototype.toOwnFormgroup = function () { return SimpleFormBuilder.toFormGroup([this.elementData]); }; /** * Has the current element got focus? * (Used to apply 'has-focus' class to surrounding DOM elements (label, etc) * @return {?} */ ElementBaseComponent.prototype.hasFocus = function () { return this.isFocussed; }; /** * Check if element has config options * @return {?} */ ElementBaseComponent.prototype.hasConfig = function () { return !!(this.elementData && this.elementData.config); }; /** * Get a custom marker for required fields. If none supplied * in config, return * * @return {?} */ ElementBaseComponent.prototype.getRequiredMarker = function () { if (this.hasConfig()) { return this.elementData.config.requiredMarker || '*'; } }; /** * Toggle focus of element input, and activate validation listener * @param {?} hasFocus * @return {?} */ ElementBaseComponent.prototype.toggleFocus = function (hasFocus) { this.isFocussed = hasFocus; this.activateValidationListener(); }; /** * Subscribe to the elements value changes to activate validation * on change, rather than on lose focus * @return {?} */ ElementBaseComponent.prototype.activateValidationListener = function () { var _this = this; this.getElement().valueChanges.subscribe(function (value) { if (value && !_this.touched()) { _this.formGroup.get(_this.elementData.inputId).markAsTouched(); } }); }; /** * Simple accessor for getting the FormControl by inputId * @return {?} */ ElementBaseComponent.prototype.getElement = function () { return /** @type {?} */ (this.formGroup.get(this.elementData.inputId)); }; /** * Convert string to camelCase inputId * \@TODO - Remove from here and move to utils * @param {?} str * @return {?} */ ElementBaseComponent.prototype.toInputId = function (str) { var /** @type {?} */ words = str.split(' '); var /** @type {?} */ mutated = words.map(function (word, index) { // If it is the first word make sure to lowercase all the chars. if (index === 0) { return word.toLowerCase(); } // If it is not the first word only upper case the first char and lowercase the rest. return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }); return mutated.join(''); }; /** * @return {?} */ ElementBaseComponent.prototype.valid = function () { return this.formGroup.controls[this.elementData.inputId].touched && this.formGroup.controls[this.elementData.inputId].valid; }; /** * @return {?} */ ElementBaseComponent.prototype.invalid = function () { return this.formGroup.controls[this.elementData.inputId].touched && this.formGroup.controls[this.elementData.inputId].invalid; }; /** * @return {?} */ ElementBaseComponent.prototype.touched = function () { return this.formGroup.controls[this.elementData.inputId].touched; }; /** * @return {?} */ ElementBaseComponent.prototype.hasValue = function () { if (this.formGroup && this.elementData) { return !!this.formGroup.get(this.elementData.inputId).value; } return false; }; return ElementBaseComponent; }()); ElementBaseComponent.decorators = [ { type: Component, args: [{ selector: 'app-element-base', template: "", styles: [""] },] }, ]; /** @nocollapse */ ElementBaseComponent.ctorParameters = function () { return []; }; ElementBaseComponent.propDecorators = { "formGroup": [{ type: Input },], "elementData": [{ type: Input },], "changeEmitter": [{ type: Output },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var CheckboxComponent = /** @class */ (function (_super) { tslib_1.__extends(CheckboxComponent, _super); function CheckboxComponent() { return _super.call(this) || this; } /** * @return {?} */ CheckboxComponent.prototype.ngOnInit = function () { this.getFormGroup(); this.setElementStyles(); }; /** * @param {?} value * @return {?} */ CheckboxComponent.prototype.updateParentFormGroup = function (value) { this.formGroup.controls[this.elementData.inputId].setValue(value); this.formGroup.controls[this.elementData.inputId].markAsTouched(); if (!this.isValid()) { this.formGroup.get(this.elementData.inputId).setErrors({ invalid: 'Incorrect number of options selected' }); } }; /** * @return {?} */ CheckboxComponent.prototype.isValid = function () { var /** @type {?} */ minChoices = this.elementData.minLength || 0; var /** @type {?} */ maxChoices = this.elementData.maxLength || this.getDefaultTotalOptions(); var /** @type {?} */ value = this.formGroup.get(this.elementData.inputId).value; var /** @type {?} */ valueCount = 0; Object.getOwnPropertyNames(value).forEach(function (key) { if (value[key]) { valueCount++; } }); var /** @type {?} */ isValid = (valueCount >= minChoices && valueCount <= maxChoices) && this.formGroup.controls[this.elementData.inputId].touched; return isValid; }; /** * @return {?} */ CheckboxComponent.prototype.showCheckboxError = function () { return !!this.elementData.errorText && !this.isValid() && this.isTouched(); }; /** * @return {?} */ CheckboxComponent.prototype.isTouched = function () { return this.formGroup.get(this.elementData.inputId).touched; }; /** * @return {?} */ CheckboxComponent.prototype.getDefaultTotalOptions = function () { if (this.elementData.options) { return this.elementData.options.length; } else { var /** @type {?} */ count_1 = 0; this.elementData.optionGroups.forEach(function (optionGroup) { count_1 += optionGroup.options.length; }); return count_1; } }; return CheckboxComponent; }(ElementBaseComponent)); CheckboxComponent.decorators = [ { type: Component, args: [{ selector: 'app-checkbox', template: "<app-grouped-checkbox-question\n *ngIf=\"elementData.optionGroups\"\n [formGroup]=\"formGroup\"\n [elementData]=\"elementData\">\n</app-grouped-checkbox-question>\n<app-ungrouped-checkbox-question\n *ngIf=\"!elementData.optionGroups\"\n [formGroup]=\"formGroup\"\n [elementData]=\"elementData\">\n</app-ungrouped-checkbox-question>\n", styles: [""] },] }, ]; /** @nocollapse */ CheckboxComponent.ctorParameters = function () { return []; }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var DatePickerComponent = /** @class */ (function (_super) { tslib_1.__extends(DatePickerComponent, _super); function DatePickerComponent() { return _super.call(this) || this; } /** * @return {?} */ DatePickerComponent.prototype.ngOnInit = function () { this.initElement(); }; return DatePickerComponent; }(ElementBaseComponent)); DatePickerComponent.decorators = [ { type: Component, args: [{ selector: 'app-date-picker', template: "<div class=\"field form-group {{elementWrapperClass}}\" [formGroup]=\"formGroup\">\n <!-- INPUT LABEL -->\n <app-label\n [labelConfig]=\"getLabelConfig()\">\n </app-label>\n <!-- INPUT FIELD -->\n <input\n [appDefaultAccessibility]=\"getElementData()\"\n [attr.aria-invalid]=\"!valid()\"\n id=\"{{getId()}}\"\n formControlName=\"{{elementData.inputId}}\"\n type=\"date\"\n (focus)=\"toggleFocus(true)\"\n (blur)=\"toggleFocus(false)\"\n class=\"form-control {{elementInputClass}}\"\n [ngClass]='{\n valid: valid(),\n invalid: invalid()\n }'/>\n <!-- VALIDATION MESSAGES -->\n <app-validation-messages [elementData]=\"elementData\" [hasError]=\"invalid()\" [hasFocus]=\"hasFocus()\"></app-validation-messages>\n</div>\n", styles: ["fieldset{\n padding:0;\n margin:0;\n border:0;\n min-width:0; }\nlegend{\n display:block;\n width:100%;\n padding:0;\n margin-bottom:20px;\n font-size:21px;\n line-height:inherit;\n color:#333333;\n border:0;\n border-bottom:1px solid #e5e5e5; }\nlabel{\n display:inline-block;\n max-width:100%;\n margin-bottom:5px;\n font-weight:bold; }\ninput[type=\"search\"]{\n -webkit-box-sizing:border-box;\n box-sizing:border-box; }\ninput[type=\"radio\"],\ninput[type=\"checkbox\"]{\n margin:4px 0 0;\n margin-top:1px \\9;\n line-height:normal; }\ninput[type=\"file\"]{\n display:block; }\ninput[type=\"range\"]{\n display:block;\n width:100%; }\nselect[multiple],\nselect[size]{\n height:auto; }\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus{\n outline:5px auto -webkit-focus-ring-color;\n outline-offset:-2px; }\noutput{\n display:block;\n padding-top:7px;\n font-size:14px;\n line-height:1.42857;\n color:#555555; }\n.form-control{\n display:block;\n width:100%;\n height:34px;\n padding:6px 12px;\n font-size:14px;\n line-height:1.42857;\n color:#555555;\n background-color:#fff;\n background-image:none;\n border:1px solid #ccc;\n border-radius:4px;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n -webkit-transition:border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; }\n .form-control:focus{\n border-color:#66afe9;\n outline:0;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); }\n .form-control::-moz-placeholder{\n color:#999;\n opacity:1; }\n .form-control:-ms-input-placeholder{\n color:#999; }\n .form-control::-webkit-input-placeholder{\n color:#999; }\n .form-control::-ms-expand{\n border:0;\n background-color:transparent; }\n .form-control[disabled], .form-control[readonly],\n fieldset[disabled] .form-control{\n background-color:#eeeeee;\n opacity:1; }\n .form-control[disabled],\n fieldset[disabled] .form-control{\n cursor:not-allowed; }\ntextarea.form-control{\n height:auto; }\ninput[type=\"search\"]{\n -webkit-appearance:none; }\n@media screen and (-webkit-min-device-pixel-ratio: 0){\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control{\n line-height:34px; }\n input[type=\"date\"].input-sm,\n .input-group-sm input[type=\"date\"],\n input[type=\"time\"].input-sm,\n .input-group-sm\n input[type=\"time\"],\n input[type=\"datetime-local\"].input-sm,\n .input-group-sm\n input[type=\"datetime-local\"],\n input[type=\"month\"].input-sm,\n .input-group-sm\n input[type=\"month\"]{\n line-height:30px; }\n input[type=\"date\"].input-lg,\n .input-group-lg input[type=\"date\"],\n input[type=\"time\"].input-lg,\n .input-group-lg\n input[type=\"time\"],\n input[type=\"datetime-local\"].input-lg,\n .input-group-lg\n input[type=\"datetime-local\"],\n input[type=\"month\"].input-lg,\n .input-group-lg\n input[type=\"month\"]{\n line-height:46px; } }\n.form-group{\n margin-bottom:15px; }\n.radio,\n.checkbox{\n position:relative;\n display:block;\n margin-top:10px;\n margin-bottom:10px; }\n .radio label,\n .checkbox label{\n min-height:20px;\n padding-left:20px;\n margin-bottom:0;\n font-weight:normal;\n cursor:pointer; }\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"]{\n position:absolute;\n margin-left:-20px;\n margin-top:4px \\9; }\n.radio + .radio,\n.checkbox + .checkbox{\n margin-top:-5px; }\n.radio-inline,\n.checkbox-inline{\n position:relative;\n display:inline-block;\n padding-left:20px;\n margin-bottom:0;\n vertical-align:middle;\n font-weight:normal;\n cursor:pointer; }\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline{\n margin-top:0;\n margin-left:10px; }\ninput[type=\"radio\"][disabled], input[type=\"radio\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled]\ninput[type=\"checkbox\"]{\n cursor:not-allowed; }\n.radio-inline.disabled,\nfieldset[disabled] .radio-inline,\n.checkbox-inline.disabled,\nfieldset[disabled]\n.checkbox-inline{\n cursor:not-allowed; }\n.radio.disabled label,\nfieldset[disabled] .radio label,\n.checkbox.disabled label,\nfieldset[disabled]\n.checkbox label{\n cursor:not-allowed; }\n.form-control-static{\n padding-top:7px;\n padding-bottom:7px;\n margin-bottom:0;\n min-height:34px; }\n .form-control-static.input-lg, .form-control-static.input-sm{\n padding-left:0;\n padding-right:0; }\n.input-sm{\n height:30px;\n padding:5px 10px;\n font-size:12px;\n line-height:1.5;\n border-radius:3px; }\nselect.input-sm{\n height:30px;\n line-height:30px; }\ntextarea.input-sm,\nselect[multiple].input-sm{\n height:auto; }\n.form-group-sm .form-control{\n height:30px;\n padding:5px 10px;\n font-size:12px;\n line-height:1.5;\n border-radius:3px; }\n.form-group-sm select.form-control{\n height:30px;\n line-height:30px; }\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control{\n height:auto; }\n.form-group-sm .form-control-static{\n height:30px;\n min-height:32px;\n padding:6px 10px;\n font-size:12px;\n line-height:1.5; }\n.input-lg{\n height:46px;\n padding:10px 16px;\n font-size:18px;\n line-height:1.33333;\n border-radius:6px; }\nselect.input-lg{\n height:46px;\n line-height:46px; }\ntextarea.input-lg,\nselect[multiple].input-lg{\n height:auto; }\n.form-group-lg .form-control{\n height:46px;\n padding:10px 16px;\n font-size:18px;\n line-height:1.33333;\n border-radius:6px; }\n.form-group-lg select.form-control{\n height:46px;\n line-height:46px; }\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control{\n height:auto; }\n.form-group-lg .form-control-static{\n height:46px;\n min-height:38px;\n padding:11px 16px;\n font-size:18px;\n line-height:1.33333; }\n.has-feedback{\n position:relative; }\n .has-feedback .form-control{\n padding-right:42.5px; }\n.form-control-feedback{\n position:absolute;\n top:0;\n right:0;\n z-index:2;\n display:block;\n width:34px;\n height:34px;\n line-height:34px;\n text-align:center;\n pointer-events:none; }\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback{\n width:46px;\n height:46px;\n line-height:46px; }\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback{\n width:30px;\n height:30px;\n line-height:30px; }\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label{\n color:#3c763d; }\n.has-success .form-control{\n border-color:#3c763d;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); }\n .has-success .form-control:focus{\n border-color:#2b542c;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; }\n.has-success .input-group-addon{\n color:#3c763d;\n border-color:#3c763d;\n background-color:#dff0d8; }\n.has-success .form-control-feedback{\n color:#3c763d; }\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label{\n color:#8a6d3b; }\n.has-warning .form-control{\n border-color:#8a6d3b;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); }\n .has-warning .form-control:focus{\n border-color:#66512c;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; }\n.has-warning .input-group-addon{\n color:#8a6d3b;\n border-color:#8a6d3b;\n background-color:#fcf8e3; }\n.has-warning .form-control-feedback{\n color:#8a6d3b; }\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label{\n color:#a94442; }\n.has-error .form-control{\n border-color:#a94442;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); }\n .has-error .form-control:focus{\n border-color:#843534;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; }\n.has-error .input-group-addon{\n color:#a94442;\n border-color:#a94442;\n background-color:#f2dede; }\n.has-error .form-control-feedback{\n color:#a94442; }\n.has-feedback label ~ .form-control-feedback{\n top:25px; }\n.has-feedback label.sr-only ~ .form-control-feedback{\n top:0; }\n.help-block{\n display:block;\n margin-top:5px;\n margin-bottom:10px;\n color:#737373; }\n@media (min-width: 768px){\n .form-inline .form-group{\n display:inline-block;\n margin-bottom:0;\n vertical-align:middle; }\n .form-inline .form-control{\n display:inline-block;\n width:auto;\n vertical-align:middle; }\n .form-inline .form-control-static{\n display:inline-block; }\n .form-inline .input-group{\n display:inline-table;\n vertical-align:middle; }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control{\n width:auto; }\n .form-inline .input-group > .form-control{\n width:100%; }\n .form-inline .control-label{\n margin-bottom:0;\n vertical-align:middle; }\n .form-inline .radio,\n .form-inline .checkbox{\n display:inline-block;\n margin-top:0;\n margin-bottom:0;\n vertical-align:middle; }\n .form-inline .radio label,\n .form-inline .checkbox label{\n padding-left:0; }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"]{\n position:relative;\n margin-left:0; }\n .form-inline .has-feedback .form-control-feedback{\n top:0; } }\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline{\n margin-top:0;\n margin-bottom:0;\n padding-top:7px; }\n.form-horizontal .radio,\n.form-horizontal .checkbox{\n min-height:27px; }\n.form-horizontal .form-group{\n margin-left:-15px;\n margin-right:-15px; }\n .form-horizontal .form-group:before, .form-horizontal .form-group:after{\n content:\" \";\n display:table; }\n .form-horizontal .form-group:after{\n clear:both; }\n@media (min-width: 768px){\n .form-horizontal .control-label{\n text-align:right;\n margin-bottom:0;\n padding-top:7px; } }\n.form-horizontal .has-feedback .form-control-feedback{\n right:15px; }\n@media (min-width: 768px){\n .form-horizontal .form-group-lg .control-label{\n padding-top:11px;\n font-size:18px; } }\n@media (min-width: 768px){\n .form-horizontal .form-group-sm .control-label{\n padding-top:6px;\n font-size:12px; } }\nfieldset{\n display:block;\n width:100%;\n padding:6px 12px;\n font-size:14px;\n line-height:1.42857143;\n color:#555555;\n background-color:#fff;\n background-image:none;\n border:1px solid #ccc;\n border-radius:4px;\n -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n -webkit-transition:border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n transition:border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; }\n.field{\n position:relative; }\n.form-group{\n display:block; }\n.form-control.valid{\n border-color:#7bb752; }\n .form-control.valid:focus{\n border-color:#28a745;\n -webkit-box-shadow:0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n box-shadow:0 0 0 0.2rem rgba(40, 167, 69, 0.25); }\n.form-control.invalid{\n border-color:red; }\n .form-control.invalid:focus{\n border-color:#dc3545;\n -webkit-box-shadow:0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n box-shadow:0 0 0 0.2rem rgba(220, 53, 69, 0.25); }\n", ""] },] }, ]; /** @nocollapse */ DatePickerComponent.ctorParameters = function () { return []; }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var DropdownQuestionComponent = /** @class */ (function (_super) { tslib_1.__extends(DropdownQuestionComponent, _super); function DropdownQuestionComponent() { return _super.call(this) || this; } /** * @return {?} */ DropdownQuestionComponent.prototype.ngOnInit = function () { this.initElement(); }; return DropdownQuestionComponent; }(ElementBaseComponent)); DropdownQuestionComponent.decorators = [ { type: Component, args: [{ selector: 'app-dropdown-question', template: "<app-grouped-dropdown-question [formGroup]=\"formGroup\" *ngIf=\"elementData.optionGroups\" [elementData]=\"elementData\"></app-grouped-dropdown-question>\n<app-ungrouped-dropdown-question [formGroup]=\"formGroup\" *ngIf=\"!elementData.optionGroups\" [elementData]=\"elementData\"></app-ungrouped-dropdown-question>\n", styles: ["select{\n width:100%;\n padding:15px;\n margin-bottom:3px; }\n.field{\n position:relative; }\n"] },] }, ]; /** @nocollapse */ DropdownQuestionComponent.ctorParameters = function () { return []; }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var PasswordInputComponent = /** @class */ (function (_super) { tslib_1.__extends(PasswordInputComponent, _super); function PasswordInputComponent() { return _super.call(this) || this; } /** * @return {?} */ PasswordInputComponent.prototype.ngOnInit = function () { this.initElement(); }; return PasswordInputComponent; }(ElementBaseComponent)); PasswordInputComponent.decorators = [ { type: Component, args: [{ selector: 'app-password-input', template: "<div class=\"form-group {{elementWrapperClass}}\" [formGroup]=\"formGroup\">\n <!-- INPUT LABEL -->\n <app-label\n [labelConfig]=\"getLabelConfig()\">\n </app-label>\n <!-- INPUT FIELD -->\n <input\n [appDefaultAccessibility]=\"getElementData()\"\n [attr.aria-invalid]=\"!valid()\"\n id=\"{{getId()}}\"\n formControlName=\"{{elementD