UNPKG

@sedeh/into-pipes

Version:

Have you ever wanted to transform data in different parts of your application into interactive objects without writing a single line of code?

116 lines 14.2 kB
import { Component, Output, EventEmitter } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class InputGroupComponent { constructor(renderer) { this.renderer = renderer; this.disabled = false; this.active = true; this.validate = (item, newValue) => true; this.onIntoComponentChange = new EventEmitter(); } keyup(event) { const code = event.which; event.stopPropagation(); event.preventDefault(); if (code === 13 && !this.disabled) { event.target.click(); } } change(event) { event.stopPropagation(); event.preventDefault(); if (!this.disabled) { let index = -1; this.options.map((option, i) => { const v = option.value ? option.value : option; if (v === event.target.value) index = i; }); const change = { index: index, value: event.target.value }; if (this.validate(this.data, change)) { if (this.type === 'radio') { this.source = change.value; } else { if (event.target.checked) { this.source.push(event.target.value); } else { const x = this.source.indexOf(event.target.value); this.source.splice(change.index, x); } } this.onIntoComponentChange.emit({ id: this.id, name: this.name, value: this.source, type: "select", item: this.data }); } else { this.options = JSON.parse(JSON.stringify(this.options)); } } } isSelected(item) { const xitem = item.value ? item.value : item; if (this.type === 'radio') { return xitem === this.source; } let found = false; this.source.map((x) => { if (xitem === x) { found = true; } }); return found; } static settingsPatterns() { return ['inputgroup']; //no argument } transform(source, data, args) { this.source = source; this.data = data; this.options = this.service.getDataFor(this.name, this.id, data); this.type = (source instanceof Array) ? 'checkbox' : 'radio'; } } InputGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputGroupComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); InputGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputGroupComponent, selector: "input-group-component", outputs: { onIntoComponentChange: "onIntoComponentChange" }, ngImport: i0, template: ` <span class="input-group-item" *ngFor="let x of options; let i = index"> <input [type]="type" [id]="name + i" tabindex="{{active ? 0 : -1}}" [name]="name + (type === 'radio' ? '' : i)" [value]="x.value ? x.value : x" [disabled]="disabled" [checked]="isSelected(x)" (keyup)='keyup($event)' (change)="change($event)"/> <label [for]="name + i" [textContent]="x.label ? x.label : x"></label> </span> <span class="selected-value" [textContent]="source"></span> `, isInline: true, styles: [":host{display:table;float:left;min-height:var(--sedeh-min-height, 25px)}:host .selected-value{display:none}@media print{:host .selected-value{display:block}:host .input-group-item{display:none}}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputGroupComponent, decorators: [{ type: Component, args: [{ selector: 'input-group-component', template: ` <span class="input-group-item" *ngFor="let x of options; let i = index"> <input [type]="type" [id]="name + i" tabindex="{{active ? 0 : -1}}" [name]="name + (type === 'radio' ? '' : i)" [value]="x.value ? x.value : x" [disabled]="disabled" [checked]="isSelected(x)" (keyup)='keyup($event)' (change)="change($event)"/> <label [for]="name + i" [textContent]="x.label ? x.label : x"></label> </span> <span class="selected-value" [textContent]="source"></span> `, styles: [":host{display:table;float:left;min-height:var(--sedeh-min-height, 25px)}:host .selected-value{display:none}@media print{:host .selected-value{display:block}:host .input-group-item{display:none}}\n"] }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { onIntoComponentChange: [{ type: Output, args: ["onIntoComponentChange"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZ3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW50by1waXBlcy9zcmMvbGliL2lucHV0Z3JvdXAvaW5wdXQtZ3JvdXAuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWEsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBZ0MzRSxNQUFNLE9BQU8sbUJBQW1CO0lBaUI5QixZQUFvQixRQUFtQjtRQUFuQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBVHZDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsV0FBTSxHQUFHLElBQUksQ0FBQztRQUNkLGFBQVEsR0FBRyxDQUFDLElBQVMsRUFBRSxRQUFhLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQztRQUs5QywwQkFBcUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBRUQsQ0FBQztJQUUzQyxLQUFLLENBQUMsS0FBVTtRQUNkLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDekIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV2QixJQUFJLElBQUksS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQy9CLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDeEI7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQVM7UUFDZCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2xCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxN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LElBQUksR0FBRyxDQUFDLE1BQU0sWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDL0QsQ0FBQzs7aUhBaEZVLG1CQUFtQjtxR0FBbkIsbUJBQW1CLDBIQTNCbEI7Ozs7Ozs7Ozs7Ozs7OztLQWVUOzRGQVlRLG1CQUFtQjtrQkE3Qi9CLFNBQVM7K0JBQ0ksdUJBQXVCLFlBQ3ZCOzs7Ozs7Ozs7Ozs7Ozs7S0FlVDtnR0EyQkgscUJBQXFCO3NCQURwQixNQUFNO3VCQUFDLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgUmVuZGVyZXIyLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBQaXBlQ29tcG9uZW50SW50ZXJmYWNlLCBQaXBlU2VydmljZUNvbXBvbmVudEludGVyZmFjZSB9IGZyb20gJy4uL2NvbW1vbi9waXBlLmNvbXBvbmVudC5pbnRlcmZhY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2lucHV0LWdyb3VwLWNvbXBvbmVudCcsXHJcbiAgICB0ZW1wbGF0ZTogYFxyXG4gICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC1pdGVtXCIgKm5nRm9yPVwibGV0IHggb2Ygb3B0aW9uczsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICA8aW5wdXQgXHJcbiAgICAgICAgW3R5cGVdPVwidHlwZVwiIFxyXG4gICAgICAgIFtpZF09XCJuYW1lICsgaVwiIFxyXG4gICAgICAgIHRhYmluZGV4PVwie3thY3RpdmUgPyAwIDogLTF9fVwiXHJcbiAgICAgICAgW25hbWVdPVwibmFtZSArICh0eXBlID09PSAncmFkaW8nID8gJycgOiBpKVwiIFxyXG4gICAgICAgIFt2YWx1ZV09XCJ4LnZhbHVlID8geC52YWx1ZSA6IHhcIiBcclxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gICAgICAgIFtjaGVja2VkXT1cImlzU2VsZWN0ZWQoeClcIlxyXG4gICAgICAgIChrZXl1cCk9J2tleXVwKCRldmVudCknXHJcbiAgICAgICAgKGNoYW5nZSk9XCJjaGFuZ2UoJGV2ZW50KVwiLz5cclxuICAgICAgPGxhYmVsIFtmb3JdPVwibmFtZSArIGlcIiBbdGV4dENvbnRlbnRdPVwieC5sYWJlbCA/IHgubGFiZWwgOiB4XCI+PC9sYWJlbD5cclxuICAgIDwvc3Bhbj5cclxuICAgIDxzcGFuIGNsYXNzPVwic2VsZWN0ZWQtdmFsdWVcIiBbdGV4dENvbnRlbnRdPVwic291cmNlXCI+PC9zcGFuPlxyXG4gICAgYCxcclxuICAgIHN0eWxlczogW1xyXG4gICAgICBgXHJcbiAgICAgIDpob3N0IHtkaXNwbGF5OnRhYmxlO2Zsb2F0OmxlZnQ7bWluLWhlaWdodDogdmFyKC0tc2VkZWgtbWluLWhlaWdodCwgMjVweCl9XHJcbiAgICAgIDpob3N0IC5zZWxlY3RlZC12YWx1ZSB7ZGlzcGxheTpub25lfVxyXG4gICAgICBAbWVkaWEgcHJpbnQge1xyXG4gICAgICAgIDpob3N0IC5zZWxlY3RlZC12YWx1ZSB7ZGlzcGxheTogYmxvY2s7fVxyXG4gICAgICAgIDpob3N0IC5pbnB1dC1ncm91cC1pdGVtIHtkaXNwbGF5OiBub25lO31cclxuICAgICAgfVxyXG4gICAgICBgXHJcbiAgICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBJbnB1dEdyb3VwQ29tcG9uZW50IGltcGxlbWVudHMgUGlwZUNvbXBvbmVudEludGVyZmFjZSB7XHJcblxyXG4gIGRhdGE6IGFueTtcclxuICBzb3VyY2U6IGFueTtcclxuICBvcHRpb25zITogYW55O1xyXG4gIGlkITogc3RyaW5nO1xyXG4gIG5hbWUhOiBzdHJpbmc7XHJcbiAgdHlwZSE6IHN0cmluZztcclxuICBkaXNhYmxlZCA9IGZhbHNlO1xyXG4gIGFjdGl2ZSA9IHRydWU7XHJcbiAgdmFsaWRhdGUgPSAoaXRlbTogYW55LCBuZXdWYWx1ZTogYW55KSA9PiB0cnVlO1xyXG5cclxuICBzZXJ2aWNlITogUGlwZVNlcnZpY2VDb21wb25lbnRJbnRlcmZhY2U7XHJcblxyXG4gIEBPdXRwdXQoXCJvbkludG9Db21wb25lbnRDaGFuZ2VcIilcclxuICBvbkludG9Db21wb25lbnRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cclxuXHJcbiAga2V5dXAoZXZlbnQ6IGFueSkge1xyXG4gICAgY29uc3QgY29kZSA9IGV2ZW50LndoaWNoO1xyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgIGlmIChjb2RlID09PSAxMyAmJiAhdGhpcy5kaXNhYmxlZCkge1xyXG4gICAgICAgIGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG4gICAgfVxyXG4gIH1cclxuICBjaGFuZ2UoZXZlbnQ6YW55KSB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgbGV0IGluZGV4ID0gLTE7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5tYXAoKG9wdGlvbjogYW55LCBpOiBudW1iZXIpID0+IHtjb25zdCB2ID0gb3B0aW9uLnZhbHVlID8gb3B0aW9uLnZhbHVlIDogb3B0aW9uOyBpZiAodiA9PT0gZXZlbnQudGFyZ2V0LnZhbHVlKWluZGV4ID0gaX0pO1xyXG4gICAgICBjb25zdCBjaGFuZ2UgPSB7aW5kZXg6ICBpbmRleCwgdmFsdWU6IGV2ZW50LnRhcmdldC52YWx1ZX07XHJcbiAgICAgIGlmICh0aGlzLnZhbGlkYXRlKHRoaXMuZGF0YSwgY2hhbmdlKSkge1xyXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdyYWRpbycpIHtcclxuICAgICAgICAgIHRoaXMuc291cmNlID0gY2hhbmdlLnZhbHVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpZiAoZXZlbnQudGFyZ2V0LmNoZWNrZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2UucHVzaChldmVudC50YXJnZXQudmFsdWUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgeCA9ICg8YW55W10+dGhpcy5zb3VyY2UpLmluZGV4T2YoZXZlbnQudGFyZ2V0LnZhbHVlKTtcclxuICAgICAgICAgICAgdGhpcy5zb3VyY2Uuc3BsaWNlKGNoYW5nZS5pbmRleCx4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbkludG9Db21wb25lbnRDaGFuZ2UuZW1pdCh7XHJcbiAgICAgICAgICBpZDogdGhpcy5pZCxcclxuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcclxuICAgICAgICAgIHZhbHVlOiB0aGlzLnNvdXJjZSxcclxuICAgICAgICAgIHR5cGU6IFwic2VsZWN0XCIsXHJcbiAgICAgICAgICBpdGVtOiB0aGlzLmRhdGFcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLm9wdGlvbnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucykpXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgaXNTZWxlY3RlZChpdGVtOiBhbnkpIHtcclxuICAgIGNvbnN0IHhpdGVtID0gaXRlbS52YWx1ZSA/IGl0ZW0udmFsdWUgOiBpdGVtO1xyXG4gICAgaWYgKHRoaXMudHlwZSA9PT0gJ3JhZGlvJykge1xyXG4gICAgICByZXR1cm4geGl0ZW0gPT09IHRoaXMuc291cmNlO1xyXG4gICAgfVxyXG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XHJcbiAgICB0aGlzLnNvdXJjZS5tYXAoKHg6IGFueSkgPT4ge1xyXG4gICAgICBpZiAoeGl0ZW0gPT09IHgpIHtcclxuICAgICAgICBmb3VuZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZvdW5kO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIHNldHRpbmdzUGF0dGVybnMoKSB7XHJcbiAgICByZXR1cm4gWydpbnB1dGdyb3VwJ107IC8vbm8gYXJndW1lbnRcclxuICB9XHJcbiAgdHJhbnNmb3JtKHNvdXJjZTogYW55LCBkYXRhOiBhbnksIGFyZ3M6IGFueVtdKSB7XHJcbiAgICB0aGlzLnNvdXJjZT0gc291cmNlO1xyXG4gICAgdGhpcy5kYXRhID0gZGF0YTtcclxuICAgIHRoaXMub3B0aW9ucyA9IHRoaXMuc2VydmljZS5nZXREYXRhRm9yKHRoaXMubmFtZSwgdGhpcy5pZCwgZGF0YSk7XHJcbiAgICB0aGlzLnR5cGUgPSAoc291cmNlIGluc3RhbmNlb2YgQXJyYXkpID8gJ2NoZWNrYm94JyA6ICdyYWRpbyc7XHJcbiAgfVxyXG59XHJcblxyXG4iXX0=