UNPKG

ngx-edu-components

Version:
1,133 lines (1,119 loc) 131 kB
import { Component, ViewChild, Input, Output, EventEmitter, Inject, ElementRef, Directive, HostListener, NgModule } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef, MatButtonModule, MatMenuModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatIconModule, MatCardModule, MatDividerModule, MatTooltipModule, MatDialogModule, MatSelectModule } from '@angular/material'; import { FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import * as moment_ from 'moment'; import Viewer from 'viewerjs'; import { v4 } from 'uuid'; import { AngularCropperjsModule } from 'angular-cropperjs'; import { CommonModule } from '@angular/common'; import { FlexLayoutModule } from '@angular/flex-layout'; import { NgxMaskModule } from 'ngx-mask'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgxEduComponentsComponent { constructor() { } /** * @return {?} */ ngOnInit() { } } NgxEduComponentsComponent.decorators = [ { type: Component, args: [{ selector: 'NgxEdu-NgxEduComponents', template: ` <p> ngx-edu-components works! </p> ` }] } ]; /** @nocollapse */ NgxEduComponentsComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // @dynamic class RegExpHelper { } RegExpHelper.D78 = /^\d{7}(?:\d{1})?$/; RegExpHelper.D123 = /^\d{1}(?:\d{1})?(?:\d{1})?$/; RegExpHelper.D12 = /^\d{1}(?:\d{1})?$/; RegExpHelper.AREA_CODE = /^[1-9]{1}(\d{1})(?:\d{1})?(?:\d{1})?$/; RegExpHelper.LOCAL_PHONE_NUMBER = /^\d{6}(?:\d{1})?(?:\d{1})?(?:\d{1})?$/; RegExpHelper.ONLY_NUMBER_MAX_2 = /^\d{1,2}$/; RegExpHelper.ONLY_NUMBER_MAX_3 = /^\d{1,3}$/; RegExpHelper.ONLY_NUMBER_MAX_4 = /^\d{1,4}$/; RegExpHelper.ONLY_NUMBER_MAX_8 = /^\d{1,8}$/; RegExpHelper.ONLY_NUMBER_MAX_10 = /^\d{1,10}$/; RegExpHelper.DATE_ES_AR = /^([0-2][0-9]|(3)[0-1])(\/)(((0)[1-9])|((1)[0-2]))(\/)([1-2])\d{3}$/; RegExpHelper.DATE_KEYPRESS = /^[0-9\/]{1,10}$/; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const moment = moment_; // const DATE_REGEXP = /^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/; /** * INSTRUCCIONES DE USO * * Importar en módulo CustomToolsModule en tu módulo * * INPUTS * yourFormGroup: FormGroup * yourFormControlName: string (nombre de control de formulario) * placeholder (Opcional): string (texto a mostrar) * * EXAMPLE * <ngx-edu-datepicker [yourFormGroup]="nameOfYourFormGroup" [yourFormControlName]="'myDate'" [placeholder]="'Fecha'"></ngx-edu-datepicker> * * Obteniendo los valores * const rawValue = this.nameOfYourFormGroup.getRawValue(); * const phoneNumber = rawValue.countryCode + rawValue.areaCode + rawValue.localPhoneNumber; */ class NgxEduDatepickerComponent { constructor() { this.yourFormGroup = null; this.yourFormControlName = ""; this.placeholder = "Fecha"; this.hasProperties = false; this.dateKeypress = RegExpHelper.DATE_KEYPRESS; this.maxDate = null; } /** * @return {?} */ ngOnInit() { this.initialize(); } /** * @return {?} */ ngOnChanges() { // this.refresh(); } /** * @return {?} */ ngOnDestroy() { } /** * @return {?} */ initialize() { if (!this.yourFormGroup || !this.yourFormGroup.get(this.yourFormControlName)) { this.hasProperties = false; return; } this.hasProperties = true; /** @type {?} */ let formattedDate = ""; if (this.yourFormGroup.get(this.yourFormControlName).value) { /** @type {?} */ const date = moment(this.yourFormGroup.get(this.yourFormControlName).value); if (date.isValid()) { formattedDate = date.format("DD/MM/YYYY"); } } /** @type {?} */ let disabled = false; try { disabled = this.yourFormGroup.get(this.yourFormControlName).disabled; } catch (error) { // console.error( // "NgxEduDatepickerComponent > initialize > validators error", // error // ); } /** @type {?} */ let validators = null; try { validators = this.yourFormGroup .get(this.yourFormControlName) .validator((/** @type {?} */ ({}))); } catch (error) { // console.error( // "NgxEduDatepickerComponent > initialize > validators error", // error // ); } console.log("VALIDATORSSSSSSSSSSSSSSSSSSSSSSS", validators); /** @type {?} */ const formControl = validators && validators.required ? new FormControl({ value: formattedDate, disabled: disabled }, [ Validators.required, Validators.pattern(RegExpHelper.DATE_ES_AR), ]) : new FormControl({ value: formattedDate, disabled: disabled }, Validators.pattern(RegExpHelper.DATE_ES_AR)); this.yourFormGroup.addControl(`${this.yourFormControlName}DisplayDate`, formControl); this.yourFormGroup .get(`${this.yourFormControlName}DisplayDate`) .valueChanges.pipe(debounceTime(300), distinctUntilChanged()) .subscribe((/** * @param {?} value * @return {?} */ (value) => { if (value && this.yourFormGroup.get(`${this.yourFormControlName}DisplayDate`).valid) { console.log("NgxEduDatepickerComponent > initialize > Fecha válidaaaaaaa...."); /** @type {?} */ const date = moment(value, "DD/MM/YYYY"); if (date.isValid()) { this.yourFormGroup .get(this.yourFormControlName) .setValue(date.toDate()); } } if (!value) { this.yourFormGroup.get(this.yourFormControlName).setValue(null); } })); } /** * @return {?} */ open() { this.datePicker.open(); } /** * @param {?} $event * @return {?} */ onDateChange($event) { console.log("DateToolComponent > onDateChange > $event", $event); /** @type {?} */ const date = moment($event.value).format("DD/MM/YYYY"); console.log("DateToolComponent > onDateChange > date", date); this.yourFormGroup .get(`${this.yourFormControlName}DisplayDate`) .setValue(date); } /** * @return {?} */ refresh() { console.log("NgxEduDatepickerComponent > refresh"); if (this.yourFormGroup && this.yourFormGroup.get(this.yourFormControlName) && this.yourFormGroup.get(this.yourFormControlName).value && this.yourFormGroup.get(`${this.yourFormControlName}DisplayDate`)) { /** @type {?} */ const date = moment(this.yourFormGroup.get(this.yourFormControlName).value); console.log("NgxEduDatepickerComponent > refresh > date", date); if (date.isValid()) { /** @type {?} */ const formattedDate = date.format("DD/MM/YYYY"); console.log("NgxEduDatepickerComponent > refresh > formattedDate", formattedDate); this.yourFormGroup .get(`${this.yourFormControlName}DisplayDate`) .setValue(formattedDate); } } } } NgxEduDatepickerComponent.decorators = [ { type: Component, args: [{ selector: "ngx-edu-datepicker", template: "<div\r\n fxLayout=\"row\"\r\n fxLayoutAlign=\"start center\"\r\n class=\"w-100-p\"\r\n [formGroup]=\"yourFormGroup\"\r\n *ngIf=\"yourFormGroup && hasProperties\"\r\n>\r\n <div fxFlex>\r\n <mat-form-field fxFlex class=\"w-100\">\r\n <input\r\n matInput\r\n placeholder=\"{{ placeholder }}\"\r\n name=\"{{ yourFormControlName }}DisplayDate\"\r\n formControlName=\"{{ yourFormControlName }}DisplayDate\"\r\n [myRegExp]=\"dateKeypress\"\r\n />\r\n </mat-form-field>\r\n <mat-form-field [style.visibility]=\"'hidden'\" fxFlex=\"8px\">\r\n <input\r\n matInput\r\n placeholder=\"\"\r\n [matDatepicker]=\"picker\"\r\n [max]=\"maxDate\"\r\n class=\"w-8\"\r\n formControlName=\"{{ yourFormControlName }}\"\r\n (dateChange)=\"onDateChange($event)\"\r\n *ngIf=\"maxDate\"\r\n />\r\n <input\r\n matInput\r\n placeholder=\"\"\r\n [matDatepicker]=\"picker\"\r\n class=\"w-8\"\r\n formControlName=\"{{ yourFormControlName }}\"\r\n (dateChange)=\"onDateChange($event)\"\r\n *ngIf=\"!maxDate\"\r\n />\r\n <mat-datepicker #picker></mat-datepicker>\r\n </mat-form-field>\r\n </div>\r\n <div fxFlex=\"40px\" fxLayoutAlign=\"center center\">\r\n <button mat-icon-button aria-label=\"Date tool\" (click)=\"open()\">\r\n <mat-icon>date_range</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<div\r\n fxLayout=\"row\"\r\n fxLayoutAlign=\"start center\"\r\n class=\"w-100-p\"\r\n *ngIf=\"!yourFormGroup || !yourFormControlName\"\r\n>\r\n <span\r\n >Los par\u00E1metros de entrada [yourFormGroup] y [yourFormControlName] son\r\n requeridos.</span\r\n >\r\n</div>\r\n<div\r\n fxLayout=\"row\"\r\n fxLayoutAlign=\"start center\"\r\n class=\"w-100-p\"\r\n *ngIf=\"yourFormGroup && yourFormControlName && !hasProperties\"\r\n>\r\n <span\r\n >El par\u00E1metro de entrada [yourFormGroup] debe contener el control \"{{\r\n yourFormControlName\r\n }}\".</span\r\n >\r\n</div>\r\n", styles: [".w-100-p{width:100%}.w-8{width:8px}.w-100{width:100px}"] }] } ]; /** @nocollapse */ NgxEduDatepickerComponent.ctorParameters = () => []; NgxEduDatepickerComponent.propDecorators = { datePicker: [{ type: ViewChild, args: ["picker",] }], yourFormGroup: [{ type: Input }], yourFormControlName: [{ type: Input }], placeholder: [{ type: Input }], maxDate: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * INSTRUCCIONES DE USO * * Instalar: * npm install viewerjs --save * * Configurar en angular.json * en styles > "node_modules/viewerjs/dist/viewer.css" * en scripts > "node_modules/viewerjs/dist/viewer.js" * * Importar en módulo ImageToolsModule en tu módulo * * Crear la siguiente variable en tu componente para cargar las imagenes a mostrar en la galería -> images: ImageItem[] = []; * Cuando se realizen cambios en el array de imagenes, realizar la siguiente asignación para refrescar cambios -> this.images = [...this.images]; * * Agregar el siguiente código en donde quieras que se muestre la galería. Opcionalmente setear imagesHeight (por defecto 200px). * <ngx-edu-gallery [images]="images" [imagesHeight]="200"></ngx-edu-gallery> */ class NgxEduGalleryComponent { constructor() { this.id = v4(); this.gallery = null; this.images = []; this.imagesHeight = 200; this.defaultImageUrl = ""; this.galleryOptions = { showAlt: true, showRemoveImage: false, }; this.onRemove = new EventEmitter(); } /** * @return {?} */ ngOnInit() { } /** * @return {?} */ ngOnChanges() { console.log("NgxEduGalleryComponent > ngOnChanges > 1", this.images); if (this.images.length > 0) { console.log("NgxEduGalleryComponent > ngOnChanges > 2"); setTimeout((/** * @return {?} */ () => { console.log("NgxEduGalleryComponent > ngOnChanges > 3"); this.initialize(); }), 1000); } } /** * @return {?} */ ngOnDestroy() { console.log("NgxEduGalleryComponent > ngOnDestroy > 1", this.gallery); if (this.gallery) { console.log("NgxEduGalleryComponent > ngOnDestroy > 2"); this.gallery.destroy(); } } /** * @return {?} */ initialize() { console.log("NgxEduGalleryComponent > initialize > 1", this.gallery); if (this.gallery) { console.log("NgxEduGalleryComponent > initialize > 2"); this.gallery.destroy(); } /** @type {?} */ const ul = document.getElementById(this.id); console.log("NgxEduGalleryComponent > initialize > 3 > ul", ul); if (!ul) return; this.gallery = new Viewer(ul); console.log("NgxEduGalleryComponent > initialize > 3", this.gallery); } /** * @param {?} event * @return {?} */ onError(event) { if (!event) return; event.target.src = this.defaultImageUrl; } /** * @return {?} */ show() { console.log("NgxEduGalleryComponent > show > 1"); if (!this.gallery) return; console.log("NgxEduGalleryComponent > show > 2"); this.gallery.show(); } /** * @param {?} index * @return {?} */ view(index) { console.log("NgxEduGalleryComponent > view > 1", this.gallery, index); if (!this.gallery || index < 0) return; console.log("NgxEduGalleryComponent > view > 2"); this.gallery.view(index); } /** * @param {?} zoom * @return {?} */ zoom(zoom) { if (!this.gallery) return; this.gallery.zoomTo(zoom); } /** * @param {?} image * @param {?} position * @return {?} */ remove(image, position) { this.onRemove.emit({ image: image, position: position, }); } } NgxEduGalleryComponent.decorators = [ { type: Component, args: [{ selector: "ngx-edu-gallery", template: "<ul [id]=\"id\" class=\"ngx-edu-gallery\">\r\n <li *ngFor=\"let image of images; let i = index\">\r\n <mat-card>\r\n <div class=\"image-container\" *ngIf=\"defaultImageUrl\">\r\n <mat-icon\r\n class=\"remove-image\"\r\n matTooltip=\"Quitar\"\r\n (click)=\"remove(image, i)\"\r\n *ngIf=\"galleryOptions.showRemoveImage\"\r\n >cancel</mat-icon\r\n >\r\n <img\r\n src=\"{{ image.url ? image.url : '' }}\"\r\n alt=\"{{ image.alt ? image.alt : '' }}\"\r\n (error)=\"onError($event)\"\r\n [style.height.px]=\"imagesHeight\"\r\n />\r\n <div class=\"description\" *ngIf=\"galleryOptions.showAlt\">\r\n {{ image.alt ? image.alt : \"\" }}\r\n </div>\r\n </div>\r\n <div\r\n fxLayout=\"row\"\r\n fxLayoutAlign=\"center center\"\r\n *ngIf=\"!defaultImageUrl\"\r\n >\r\n <span>El par\u00E1metro de entrada [defaultImageUrl] es requerido.</span>\r\n </div>\r\n </mat-card>\r\n </li>\r\n</ul>\r\n", styles: [".ngx-edu-gallery{list-style-type:none;margin:0;padding:0}.ngx-edu-gallery li{display:inline-block;margin-right:8px;margin-bottom:8px;padding:0}.ngx-edu-gallery li mat-card{max-width:unset;min-width:unset}.ngx-edu-gallery li mat-card .image-container{position:relative}.ngx-edu-gallery li mat-card .image-container .remove-image{position:absolute;top:-12px;right:-12px;cursor:pointer}.ngx-edu-gallery li mat-card .image-container img{cursor:pointer}.ngx-edu-gallery li mat-card .image-container .description{position:absolute;background-color:#000;opacity:.8;color:#fff!important;font-size:20px;padding:8px!important;width:100%!important;left:0;bottom:0}"] }] } ]; /** @nocollapse */ NgxEduGalleryComponent.ctorParameters = () => []; NgxEduGalleryComponent.propDecorators = { images: [{ type: Input }], imagesHeight: [{ type: Input }], defaultImageUrl: [{ type: Input }], galleryOptions: [{ type: Input }], onRemove: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * INSTRUCCIONES DE USO * * Importar en módulo ImageToolsModule en tu módulo * * EXAMPLE * * <div #imageCanvas></div> * * \@ViewChild('imageCanvas') public imageCanvas: ElementRef; * confirmDialogRef: any; * openCropperDialog() { * const config: MatDialogConfig = { * width: '50%', * disableClose: true, * panelClass: 'ea-dialog', * data: { * imageUrl: 'assets/images/default/company.jpg' * } * }; * this.confirmDialogRef = this.dialog.open(NgxEduCropperDialogComponent, config); * this.confirmDialogRef.afterClosed().subscribe((result: NgxEduCropperResponse | boolean) => { * if (!result) return; * this.imageCanvas.nativeElement.appendChild((<NgxEduCropperResponse>result).canvas); * }); * } */ class NgxEduCropperDialogComponent { /** * @param {?} data * @param {?} _dialogRef */ constructor(data, _dialogRef) { this.data = data; this._dialogRef = _dialogRef; this.imageUrl = data.imageUrl; this.title = data.title ? data.title : 'Recorte de imagen'; this.accept = data.accept ? data.accept : 'Aceptar'; this.cancel = data.cancel ? data.cancel : 'Cancelar'; this.close = data.close ? data.close : 'Cerrar'; this.ngxEduCropperResponse = null; } /** * @return {?} */ ngOnInit() { } /** * @return {?} */ ngOnChanges() { } /** * @return {?} */ ngOnDestroy() { } /** * @param {?} ngxEduCropperResponse * @return {?} */ onChange(ngxEduCropperResponse) { this.ngxEduCropperResponse = ngxEduCropperResponse; } /** * @return {?} */ save() { this._dialogRef.close(this.ngxEduCropperResponse); } } NgxEduCropperDialogComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-edu-cropper-dialog', template: "<div class=\"ngx-edu-header\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\">\r\n <span>{{title}}</span>\r\n <button mat-icon-button aria-label=\"close\" matTooltip=\"{{close}}\" [mat-dialog-close]=\"false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n</div>\r\n<ngx-edu-cropper [imageUrl]=\"imageUrl\" (onChange)=\"onChange($event)\"></ngx-edu-cropper>\r\n<div class=\"ngx-edu-footer\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\r\n <button mat-raised-button color=\"accent\" (click)=\"save()\" [disabled]=\"!ngxEduCropperResponse\">{{accept}}</button>\r\n <button mat-raised-button color=\"warn\" class=\"ngx-edu-cancel\"\r\n [mat-dialog-close]=\"false\">{{cancel}}</button>\r\n</div>", styles: [".ngx-edu-footer,.ngx-edu-header{padding:4px 16px}.ngx-edu-cancel{margin-left:12px}"] }] } ]; /** @nocollapse */ NgxEduCropperDialogComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }, { type: MatDialogRef } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Ir a la documentaciones oficial para ver todas las opciones disponibles para cada atributo. * https://github.com/fengyuanchen/cropperjs/blob/master/README.md#options */ class NgxEduCropperOptions { // Function constructor() { this.viewMode = 0; this.dragMode = 'crop'; this.initialAspectRatio = NaN; this.aspectRatio = NaN; this.data = null; this.preview = ''; this.responsive = true; this.restore = true; this.checkCrossOrigin = true; this.checkOrientation = true; this.modal = true; this.guides = true; this.center = true; this.highlight = true; this.background = true; this.autoCrop = true; this.autoCropArea = 0.8; this.movable = true; this.rotatable = true; this.scalable = true; this.zoomable = true; this.zoomOnTouch = true; this.zoomOnWheel = true; this.wheelZoomRatio = 0.1; this.cropBoxMovable = true; this.cropBoxResizable = true; this.toggleDragModeOnDblclick = true; this.minContainerWidth = 200; this.minContainerHeight = 100; this.minCanvasWidth = 0; this.minCanvasHeight = 0; this.minCropBoxWidth = 0; this.minCropBoxHeight = 0; this.ready = null; this.cropstart = null; this.cropmove = null; this.cropend = null; this.crop = null; this.zoom = null; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * INSTRUCCIONES DE USO * * Instalar: * npm install angular-cropperjs --save * npm install cropperjs --save * * Configurar en angular.json * en styles > "node_modules/cropperjs/dist/cropper.css" * en scripts > "node_modules/cropperjs/dist/cropper.js" * * Importar en módulo ImageToolsModule en tu módulo * * INPUTS * imageUrl: Url de la imagen a recortar. * minContainerHeight: Alto mínimo del contenedor (No puede ser inferior a 325). Valor por defecto: 325. * * OUTPUTS * onChange(EventEmitter<ImageCropperToolResponse>): Cuando se aplican los cambios devuelve un canvas * con la imagen recortada para mostrar dentro de un div y blob que se puede utilizar para subir el archivo * utilizando FormData, cuando se realiza algun cambio devuelve null hasta que se apliquen nuevamente los cambios. * * EXAMPLE * <ngx-edu-cropper [imageUrl]="imageUrl" [minContainerHeight]="325" (onChange)="onChange($event)"></ngx-edu-cropper> */ class NgxEduCropperComponent { constructor() { this.ngxEduCropperOptions = new NgxEduCropperOptions(); this.imageUrl = ''; this.minContainerHeight = 325; this.onChange = new EventEmitter(); this.setImageCropperToolEvents(); } /** * @return {?} */ ngOnInit() { if (this.minContainerHeight < 325) { this.minContainerHeight = 325; } this.ngxEduCropperOptions.minContainerHeight = this.minContainerHeight; } /** * @return {?} */ ngOnChanges() { } /** * @return {?} */ ngOnDestroy() { } /** * @return {?} */ setImageCropperToolEvents() { this.ngxEduCropperOptions.cropstart = (/** * @param {?} e * @return {?} */ (e) => { this.onChange.emit(null); }); this.ngxEduCropperOptions.cropmove = (/** * @param {?} e * @return {?} */ (e) => { this.onChange.emit(null); }); this.ngxEduCropperOptions.cropend = (/** * @param {?} e * @return {?} */ (e) => { this.onChange.emit(null); }); this.ngxEduCropperOptions.zoom = (/** * @param {?} e * @return {?} */ (e) => { this.onChange.emit(null); }); } /** * @param {?} dragMode * @return {?} */ setDragMode(dragMode) { /** @type {?} */ const cropperDragMode = (/** @type {?} */ (dragMode)); this.angularCropper.cropper.setDragMode(cropperDragMode); } /** * @param {?} ratio * @return {?} */ zoom(ratio) { this.angularCropper.cropper.zoom(ratio); this.onChange.emit(null); } /** * @param {?} degree * @return {?} */ rotate(degree) { this.angularCropper.cropper.rotate(degree); this.onChange.emit(null); } /** * @param {?} offsetX * @param {?} offsetY * @return {?} */ move(offsetX, offsetY) { this.angularCropper.cropper.move(offsetX, offsetY); this.onChange.emit(null); } /** * @return {?} */ disable() { this.angularCropper.cropper.disable(); this.onChange.emit(null); } /** * @return {?} */ enable() { this.angularCropper.cropper.enable(); this.onChange.emit(null); } /** * @return {?} */ reset() { this.angularCropper.cropper.reset(); this.onChange.emit(null); } /** * @return {?} */ clear() { this.angularCropper.cropper.clear(); this.onChange.emit(null); } /** * @return {?} */ crop() { this.angularCropper.cropper.crop(); /** @type {?} */ const canvas = this.angularCropper.cropper.getCroppedCanvas(); canvas.toBlob((/** * @param {?} blob * @return {?} */ (blob) => { console.log('NgxEduCropperComponent > crop > blob', blob); this.onChange.emit({ canvas: canvas, blob: blob }); })); } } NgxEduCropperComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-edu-cropper', template: "<div fxLayout=\"row\">\r\n <div fxFlex=\"80px\">\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Modo mover\" (click)=\"setDragMode('move')\">\r\n <mat-icon>open_with</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Modo recorte\" (click)=\"setDragMode('crop')\">\r\n <mat-icon>crop</mat-icon>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Acercarse\" (click)=\"zoom(0.1)\">\r\n <mat-icon>zoom_in</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Alejarse\" (click)=\"zoom(-0.1)\">\r\n <mat-icon>zoom_out</mat-icon>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Rotar a la izquierda\" (click)=\"rotate(-90)\">\r\n <mat-icon>rotate_left</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Rotar a la derecha\" (click)=\"rotate(90)\">\r\n <mat-icon>rotate_right</mat-icon>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Mover a la izquierda\" (click)=\"move(-10, 0)\">\r\n <mat-icon>arrow_back</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Mover a la derecha\" (click)=\"move(10, 0)\">\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Mover arriba\" (click)=\"move(0, -10)\">\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Mover abajo\" (click)=\"move(0, 10)\">\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Bloquear\" (click)=\"disable()\">\r\n <mat-icon>lock</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Desbloquear\" (click)=\"enable()\">\r\n <mat-icon>lock_open</mat-icon>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-icon-button aria-label=\"rotate left\" matTooltip=\"Reiniciar\" (click)=\"reset()\">\r\n <mat-icon>cached</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Limpiar\" (click)=\"clear()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n <button mat-icon-button aria-label=\"rotate right\" matTooltip=\"Aplicar cambios\" (click)=\"crop()\">\r\n <mat-icon>check</mat-icon>\r\n </button>\r\n </div>\r\n <div fxFlex>\r\n <angular-cropper #angularCropper [cropperOptions]=\"ngxEduCropperOptions\" [imageUrl]=\"imageUrl\">\r\n </angular-cropper>\r\n </div>\r\n</div>", styles: [""] }] } ]; /** @nocollapse */ NgxEduCropperComponent.ctorParameters = () => []; NgxEduCropperComponent.propDecorators = { angularCropper: [{ type: ViewChild, args: ['angularCropper',] }], imageUrl: [{ type: Input }], minContainerHeight: [{ type: Input }], onChange: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class PhoneNumberOptions { constructor() { this.disabled = false; this.countryPlaceholder = 'País'; this.areaCodePlaceholder = 'Código'; this.prefix = '15'; this.numberPlaceholder = 'Número'; } /** * @return {?} */ static getDefaultOptions() { return { disabled: false, countryPlaceholder: 'País', areaCodePlaceholder: 'Código', prefix: '15', numberPlaceholder: 'Número' }; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * INSTRUCCIONES DE USO * * Agregar las imagenes de las banderas a utilizar en la siguiente carpeta: * assets/images/flags * * Importar en módulo CustomToolsModule en tu módulo * * INPUTS * yourFormGroup: FormGroup que utilizas tu formulario (se requiere agregar los controles "countryCode", "areaCode" y "localPhoneNumber"). * countries (Opcional): Country[] (listado de paises a ulitizar, por defecto Argentina y Brasil). * selectedCountry (Opcional): Country seleccionado por defecto. * options (Opcional): PhoneNumberToolOptions (Opciones de configuración del componente). * * EXAMPLE * <ngx-edu-phone-number [yourFormGroup]="nameOfYourFormGroup"></ngx-edu-phone-number> * * Ejemplo de controles en tu FormGroup * 'countryCode': [this.data.driver.countryCode, [Validators.required]], * 'areaCode': [this.data.driver.areaCode, [Validators.required, Validators.minLength(2), Validators.maxLength(4), Validators.pattern(RegExpHelper.AREA_CODE)]], * 'localPhoneNumber': [this.data.driver.localPhoneNumber, [Validators.required, Validators.minLength(6), Validators.maxLength(9), Validators.pattern(RegExpHelper.LOCAL_PHONE_NUMBER)]], * * Obteniendo los valores * const rawValue = this.nameOfYourFormGroup.getRawValue(); * const phoneNumber = rawValue.countryCode + rawValue.areaCode + rawValue.localPhoneNumber; */ class NgxEduPhoneNumberComponent { constructor() { this.yourFormGroup = null; this.countryCodeFormControlName = ''; this.areaCodeFormControlName = ''; this.localPhoneNumberFormControlName = ''; this.countries = []; this.selectedCountry = null; this.defaultCountry = null; this.options = new PhoneNumberOptions(); this.hasProperties = false; this.onlyNumberMax4 = RegExpHelper.ONLY_NUMBER_MAX_4; this.onlyNumberMax10 = RegExpHelper.ONLY_NUMBER_MAX_10; } /** * @return {?} */ ngOnInit() { this.initialize(); } /** * @return {?} */ ngOnChanges() { this.refreshOptions(); } /** * @return {?} */ ngOnDestroy() { } /** * @return {?} */ initialize() { if (!this.yourFormGroup || !this.yourFormGroup.get(this.countryCodeFormControlName) || !this.yourFormGroup.get(this.areaCodeFormControlName) || !this.yourFormGroup.get(this.localPhoneNumberFormControlName)) { this.hasProperties = false; return; } this.hasProperties = true; if (this.yourFormGroup.get(this.countryCodeFormControlName).value) { /** @type {?} */ const country = this.countries.find((/** * @param {?} c * @return {?} */ c => c.code == this.yourFormGroup.get(this.countryCodeFormControlName).value)); this.selectedCountry = country ? country : null; } if (!this.selectedCountry) { this.selectedCountry = this.defaultCountry; } this.yourFormGroup.get(this.countryCodeFormControlName).setValue(this.selectedCountry.code); } /** * @return {?} */ refreshOptions() { /** @type {?} */ const defaultOptions = PhoneNumberOptions.getDefaultOptions(); if (!this.options) { this.options = defaultOptions; } if (this.options.disabled == null || this.options.disabled == undefined) { this.options.disabled = defaultOptions.disabled; } if (!this.options.countryPlaceholder) { this.options.countryPlaceholder = defaultOptions.countryPlaceholder; } if (!this.options.areaCodePlaceholder) { this.options.areaCodePlaceholder = defaultOptions.areaCodePlaceholder; } if (!this.options.prefix) { this.options.prefix = defaultOptions.prefix; } if (!this.options.numberPlaceholder) { this.options.numberPlaceholder = defaultOptions.numberPlaceholder; } } /** * @param {?} country * @return {?} */ setSelectedCountry(country) { this.selectedCountry = country; if (!this.yourFormGroup || !this.yourFormGroup.get(this.countryCodeFormControlName)) return; this.yourFormGroup.get(this.countryCodeFormControlName).setValue(this.selectedCountry.code); } } NgxEduPhoneNumberComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-edu-phone-number', template: "<div fxLayout=\"row\" fxLayoutAlign=\"start center\" [formGroup]=\"yourFormGroup\" *ngIf=\"yourFormGroup && countryCodeFormControlName && areaCodeFormControlName && localPhoneNumberFormControlName && countries.length > 0 && defaultCountry && hasProperties\">\r\n <div>\r\n <button mat-button fxHide fxShow.gt-xs [matMenuTriggerFor]=\"countriesMenu\" [disabled]=\"options.disabled\">\r\n <div fxLayout=\"row\" fxLayoutAlign=\"center center\" *ngIf=\"selectedCountry\">\r\n <img class=\"flag\" [src]=\"selectedCountry.icon\">\r\n <span hidden=\"true\" class=\"iso text-uppercase\">+{{selectedCountry.code}}</span>\r\n </div>\r\n <div fxLayout=\"row\" fxLayoutAlign=\"center center\" *ngIf=\"!selectedCountry\">\r\n <span>{{options.countryPlaceholder}}</span>\r\n </div>\r\n </button>\r\n <mat-menu #countriesMenu=\"matMenu\" [overlapTrigger]=\"false\">\r\n <button mat-menu-item *ngFor=\"let country of countries\" (click)=\"setSelectedCountry(country)\">\r\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\r\n <img class=\"flag\" [src]=\"country.icon\">\r\n <span class=\"iso\">{{country.name}}</span>\r\n </div>\r\n </button>\r\n </mat-menu>\r\n </div>\r\n <mat-form-field fxFlex=\"25\">\r\n <input matInput placeholder=\"{{options.areaCodePlaceholder}}\" autocomplete=\"off\" [myRegExp]=\"onlyNumberMax4\"\r\n formControlName=\"{{areaCodeFormControlName}}\">\r\n </mat-form-field>\r\n <span class=\"prefix\" fxLayoutGap=\"12px\">{{options.prefix}}</span>\r\n <mat-form-field fxFlex=\"40\">\r\n <input matInput placeholder=\"{{options.numberPlaceholder}}\" formControlName=\"{{localPhoneNumberFormControlName}}\" [myRegExp]=\"onlyNumberMax10\">\r\n </mat-form-field>\r\n</div>\r\n<div fxLayout=\"row\" fxLayoutAlign=\"start center\" *ngIf=\"!yourFormGroup || !countryCodeFormControlName || !areaCodeFormControlName || !localPhoneNumberFormControlName || countries.length == 0 || !defaultCountry\">\r\n <span>Los par\u00E1metros de entrada [yourFormGroup], [countryCodeFormControlName], [areaCodeFormControlName], [localPhoneNumberFormControlName], [countries] y [defaultCountry] son requeridos.</span>\r\n</div>\r\n<div fxLayout=\"row\" fxLayoutAlign=\"start center\" *ngIf=\"yourFormGroup && countryCodeFormControlName && areaCodeFormControlName && localPhoneNumberFormControlName && countries.length > 0 && defaultCountry && !hasProperties\">\r\n <span>El par\u00E1metro de entrada [yourFormGroup] debe contener los controles \"{{countryCodeFormControlName}}\", \"{{areaCodeFormControlName}}\" y \"{{localPhoneNumberFormControlName}}\".</span>\r\n</div>", styles: [".flag{max-width:100%;height:auto;vertical-align:top;border:none}.iso{margin-left:4px}.prefix{margin-left:8px;margin-right:8px}"] }] } ]; /** @nocollapse */ NgxEduPhoneNumberComponent.ctorParameters = () => []; NgxEduPhoneNumberComponent.propDecorators = { yourFormGroup: [{ type: Input }], countryCodeFormControlName: [{ type: Input }], areaCodeFormControlName: [{ type: Input }], localPhoneNumberFormControlName: [{ type: Input }], countries: [{ type: Input }], selectedCountry: [{ type: Input }], defaultCountry: [{ type: Input }], options: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgxEduSelectComponent { constructor() { this.yourFormGroup = null; this.multiple = false; this.yourFormControlName = ''; this.placeholder = ''; this.filterPlaceholder = 'Buscar...'; this.selectAnOption = ''; this.options = []; this.displayOption = ''; this.hasFormControls = false; this.filteredOptions = []; this.compareWith = null; this.onChange = new EventEmitter(); } /** * @return {?} */ ngOnInit() { this.initialize(); } /** * @return {?} */ ngOnChanges() { this.filteredOptions = this.options; if (this.yourFormGroup && this.yourFormGroup.get(`${this.yourFormControlName}Filter`)) { this.yourFormGroup.get(`${this.yourFormControlName}Filter`).setValue(this.yourFormGroup.get(`${this.yourFormControlName}Filter`).value); } } /** * @return {?} */ ngOnDestroy() { } /** * @return {?} */ initialize() { if (!this.yourFormGroup || !this.yourFormGroup.get(this.yourFormControlName)) { this.hasFormControls = false; return; } this.hasFormControls = true; /** @type {?} */ const formControl = new FormControl(''); this.yourFormGroup.addControl(`${this.yourFormControlName}Filter`, formControl); this.yourFormGroup.get(`${this.yourFormControlName}Filter`).valueChanges.pipe(debounceTime(300), distinctUntilChanged()).subscribe((/** * @param {?} value * @return {?} */ value => { if (value) { this.filter(value); } else { this.filteredOptions = this.options; } })); this.filteredOptions = this.options; console.log('NgxEduSelectComponent > initialize > value', this.yourFormGroup.get(this.yourFormControlName).value); } /** * @param {?} v1 * @param {?} v2 * @return {?} */ compareFn(v1, v2) { // console.log('v1', v1); // console.log('v2', v2); // console.log('this.idOption', this.idOption); // console.log('v1[this.idOption]', v1[this.idOption]); // console.log('v2[this.idOption]', v2[this.idOption]); // console.log('v1 === v2', v1 === v2); // console.log('compareFn', v1 && v2 ? v1[this.idOption] === v2[this.idOption] : v1 === v2); return v1 && v2 ? v1['id'] === v2['id'] : v1 === v2; } /** * @param {?} value * @return {?} */ filter(value) { /** @type {?} */ let filteredOptions = []; for (const o of this.options) { if (typeof (o) == 'string') { if (o.toLowerCase().indexOf(value.toLowerCase()) >= 0) { filteredOptions.unshift(o); } else { filteredOptions.push(o); } continue; } if (typeof (o) == 'object') { /** @type {?} */ let result = false; for (const key in o) { if (o[key] && typeof (o[key]) == 'string') { result = o[key].toString().toLowerCase().indexOf(value.toLowerCase()) >= 0; } if (result) { break; } } if (result) { filteredOptions.unshift(o); } else { filteredOptions.push(o); } continue; } filteredOptions.push(o); } this.filteredOptions = filteredOptions; // this.filteredOptions = this.options.filter(o => { // if (typeof(o) == 'string') { // return o.toLowerCase().indexOf(value.toLowerCase()) >= 0; // } // let result = false; // if (typeof(o) == 'object') { // for (const key in o) { // result = o[key].toString().toLowerCase().indexOf(value.toLowerCase()) >= 0; // if (result) { // break; // } // } // } // return result; // }); } /** * @param {?} $event * @return {?} */ onSelectionChange($event) { console.log('NgxEduSelectComponent > onSelectionChange > $event', $event); this.onChange.emit($event); if (this.multiple) { this.filterInput.nativeElement.focus(); } } /** * @param {?} $event * @return {?} */ onOpenedChange($event) { if ($event) { this.yourFormGroup.get(`${this.yourFormControlName}Filter`).setValue(''); this.filterInput.nativeElement.focus(); } } } NgxEduSelectComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-edu-select', template: "<div\r\n [formGroup]=\"yourFormGroup\"\r\n *ngIf=\"\r\n yourFormGroup &&\r\n yourFormControlName &&\r\n options.length > 0 &&\r\n displayOption &&\r\n compareWith &&\r\n hasFormControls\r\n \"\r\n>\r\n <mat-form-field class=\"w-100-p\">\r\n <mat-select\r\n *ngIf=\"!multiple\"\r\n formControlName=\"{{ yourFormControlName }}\"\r\n placeholder=\"{{ placeholder }}\"\r\n [compareWith]=\"compareWith\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n (openedChange)=\"onOpenedChange($event)\"\r\n >\r\n <input\r\n #filterInput\r\n matInput\r\n class=\"filter\"\r\n placeholder=\"{{ filterPlaceholder }}\"\r\n formControlName=\"{{ yourFormControlName }}Filter\"\r\n />\r\n <mat-option *ngIf=\"selectAnOption\">{{ selectAnOption }}</mat-option>\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n {{\r\n option[displayOption]\r\n ? option[displayOption]\r\n : \"Display option not exists.\"\r\n }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-select\r\n *ngIf=\"multiple\"\r\n formControlName=\"{{ yourFormControlName }}\"\r\n placeholder=\"{{ placeholder }}\"\r\n [compareWith]=\"compareWith\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n (openedChange)=\"onOpenedChange($event)\"\r\n multiple\r\n >\r\n <input\r\n #filterInput\r\n matInput\r\n class=\"filter\"\r\n placeholder=\"{{ filterPlaceholder }}\"\r\n formControlName=\"{{ yourFormControlName }}Filter\"\r\n />\r\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option\">\r\n {{\r\n option[displayOption]\r\n ? option[displayOption]\r\n : \"Display option not exists.\"\r\n }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>\r\n<div\r\n fxLayoutAlign=\"center center\"\r\n *ngIf=\"\r\n !yourFormGroup || !yourFormControlName || !displayOption || !compareWith\r\n \"\r\n>\r\n <span\r\n >Los par\u00E1metros de entrada [yourFormGroup], [yourFormControlName],\r\n [displayOption] y [compareWith] son requeridos.</span\r\n >\r\n</div>\r\n<div\r\n fxLayoutAlign=\"center center\"\r\n *ngIf=\"\r\n yourFormGroup &&\r\n yourFormControlName &&\r\n options.length > 0 &&\r\n displayOption &&\r\n compareWith &&\r\n !hasFormControls\r\n \"\r\n>\r\n <span\r\n >El par\u00E1metro de entrada [yourFormGroup] debe contener el control \"{{\r\n yourFormControlName\r\n }}\".</span\r\n >\r\n</div>\r\n<div\r\n fxLayoutAlign=\"center center\"\r\n *ngIf=\"\r\n yourFormGroup &&\r\n yourFormControlName &&\r\n options.length <= 0 &&\r\n displayOption &&\r\n compareWith &&\r\n hasFormControls\r\n \"\r\n>\r\n <span\r\n >El control \"{{ yourFormControlName }}\" debe contener al menos una\r\n opci\u00F3n.</span\r\n >\r\n</div>\r\n", styles: [".w-100-p{width:100%}.filter{padding:8px 16px;border-bottom:1px solid}"] }] } ]; /** @nocollapse */ NgxEduSelectComponent.ctorParameters = () => []; NgxEduSelectComponent.propDecorators = { filterInput: [{ type: ViewChild, args: ['filterInput',] }], yourFormGroup: [{ type: Input }], multiple: [{ type: Input }], yourFormControlName: [{ type: Input }], placeholder: [{ type: Input }], filterPlaceholder: [{ type: Input }], selectAnOption: [{ type: Input }], options: [{ type: Input }], displayOption: [{ type: Input }], compareWith: [{ type: Input }], onChange: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgxEduFromToComponent { constructor() { } /** * @return {?} */ ngOnInit() { } /** * @return {?} */ ngOnChanges() { } /** * @return {?} */ ngOnDestroy() { } } NgxEduFromToComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-edu-from-to', template: "<!--component html goes here -->\r\n", styles: [""] }] } ]; /** @nocollapse */ NgxEduFromToComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MyRegExpDirective { /** * @param {?} elementRef */ constructor(elementRef) { this.TAG = 'MyRegExpDirective'; this.elementRef = elementRef; } /** * @param {?} event * @return {?} */ onKeyPress(event) { /** @type {?} */ const e = (/** @type {?} */ (event)); // conso