UNPKG

ngx-surveys

Version:
1 lines 263 kB
{"version":3,"file":"ngx-surveys.mjs","sources":["../../../projects/ngx-surveys/src/lib/ngx-survey.service.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item.directive.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item.ts","../../../projects/ngx-surveys/src/lib/form-item/error-state.matcher.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-string/form-item-string.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-string/form-item-string.component.html","../../../projects/ngx-surveys/src/lib/components/star-rating/star-rating.component.ts","../../../projects/ngx-surveys/src/lib/components/star-rating/star-rating.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-rating/form-item-rating.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-rating/form-item-rating.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-text/form-item-text.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-text/form-item-text.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-date/form-item-date.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-date/form-item-date.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-segments/form-item-segments.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-segments/form-item-segments.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/radio-group/radio-group.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/radio-group/radio-group.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/selection-list/selection-list.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/selection-list/selection-list.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/select/select.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/select/select.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/form-item-radio.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-radio/form-item-radio.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-numeric-rating/form-item-numeric-rating.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-numeric-rating/form-item-numeric-rating.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-select/form-item-select.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-select/form-item-select.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-options-editor/form-item-options-editor.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-options-editor/form-item-options-editor.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-checkbox/form-item-checkbox.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-checkbox/form-item-checkbox.component.html","../../../projects/ngx-surveys/src/lib/pipes/file-size.pipe.ts","../../../projects/ngx-surveys/src/lib/pipes/truncate.pipe.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-image/file-list-item-image.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-image/file-list-item-image.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-video/file-list-item-video.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-video/file-list-item-video.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/form-item-file.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/form-item-file.component.html","../../../projects/ngx-surveys/src/lib/pipes/duration.pipe.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-voice/form-item-voice.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-voice/form-item-voice.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-label/form-item-label.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-label/form-item-label.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item.component.html","../../../projects/ngx-surveys/src/lib/ngx-survey.component.ts","../../../projects/ngx-surveys/src/lib/ngx-survey.component.html","../../../projects/ngx-surveys/src/lib/dialogs/dialog-section-edit/dialog-section-edit.ts","../../../projects/ngx-surveys/src/lib/dialogs/dialog-section-edit/dialog-section-edit.html","../../../projects/ngx-surveys/src/lib/dialogs/dialog-item-edit/dialog-item-edit.ts","../../../projects/ngx-surveys/src/lib/dialogs/dialog-item-edit/dialog-item-edit.html","../../../projects/ngx-surveys/src/lib/dialogs/dialog-item-visibility/dialog-item-visibility.ts","../../../projects/ngx-surveys/src/lib/dialogs/dialog-item-visibility/dialog-item-visibility.html","../../../projects/ngx-surveys/src/lib/form-builder/form-builder.component.ts","../../../projects/ngx-surveys/src/lib/form-builder/form-builder.component.html","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-file/file-list-item-file.component.ts","../../../projects/ngx-surveys/src/lib/form-item/form-item-file/file-list-item-file/file-list-item-file.component.html","../../../projects/ngx-surveys/src/lib/ngx-survey.module.ts","../../../projects/ngx-surveys/src/ngx-surveys.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { FormItemError, SurveyFile } from './form-item';\nimport * as _ from 'lodash';\nimport { ReplaySubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NgxSurveyService {\n\n constructor() {\n\n }\n\n public onFilesSelected: ReplaySubject<SurveyFile[]> = new ReplaySubject(1);\n\n public errorMessages: any= {\n require: \"Field required\",\n minLength: \"Must be more than {value} characters\",\n maxLength: \"Must be less than {value} characters\",\n setLength: \"{value} Digit Number Required\",\n numeric: \"The entry can only contain numbers\",\n email: \"Not valid email\"\n };\n\n public initForm(form, formValues) {\n //console.log(form, formValues);\n form.forEach(section=>{\n if (section.name) {\n const groupedItems = _.groupBy(_.filter(section.items, item=>!item.name), item=>item.type);\n\n _.each(groupedItems, (items, type)=>{\n if (type) {\n section.items[_.indexOf(section.items, _.first(items))] = {\n type: type,\n items: items,\n name: section.name,\n isSectionValueItem: true,\n };\n _.each(items, (item)=>{\n section.items = _.without(section.items, item);\n });\n }\n });\n }\n });\n\n\n const visibilityValuesInTableConvert = (item)=>{\n if (item.visibilityValuesInTable) {\n const tableItem = _.first(_.map(form, (section)=>{\n return _.find(section.items, (item)=>{\n if (!item.items) {\n return item.actionUpdatesTableValue;\n } else {\n return _.find(item.items, item=>item.actionUpdatesTableValue);\n }\n });\n }));\n const newValues = <any[]>[];\n if (tableItem) {\n _.each(item.visibilityValuesInTable, (val)=>{\n let valItem = _.find(tableItem.items, item=>item.title===val);\n newValues.push(valItem && valItem.optionValue ? valItem.optionValue : val);\n });\n }\n item.visibilityValuesInTable = newValues;\n }\n };\n\n _.each(form, (section)=>{\n visibilityValuesInTableConvert(section);\n _.each(section.items, (item)=>{\n visibilityValuesInTableConvert(item);\n if (item.type === 'radio' && section.allowsMultipleSelection) {\n item.multiple = true;\n }\n if (item.multiple && _.isString(item.value)) {\n if (_.isString(item.value)) {\n try {\n item.value = JSON.parse(item.value);\n }\n catch (err){\n console.log(err);\n }\n }\n }\n if (formValues[item.name] !== undefined) {\n item.value = formValues[item.name];\n if (item.type === 'date' && !_.isString(item.value)) {\n //item.value = this.getDateStr(formValues[item.name]);\n }\n //item.readOnly = item.readOnly || _.contains(this.readOnlyFields, item.name);\n if (item.multiple && _.isString(item.value)) {\n item.value = JSON.parse(item.value);\n }\n\n if (item.type === 'numericRating' && _.isString(item.value)) {\n item.value = parseInt(item.value);\n }\n }\n if (item.isSectionValueItem && section.sectionValidation && !item.fieldValidation) {\n item.fieldValidation = section.sectionValidation;\n }\n });\n if (section.subtitle) {\n section.subtitle = section.subtitle.replace(new RegExp('\\n', 'g'), '<br />');\n }\n });\n //console.log(form);\n return form;\n }\n\n public isItemVisible(form, section, item) {\n let res = true;\n if (item.visibilityValuesInSection && item.visibilityValuesInSection.length) {\n let sectionItems = section.items?.filter(item=>item.isSectionValueItem).length ? section.items?.filter(item=>item.isSectionValueItem) : section.items?.filter(item=>item.actionUpdatesSectionValue);\n\n res = sectionItems.filter((sItem)=>{\n const valArr=_.isArray(sItem.value) ? sItem.value : [sItem.value];\n return valArr.find(val=>\n item.visibilityValuesInSection.find(arr=>\n arr.indexOf(val)>=0\n )\n )\n }\n ).length===item.visibilityValuesInSection.length;\n }\n if (item.visibilityValuesInTable && item.visibilityValuesInTable.length) {\n let tableItem = _.first(_.map(form, (section) => {\n return _.find(section.items, (item) => {\n if (!item.items) {\n return item.actionUpdatesTableValue;\n } else {\n return _.find(item.items, item=>item.actionUpdatesTableValue);\n }\n });\n }));\n if (tableItem) {\n res = item.visibilityValuesInTable.indexOf(tableItem.value)>=0;\n }\n }\n\n if (section.visibilityValuesInTable && section.visibilityValuesInTable.length) {\n let sectionTableItem = _.first(_.map(form, (section) => {\n return _.find(section.items, (item) => {\n if (!item.items) {\n return item.actionReloadsTable;\n } else {\n return _.find(item.items, item=>item.actionReloadsTable);\n }\n });\n }));\n if (sectionTableItem) {\n res = section.visibilityValuesInTable.indexOf(sectionTableItem.value)>=0;\n }\n }\n\n return res;\n };\n\n public isSectionVisible(form, section) {\n let res = false;\n _.each(section.items, (item)=>{\n if (this.isItemVisible(form, section, item)) {\n res = true;\n }\n });\n return !section.items ? this.isItemVisible(form, section, {}) : res;\n };\n\n getErrors(item): FormItemError[] {\n if (item.fieldValidations) {\n let errors = <FormItemError []> [];\n _.each(item.fieldValidations.rules, (rule)=>{\n const err = <FormItemError> this.checkValidationRule(item, rule);\n if (err) {\n errors.push(err);\n }\n });\n errors = _.flatten(errors);\n if (item.fieldValidations.type === 'OR') {\n return errors.length === item.fieldValidations.rules.length ? [errors[errors.length-1]] : [];\n }\n return errors;\n }\n const err=this.checkValidationRule(item, item.fieldValidation);\n return err ? [err] : [];\n };\n\n checkValidationRule(item, rule) : FormItemError {\n let res;\n let errorMessages=_.clone(this.errorMessages);\n //console.log(item);\n if (rule && rule.minLength >= 0 && rule.minLength === rule.maxLength) {\n rule.setLength = rule.maxLength;\n delete rule.minLength;\n delete rule.maxLength;\n }\n let validationObj = rule || item.sectionValidation;\n let isNumericError = !/^\\d+$/.test(item.value) && validationObj && validationObj.numeric;\n if (!validationObj) {\n //console.log('!validationObj', item);\n }\n if (item.type==='label'){\n return res;\n }\n\n _.each(validationObj, (param, name) => {\n if (name === 'minCount') {\n name = 'minLength';\n }\n let message = '';\n let itemValue = '' + item.value;\n\n switch (name) {\n case \"setLength\":\n if (item.value === undefined || (item.value && itemValue.length !== param) || isNumericError) {\n message = errorMessages[name].replace('{value}', param);\n if (item.keyboardType && item.keyboardType === 'number-pad') {\n message = message.replace('characters', 'digits');\n }\n res={\n type: name,\n message: message\n };\n } else if (item.value === null) {\n //console.log(item);\n res={\n type: 'require',\n message: errorMessages.require\n };\n }\n break;\n case \"minLength\":\n if (!_.isObject(item.value) && (item.value === null || item.value === undefined || !item.value || (item.value?.length || 0) < param || isNumericError)) {\n //console.log(isNumericError, param, item, rule, name);\n if (param > 1) {\n message = errorMessages[name].replace('{value}', param);\n if (item.keyboardType && item.keyboardType === 'number-pad') {\n message = message.replace('characters', 'digits');\n }\n res={\n type: name,\n message: message\n };\n } else if (!item.value || !item?.value?.length) {\n //console.log(item);\n res={\n type: 'require',\n message: errorMessages.require\n };\n }\n else if (isNumericError) {\n res={\n type: 'numeric',\n message: errorMessages.numeric\n };\n }\n }\n if (item.name === 'email' && !res?.length) {\n let re = /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n if (!re.test(item.value)) {\n res={\n type: 'email',\n message: errorMessages.email\n };\n }\n }\n break;\n case \"optionKeyValues\":\n if (!item.value || !item.value.length){\n res={\n type: 'require',\n message: errorMessages.require\n };\n }\n else {\n if (item.value.find(op=>!op.optionValue || !op.label)){\n res={\n type: 'require',\n message: 'All options should have Value and Labels defined'\n };\n }\n }\n break;\n default:\n break;\n }\n });\n return res;\n };\n\n public getValue(form, validateAll:boolean=false){\n let value = {};\n let valid = true;\n let firstError;\n _.each(_.filter(form, (section)=>this.isSectionVisible(form, section)), (section)=>{\n _.each(_.filter(section.items, (item)=>this.isItemVisible(form, section, item)), (item)=>{\n //value[item.name] = _.isArray(item.value) ? JSON.stringify(item.value) : item.value;\n\n value[item.name] = item.value;\n if (validateAll){\n item.errors = this.getErrors(item);\n if (item.errors && item.errors.length) {\n if (!firstError) {\n firstError = item;\n }\n valid = false;\n }\n }\n });\n });\n return {\n valid,\n value,\n firstError\n };\n }\n}\n","import { Directive, ViewContainerRef } from '@angular/core';\n\n@Directive({\n selector: '[form-item-host]',\n})\nexport class FormItemDirective {\n constructor(\n public viewContainerRef: ViewContainerRef\n ) { }\n}\n","import { EventEmitter } from '@angular/core';\nimport { Observable, Observer } from 'rxjs';\n\nexport interface FormItemError {\n type?: string;\n message?: string;\n}\n\nexport interface FormItemValidationRules {\n minLength?: number;\n optionKeyValues?: boolean;\n}\n\nexport interface FormItemValidation {\n rules: FormItemValidationRules[];\n}\n\nexport class FormItem {\n type: string;\n name: string;\n label: string;\n style: string;\n hint: string;\n value?: string | number | string[] | boolean | FormItemOptionItem[] | SurveyFile[] | SurveyFile;\n errors: FormItemError[];\n fieldValidations: FormItemValidation;\n fieldValidation: FormItemValidationRules;\n hasOptions: boolean;\n justAdded: boolean;\n required: boolean;\n readOnly: boolean;\n multiple: boolean;\n actionUpdatesTableValue: boolean;\n actionUpdatesSectionValue: boolean;\n visibilityValuesInTable: string[];\n visibilityValuesInSection: string[];\n items?: FormItemOptionItem[];\n segments?: FormItemOptionItem[];\n isSectionValueItem?: boolean;\n busy?:boolean;\n}\n\nexport interface FormItemOptionItem {\n optionValue: string;\n label: string;\n showExplanation?: boolean;\n explanationLabel?: string;\n selected?: boolean;\n}\n\n\nexport interface FormItemWidget {\n item: FormItem;\n editable: boolean;\n isMobile?: boolean;\n changes: EventEmitter<FormItem>;\n}\n\nexport interface FormSection {\n name?: string;\n title?: string;\n subtitle?: string;\n sectionStyle?: string;\n items?: FormItem[];\n isEditable?: boolean;\n hasError?: boolean;\n firstErrorText?: string;\n}\n\nexport class SurveyFile {\n progressSubject: Observable<number>;\n progressObserver: Observer<number>;\n progressValue: number;\n uploading: boolean;\n name: string;\n size: number;\n mime: string;\n src: string | ArrayBuffer | null;\n url: string;\n file: File;\n duration: number;\n}\n","import {UntypedFormControl, FormGroupDirective, NgForm} from '@angular/forms';\nimport {ErrorStateMatcher} from '@angular/material/core';\n\nexport class SurveyErrorStateMatcher implements ErrorStateMatcher {\n public item:any;\n isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {\n return !(this.item && !(this.item.errors && this.item.errors.length));\n }\n}\n\nexport class ItemOptionStateMatcher implements ErrorStateMatcher {\n isErrorState(control: UntypedFormControl, form: FormGroupDirective | NgForm): boolean {\n //console.log(control);\n return control && !control.value;\n }\n}\n","import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core';\nimport { FormItem, SurveyErrorStateMatcher, FormItemWidget } from '../index';\n\nexport class FormItemString extends FormItem {\n hint: string;\n}\n\n@Component({\n selector: 'ammo-form-item-string',\n templateUrl: './form-item-string.component.html',\n styleUrls: ['./form-item-string.component.scss']\n})\nexport class FormItemStringComponent implements FormItemWidget, OnInit, OnChanges {\n\n @Input() item: FormItemString;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemString>();\n matcher = new SurveyErrorStateMatcher();\n maxLabelLength=60;\n\n constructor() { }\n\n ngOnInit() {\n this.matcher.item=this.item;\n }\n\n ngOnChanges() {\n this.matcher.item=this.item;\n }\n\n checkRequired(placeholder) {\n if (placeholder === 'Required') {\n return true;\n }\n }\n\n onValueChanges(item) {\n this.changes.emit(item);\n }\n}\n","\n<mat-form-field>\n <label class=\"long-label-text\" *ngIf=\"item.label.length>=maxLabelLength\" [ngClass]=\"{'has-error':item.errors && item.errors.length}\">{{item.label}} <span *ngIf=\"item.required\" class=\"required-asterix\">*</span></label>\n <input #inputField\n matInput\n [type]=\"item.style || 'text'\"\n [disabled]=\"!editable\"\n [attr.id]=\"item.name\"\n [placeholder]=\"item.label.length<maxLabelLength ? item.label : ''\"\n [(ngModel)]=\"item.value\"\n [minlength]=\"item.fieldValidation ? item.fieldValidation.minLength : undefined \"\n (ngModelChange)=\"onValueChanges(item)\"\n [errorStateMatcher]=\"matcher\"\n [required]=\"item.required\"\n >\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length) && item.hint?.length < maxLabelLength\"><strong>{{item.hint}}</strong> </mat-hint>\n\n</mat-form-field>\n<small class=\"long-hint\" *ngIf=\"!(item.errors && item.errors.length) && item.hint?.length >= maxLabelLength\"><strong>{{item.hint}}</strong> </small>\n\n","import { Component, OnInit, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';\n\n\n@Component({\n selector: 'mat-star-rating',\n templateUrl: './star-rating.component.html',\n styleUrls: ['./star-rating.component.css'],\n encapsulation: ViewEncapsulation.Emulated\n})\nexport class StarRatingComponent implements OnInit {\n\n @Input() public rating: number;\n @Input() public starCount: number;\n @Input() public color: string;\n @Input() public readOnly: boolean;\n @Output() public ratingUpdated = new EventEmitter();\n\n public snackBarDuration: number = 2000;\n public ratingArr : number[]=[];\n\n constructor() {\n }\n\n\n ngOnInit() {\n for (let index = 0; index < this.starCount; index++) {\n this.ratingArr.push(index);\n }\n }\n onClick(rating:number) {\n if (this.readOnly){\n return false;\n }\n this.rating=rating;\n this.ratingUpdated.emit(rating);\n return false;\n }\n\n showIcon(index:number) {\n if (this.rating >= index + 1) {\n return 'star';\n } else {\n return 'star_border';\n }\n }\n\n}\nexport enum StarRatingColor {\n primary = \"primary\",\n accent = \"accent\",\n warn = \"warn\"\n}\n","<button mat-icon-button [color]=\"color\" *ngFor=\"let ratingId of ratingArr;index as i\" [id]=\"'star_'+i\" (click)=\"onClick(i+1)\" [matTooltip]=\"ratingId+1\" matTooltipPosition=\"above\">\n <mat-icon>\n {{showIcon(i)}}\n </mat-icon>\n</button>\n<mat-error *ngIf=\"starCount == null || starCount == 0\">\n Star count is <strong>required</strong> and cannot be zero\n</mat-error>\n","import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';\nimport { FormItem, FormItemWidget } from '../form-item';\n\nexport class FormItemRating extends FormItem {\n value: number;\n}\n\n\n@Component({\n selector: 'ammo-form-item-rating',\n templateUrl: './form-item-rating.component.html',\n styleUrls: ['./form-item-rating.component.scss']\n})\nexport class FormItemRatingComponent implements FormItemWidget, OnInit {\n\n @Input() item: FormItemRating;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemRating>();\n\n constructor() { }\n\n ngOnInit() {\n\n }\n\n onRatingChanged(value){\n if (!this.editable){\n return;\n }\n this.item.value=value;\n this.changes.emit(this.item);\n }\n}\n","<div class=\"form-group\">\n <div class=\"col-xs-12 rating-set\">\n <div class=\"rating-set-title\">{{item.label}}</div>\n <div class=\"rating-set-stars\">\n <mat-star-rating\n [rating]=\"item.value\"\n [starCount]=\"5\"\n [color]=\"editable ? 'primary' : 'muted'\"\n [readOnly]=\"!editable\"\n (ratingUpdated)=\"onRatingChanged($event)\"\n ></mat-star-rating>\n </div>\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length)\"><strong>{{item.hint}}</strong> </mat-hint>\n </div>\n</div>\n","import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';\nimport { FormItem, SurveyErrorStateMatcher, FormItemWidget } from '../index';\n\nexport class FormItemText extends FormItem {\n hint: string;\n}\n\n@Component({\n selector: 'ammo-form-item-text',\n templateUrl: './form-item-text.component.html',\n styleUrls: ['./form-item-text.component.scss']\n})\nexport class FormItemTextComponent implements FormItemWidget, OnInit {\n\n @Input() item: FormItemText;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemText>();\n matcher = new SurveyErrorStateMatcher();\n maxLabelLength=60;\n\n constructor() { }\n\n\n ngOnInit() {\n this.matcher.item=this.item;\n }\n\n ngOnChanges() {\n this.matcher.item=this.item;\n }\n\n checkRequired(placeholder) {\n if (placeholder === 'Required') {\n return true;\n }\n }\n\n onValueChanges(item) {\n this.changes.emit(item);\n }\n}\n","\n<mat-form-field class=\"example-full-width\">\n <label class=\"long-label-text\" *ngIf=\"item.label.length>=maxLabelLength\" [ngClass]=\"{'has-error':item.errors && item.errors.length}\">{{item.label}} <span *ngIf=\"item.required\" class=\"required-asterix\">*</span></label>\n <textarea matInput\n [disabled]=\"!editable\"\n [attr.id]=\"item.name\"\n [placeholder]=\"item.label.length<maxLabelLength ? item.label : ''\"\n [(ngModel)]=\"item.value\"\n (ngModelChange)=\"onValueChanges(item)\"\n [errorStateMatcher]=\"matcher\"\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n [required]=\"item.required\"\n ></textarea>\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length) && item.hint?.length < maxLabelLength\"><strong>{{item.hint}}</strong> </mat-hint>\n\n</mat-form-field>\n<small class=\"long-hint\" *ngIf=\"!(item.errors && item.errors.length) && item.hint?.length >= maxLabelLength\"><strong>{{item.hint}}</strong> </small>\n","import { Component, OnInit, Input, EventEmitter, forwardRef, Output, ViewChild, AfterViewInit } from '@angular/core';\nimport { FormItem, SurveyErrorStateMatcher, FormItemWidget } from '../index';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\nimport { MatInput } from '@angular/material/input';\nimport moment from \"moment\";\n\nexport class FormItemDate extends FormItem {\n\n}\n\n\nexport const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormItemDateComponent),\n multi: true\n};\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'ammo-form-item-date',\n templateUrl: './form-item-date.component.html',\n styleUrls: ['./form-item-date.component.scss'],\n providers: [\n CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR\n ],\n})\nexport class FormItemDateComponent implements FormItemWidget, OnInit, AfterViewInit, ControlValueAccessor {\n\n @ViewChild('inputField', { static: true }) public inputField:MatInput;\n\n @Input() item: FormItemDate;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemDate>();\n matcher = new SurveyErrorStateMatcher();\n\n innerValue: any;\n\n constructor() { }\n\n ngOnInit() {\n this.matcher.item=this.item;\n if (this.item.value){\n this.value=moment(this.item.value.toString());//\n }\n this.onTouchedCallback();\n }\n\n ngAfterViewInit(){\n //console.log(this.inputField);\n this.inputField.value='5/14/2021';\n }\n\n ngOnChanges() {\n this.matcher.item=this.item;\n }\n\n checkRequired(placeholder) {\n if (placeholder === 'Required') {\n return true;\n }\n }\n\n onValueChanges(ev) {\n const val=ev.value ? ev.value.format('L') : '';\n this.item.value=val;\n this.changes.emit(this.item);\n }\n\n //Placeholders for the callbacks which are later provided\n //by the Control Value Accessor\n private onTouchedCallback: () => void = noop;\n private onChangeCallback: (_: any) => void = noop;\n\n\n //get accessor\n get value(): any {\n return this.innerValue;\n };\n\n get textValue(): string {\n return this.value ? this.value.format('L') : '';\n };\n\n //set accessor including call the onchange callback\n set value(v: any) {\n if (v !== this.innerValue) {\n this.innerValue = v;\n }\n }\n //Occured value changed from module\n writeValue(value: any): void {\n if (value !== this.innerValue) {\n this.innerValue = value;\n }\n }\n\n registerOnChange(fn: any): void {\n this.onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this.onTouchedCallback = fn;\n }\n\n onChange(event) {\n this.value = event;\n this.onBlur();\n }\n\n onBlur() {\n this.onChangeCallback(this.innerValue);\n }\n\n todate(value){\n this.value = value ? moment(value) : '';\n this.onValueChanges({\n value: this.value\n })\n }\n\n}\n","<div class=\"form-group\">\n <mat-form-field class=\"example-full-width\">\n <input type=\"hidden\" [matDatepicker]=\"picker\" [(ngModel)]='value' (dateChange)=\"onValueChanges($event)\">\n <input matInput #inputField\n [name]=\"item.name\"\n [disabled]=\"!editable || (value && item.readOnly)\"\n [attr.id]=\"item.name\"\n [placeholder]=\"item.label\"\n (change)='todate($event.target.value)'\n [ngModel]=\"textValue | date:'MM/dd/yyyy'\"\n [errorStateMatcher]=\"matcher\"\n [required]=\"item.required\"\n mask=\"M0/d0/0000\"\n (blur)=\"onBlur()\"\n >\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length)\"><strong>{{item.hint}}</strong> </mat-hint>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker (selectedChanged)=\"onChange($event)\" #picker></mat-datepicker>\n </mat-form-field>\n</div>\n\n","import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';\nimport { FormItem, FormItemOptionItem, FormItemWidget } from '../form-item';\n\nexport class FormItemSegments extends FormItem {\n segments: FormItemOptionItem[];\n value: string;\n hasOptions: boolean=true;\n}\n\n@Component({\n selector: 'ammo-form-item-segments',\n templateUrl: './form-item-segments.component.html',\n styleUrls: ['./form-item-segments.component.scss']\n})\nexport class FormItemSegmentsComponent implements FormItemWidget, OnInit {\n\n @Input() item: FormItemSegments;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemSegments>();\n\n constructor() { }\n\n ngOnInit() {\n\n }\n\n onSelectionChange(value){\n this.item.value=value;\n this.changes.emit(this.item);\n }\n\n}\n","<div class=\"form-group\">\n <mat-label *ngIf=\"item.label\">{{item.label}}</mat-label>\n <mat-button-toggle-group\n aria-label=\"type of credits\"\n [ngClass]=\"{'has-error':item.errors && item.errors.length}\"\n value=\"{{item.value}}\">\n <mat-button-toggle\n *ngFor=\"let segment of item.segments\"\n [disabled]=\"!editable\"\n (click)=\"editable ? onSelectionChange(segment.optionValue) : false\"\n [value]=\"segment.value\"\n [checked]=\"segment.optionValue===item.value\"\n >{{segment.label}}\n </mat-button-toggle>\n </mat-button-toggle-group>\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length)\"><strong>{{item.hint}}</strong> </mat-hint>\n</div>\n","import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';\nimport { FormItemOptionItem } from '../../form-item';\nimport { MatRadioChange } from '@angular/material/radio';\nimport { MatCheckboxChange } from '@angular/material/checkbox';\n\n\n@Component({\n selector: 'app-radio-group',\n templateUrl: './radio-group.component.html',\n styleUrls: ['./radio-group.component.scss']\n})\nexport class RadioGroupComponent implements OnInit {\n\n @Input() label: string;\n @Input() editable: boolean=true;\n @Input() required: boolean;\n @Input() multiple: boolean;\n @Input() options: FormItemOptionItem[]=[];\n @Output() selectionChange = new EventEmitter<string | string[]>();\n\n @Input() value: string | string[];\n\n constructor() { }\n\n ngOnInit(): void {\n }\n\n isOptionSelected(option:FormItemOptionItem){\n return this.multiple ? (this.value || []).indexOf(option.optionValue) >=0 : this.value===option.optionValue;\n }\n\n onSelectionChange(event:MatRadioChange){\n this.selectionChange.emit(event.value);\n }\n onCheckboxSelectionChange(event:MatCheckboxChange){\n let value=this.value && Array.isArray(this.value) ? this.value : [];\n if (event.checked){\n value.push(event.source.value);\n }\n else {\n value=value.filter(v=>v!==event.source.value);\n }\n //console.log(value);\n this.selectionChange.emit(value);\n }\n\n}\n","<mat-radio-group [attr.aria-label]=\"label\" *ngIf=\"!multiple\"\n (change)=\"onSelectionChange($event)\"\n [disabled]=\"!editable\"\n [(ngModel)]=\"value\"\n [required]=\"required\"\n>\n <mat-radio-button *ngFor=\"let option of options\"\n [value]=\"option.optionValue\"\n [checked]=\"isOptionSelected(option)\"\n >{{option.label}}\n </mat-radio-button>\n\n</mat-radio-group>\n<div class=\"example-list-section\" *ngIf=\"multiple\">\n <ul>\n <li *ngFor=\"let option of options\">\n <mat-checkbox\n [value]=\"option.optionValue\"\n [checked]=\"isOptionSelected(option)\"\n [disabled]=\"!editable\"\n (change)=\"onCheckboxSelectionChange($event)\">\n {{option.label}}\n </mat-checkbox>\n </li>\n </ul>\n</div>\n","import { Component, OnInit, EventEmitter, Input, Output, ViewChild, OnChanges, SimpleChanges } from '@angular/core';\nimport { MatSelectionList, MatSelectionListChange } from '@angular/material/list';\nimport { FormItemOptionItem } from '../../form-item';\n\n@Component({\n selector: 'app-selection-list',\n templateUrl: './selection-list.component.html',\n styleUrls: ['./selection-list.component.scss']\n})\nexport class SelectionListComponent implements OnInit, OnChanges {\n\n @Input() label: string;\n @Input() editable: boolean=true;\n @Input() required: boolean;\n @Input() multiple: boolean;\n @Input() options: FormItemOptionItem[]=[];\n @Output() selectionChange = new EventEmitter<string | string[]>();\n\n @Input() value: string | string[];\n\n @ViewChild('selectedOptions', { static: false }) public selectedOptions:MatSelectionList;\n\n public init:boolean=true;\n\n constructor() { }\n\n ngOnInit(): void {\n }\n\n isOptionSelected(option:FormItemOptionItem){\n return this.multiple ? (this.value || []).indexOf(option.optionValue) >=0 : this.value===option.optionValue;\n }\n\n onSelectionChange(event: MatSelectionListChange){\n //console.log(event, this.selectedOptions);\n this.value=this.multiple ? this.selectedOptions.selectedOptions.selected.map(op=>op.value) : event.options[0].value;\n this.selectionChange.emit(this.value);\n }\n\n ngOnChanges(changes:SimpleChanges){\n if (changes.multiple && changes.multiple.previousValue!==changes.multiple.currentValue){\n this.init=false;\n //console.log(changes);\n setTimeout(()=>{this.init=true;}, 10);\n }\n }\n\n onOptionClick(event, option:FormItemOptionItem){\n /*\n console.log(event, option);\n if (!this.required){\n if (this.multiple && this.value.indexOf(option.optionValue)>=0 && Array.isArray(this.value)){\n this.value=this.value.filter(str=>str!==option.optionValue);\n this.selectionChange.emit(this.value);\n }\n else if (this.value===option.optionValue) {\n this.value='';\n this.selectionChange.emit(this.value);\n }\n }\n */\n }\n\n}\n","<mat-selection-list #selectedOptions *ngIf=\"init\"\n (selectionChange)=\"onSelectionChange($event)\"\n [disabled]=\"!editable\"\n\n [multiple]=\"multiple\"\n>\n <!--\n [selected]=\"isOptionSelected(option)\"\n -->\n <mat-list-option *ngFor=\"let option of options\"\n [value]=\"option.optionValue\"\n [selected]=\"isOptionSelected(option)\"\n (click)=\"onOptionClick($event, option)\"\n >\n <span>{{option.label}}</span>\n <!--\n <mat-pseudo-checkbox *ngIf=\"!multiple && isOptionSelected(option)\" class=\"mat-pseudo-checkbox mat-pseudo-checkbox-checked\"></mat-pseudo-checkbox>\n -->\n </mat-list-option>\n</mat-selection-list>\n","import { Component, OnInit, EventEmitter, Input, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { MatSelectChange } from '@angular/material/select';\nimport { FormItemOptionItem } from '../../form-item';\nimport { SurveyErrorStateMatcher } from '../../error-state.matcher';\n\n\n@Component({\n selector: 'app-select',\n templateUrl: './select.component.html',\n styleUrls: ['./select.component.scss']\n})\nexport class SelectComponent implements OnInit, OnChanges {\n\n @Input() label: string;\n @Input() editable: boolean=true;\n @Input() required: boolean;\n @Input() multiple: boolean;\n @Input() options: FormItemOptionItem[]=[];\n @Output() selectionChange = new EventEmitter<string | string[]>();\n\n @Input() value: string | string[];\n\n public init:boolean=true;\n\n matcher = new SurveyErrorStateMatcher();\n\n constructor() { }\n\n ngOnInit(): void {\n }\n\n isOptionSelected(option:FormItemOptionItem){\n return this.multiple ? (this.value || []).indexOf(option.optionValue) >=0 : this.value===option.optionValue;\n }\n\n onSelectionChange(event: MatSelectChange){\n //console.log(event);\n this.value=event.value;\n this.selectionChange.emit(this.value);\n }\n\n ngOnChanges(changes:SimpleChanges){\n if (changes.multiple && changes.multiple.previousValue!==changes.multiple.currentValue){\n this.init=false;\n //console.log(changes);\n setTimeout(()=>{this.init=true;}, 10);\n }\n }\n\n}\n","<mat-form-field appearance=\"fill\" *ngIf=\"init\">\n <mat-select\n [value]=\"value\"\n [disabled]=\"!editable\"\n (selectionChange)=\"onSelectionChange($event)\"\n [errorStateMatcher]=\"matcher\"\n [required]=\"required\"\n [multiple]=\"multiple\"\n >\n <mat-option *ngFor=\"let option of options\" [value]=\"option.optionValue\">\n {{option.label}}\n </mat-option>\n </mat-select>\n</mat-form-field>","import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';\nimport { FormItem, FormItemOptionItem, FormItemWidget } from '../form-item';\n\nexport class FormItemRadio extends FormItem {\n items: FormItemOptionItem[];\n multiple: boolean;\n value: string | string[];\n hasOptions: boolean=true;\n otherTextValue: string;\n}\n\n@Component({\n selector: 'ammo-form-item-radio',\n templateUrl: './form-item-radio.component.html',\n styleUrls: ['./form-item-radio.component.scss']\n})\nexport class FormItemRadioComponent implements FormItemWidget, OnInit {\n\n @Input() item: FormItemRadio;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemRadio>();\n\n explanationValue: string='';\n explanationLabel: string | undefined;\n selectedOption: string;\n\n constructor() { }\n\n ngOnInit() {\n //console.log(this.item);\n if (this.item && !this.item.multiple && Array.isArray(this.item.value)){\n this.item.value=this.item.value[0];\n }\n //console.log(this.item.value);\n let selectedOptionObj=this.item.items.find(op=>op.optionValue===this.item.value);\n this.selectedOption=selectedOptionObj ? selectedOptionObj.optionValue : '';\n if (!this.selectedOption && this.item.value && !this.item.multiple){\n const valArr=(this.item.value.toString()).split(', ');\n\n selectedOptionObj=this.item.items.find(op=>op.optionValue===valArr[0]);\n //console.log(valArr, selectedOptionObj);\n if (selectedOptionObj){\n this.selectedOption=selectedOptionObj.optionValue;\n this.explanationValue=valArr.slice(1, valArr.length).join(', ');\n }\n }\n //console.log(this.item.value);\n }\n\n\n onSelectionChange(value:string | string[]){\n //console.log(value);\n this.item.value=value;\n if (!Array.isArray(value)){\n this.selectedOption=value;\n this.onExplanationValueChanges(this.explanationValue, this.item.value);\n }\n this.changes.emit(this.item);\n }\n\n\n onExplanationValueChanges(val:string, selectedOptionVal:string | string[]){\n //console.log(val);\n //console.log(val, selectedOptionVal);\n const option=this.item.items.find(op=>op.optionValue===selectedOptionVal);\n if (!option || !this.isExplanationRequired(option.optionValue)){\n return false;\n }\n\n this.item.value=option.optionValue+', '+val;\n this.changes.emit(this.item);\n }\n\n isExplanationRequired(selectedOptionVal:string | string[]){\n //console.log(selectedOptionVal);\n const option=this.item.items.find(op=>op.optionValue===selectedOptionVal);\n if (!option){\n return false;\n }\n this.explanationLabel=option.explanationLabel\n return option && option.showExplanation;\n }\n}\n","<label *ngIf=\"item.label\" [ngClass]=\"{'has-error':item.errors && item.errors.length}\">{{item.label}} <span class=\"required\" *ngIf=\"item.required\">*</span></label>\n<ng-container *ngIf=\"item.items && item.items.length\">\n <app-selection-list *ngIf=\"!item.style || item.style==='list'\"\n [label]=\"item.label\"\n [editable]=\"editable\"\n [required]=\"item.required\"\n [value]=\"item.multiple ? item.value : selectedOption\"\n [options]=\"item.items\"\n [multiple]=\"item.multiple\"\n (selectionChange)=\"onSelectionChange($event)\"\n ></app-selection-list>\n <app-radio-group *ngIf=\"item.style==='buttons'\"\n [label]=\"item.label\"\n [editable]=\"editable\"\n [required]=\"item.required\"\n [label]=\"item.label\"\n [value]=\"item.multiple ? item.value : selectedOption\"\n [options]=\"item.items\"\n [multiple]=\"item.multiple\"\n (selectionChange)=\"onSelectionChange($event)\"\n ></app-radio-group>\n <app-select *ngIf=\"item.style==='select'\"\n [label]=\"item.label\"\n [editable]=\"editable\"\n [required]=\"item.required\"\n [value]=\"item.multiple ? item.value : selectedOption\"\n [options]=\"item.items\"\n [multiple]=\"item.multiple\"\n (selectionChange)=\"onSelectionChange($event)\"\n ></app-select>\n <mat-form-field *ngIf=\"isExplanationRequired(selectedOption)\" class=\"other-option-field\">\n <mat-label>{{explanationLabel}}</mat-label>\n <input #inputField\n matInput\n [(ngModel)]=\"explanationValue\"\n (ngModelChange)=\"onExplanationValueChanges($event, selectedOption)\"\n >\n </mat-form-field>\n</ng-container>\n\n<mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n</mat-error>\n<mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length)\"><strong>{{item.hint}}</strong> </mat-hint>\n","import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';\nimport { FormItem, FormItemWidget } from '../form-item';\n\nexport class FormItemNumericRating extends FormItem {\n value: number;\n}\n\n@Component({\n selector: 'ammo-form-item-numeric-rating',\n templateUrl: './form-item-numeric-rating.component.html',\n styleUrls: ['./form-item-numeric-rating.component.scss']\n})\nexport class FormItemNumericRatingComponent implements FormItemWidget, OnInit {\n\n @Input() item: FormItemNumericRating;\n @Input() editable: boolean=true;\n @Output() changes = new EventEmitter<FormItemNumericRating>();\n\n constructor() { }\n\n ngOnInit() {\n\n }\n\n onSelectionChange(value){\n this.item.value=value;\n this.changes.emit(this.item);\n }\n\n}\n","<div class=\"form-group\">\n <div class=\"col-xs-12 rating-set\">\n <div class=\"rating-set-title\">{{item.label}}</div>\n <div class=\"rating-set-buttons\">\n <button mat-button class=\"btn btn-sm\" type=\"button\"\n (click)=\"editable ? onSelectionChange(i) : false\"\n [ngClass]=\"item.value===i ? 'btn-primary' : 'btn-outline-primary'\"\n *ngFor=\"let i of [0,1,2,3,4,5,6,7,8,9,10]\">{{i}}</button>\n </div>\n <mat-error *ngIf=\"item.errors && item.errors.length\">\n <div *ngFor=\"let error of item.errors\">{{error.message}}</div>\n </mat-error>\n <mat-hint align=\"start\" *ngIf=\"!(item.errors && item.errors.length)\"><strong>{{item.hint}}</strong> </mat-hint>\n </div>\n</div>\n","import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';\nimport { SurveyErrorStateMatcher } from '../error-state.matcher';\nimport { FormItem, FormItemOptionItem, FormItemWidget } from '../form-item';\n\nexport class FormItemSelect extends FormItem {\n items: FormItemOptionItem[];\n value: string;\n hasOptions: boolean=true;\n}\n\n@Component({\n selector: 'ammo-form-item-select',\n templateUrl: './form-item-select.component.html',\n styleUrls: ['./form-item-select.component.scss']\n})\nexport class