ng2-simple-forms
Version:
A simple(ish) module for creating accessible, reactive forms.
920 lines (918 loc) • 229 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs/Subject'), require('@angular/core'), require('@angular/forms'), require('number-to-words'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define(['exports', 'rxjs/Subject', '@angular/core', '@angular/forms', 'number-to-words', '@angular/common'], factory) :
(factory((global['ng2-simple-forms'] = {}),global.Rx,global.ng.core,global.ng.forms,global.numberToWords,global.ng.common));
}(this, (function (exports,Subject,core,forms,numberToWords,common) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
/**
* @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.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 core.EventEmitter();
this.submitEmitter = new core.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: core.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: core.Input },],
"formSubtitle": [{ type: core.Input },],
"form": [{ type: core.Input },],
"hideClear": [{ type: core.Input },],
"formOptions": [{ type: core.Input },],
"defaultFormData": [{ type: core.Input },],
"formData": [{ type: core.Output },],
"changeEmitter": [{ type: core.Output },],
"submitEmitter": [{ type: core.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: core.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: core.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: core.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: core.Input },],
"formElement": [{ type: core.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: core.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: core.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(forms.Validators.required);
}
if (element.minLength) {
var /** @type {?} */ minLength = typeof element.minLength === 'number' ? element.minLength : parseInt(element.minLength, 10);
validators.push(forms.Validators.minLength(minLength));
}
if (element.maxLength) {
var /** @type {?} */ maxLength = typeof element.maxLength === 'number' ? element.maxLength : parseInt(element.maxLength, 10);
validators.push(forms.Validators.maxLength(maxLength));
}
if (element.regex) {
validators.push(forms.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 forms.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 forms.FormBuilder();
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var ElementBaseComponent = /** @class */ (function () {
function ElementBaseComponent() {
this.changeEmitter = new core.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: core.Component, args: [{
selector: 'app-element-base',
template: "",
styles: [""]
},] },
];
/** @nocollapse */
ElementBaseComponent.ctorParameters = function () { return []; };
ElementBaseComponent.propDecorators = {
"formGroup": [{ type: core.Input },],
"elementData": [{ type: core.Input },],
"changeEmitter": [{ type: core.Output },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var CheckboxComponent = /** @class */ (function (_super) {
__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: core.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) {
__extends(DatePickerComponent, _super);
function DatePickerComponent() {
return _super.call(this) || this;
}
/**
* @return {?}
*/
DatePickerComponent.prototype.ngOnInit = function () {
this.initElement();
};
return DatePickerComponent;
}(ElementBaseComponent));
DatePickerComponent.decorators = [
{ type: core.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) {
__extends(DropdownQuestionComponent, _super);
function DropdownQuestionComponent() {
return _super.call(this) || this;
}
/**
* @return {?}
*/
DropdownQuestionComponent.prototype.ngOnInit = function () {
this.initElement();
};
return DropdownQuestionComponent;
}(ElementBaseComponent));
DropdownQuestionComponent.decorators = [
{ type: core.Component, args: