ronaldkwandy

Untitled

May 14th, 2019
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, forwardRef } from '@angular/core';
  2. import { NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlValueAccessor, Validator, AbstractControl } from '@angular/forms';
  3.  
  4. declare var $: any;
  5. import '../../../../node_modules/jexcel/dist/js/jexcel';
  6. import '../../../../node_modules/jexcel/dist/js/jquery.jexcel';
  7. import '../../../../node_modules/jexcel/dist/js/jquery.jcalendar';
  8. import '../../../../node_modules/jexcel/dist/js/jquery.jdropdown';
  9. import '../../../../node_modules/jexcel/dist/js/jexcel-formulas';
  10. import '../../../../node_modules/jexcel/dist/js/jquery.csv.min';
  11.  
  12. import { DateFormatPipe } from '../pipe/date-format.pipe';
  13. import { JExcelColumn, JExcelError, JExcel, JExcelOptions } from './jexcel';
  14. import { ObjectHelper } from '../helper/object-helper';
  15.  
  16. import { TranslateService } from '@ngx-translate/core';
  17.  
  18. import * as lodash from 'lodash';
  19.  
  20. export const JEXCEL_CONTROL_VALUE_ACCESSOR: any = {
  21.   provide: NG_VALUE_ACCESSOR,
  22.   useExisting: forwardRef(() => JExcelComponent),
  23.   multi: true
  24. };
  25.  
  26. export const JEXCEL_INPUT_VALIDATORS_ACCESSOR: any = {
  27.   provide: NG_VALIDATORS,
  28.   useExisting: forwardRef(() => JExcelComponent),
  29.   multi: true,
  30. };
  31.  
  32. @Component({
  33.   selector: 'app-jexcel',
  34.   templateUrl: './jexcel.component.html',
  35.   providers: [
  36.     JEXCEL_CONTROL_VALUE_ACCESSOR,
  37.     JEXCEL_INPUT_VALIDATORS_ACCESSOR
  38.   ]
  39. })
  40. export class JExcelComponent implements ControlValueAccessor, Validator, OnDestroy {
  41.  
  42.   @Input()
  43.   public get id(): string { return this._id; }
  44.   public set id(id: string) { this._id = id; }
  45.   private _id: string;
  46.  
  47.   @Input()
  48.   public get columns(): JExcelColumn[] { return this._columns; }
  49.   public set columns(columns: JExcelColumn[]) { this._columns = columns; }
  50.   public _columns: JExcelColumn[] = null;
  51.  
  52.   @Input()
  53.   public get options(): JExcelOptions { return this.options; }
  54.   public set options(options: JExcelOptions) { this._options = options; }
  55.   public _options: JExcelOptions = {};
  56.  
  57.   public data: any[] = [];
  58.   public errors: JExcelError[] = [];
  59.   public onchange: EventEmitter<any[]>;
  60.   public translate: boolean = true;
  61.  
  62.   private configuration: JExcel;
  63.   private dateFormatPipe: DateFormatPipe;
  64.   private defaultColumnWidth: number = 100;
  65.   private defaultColumnType: any = { type: 'text' };
  66.   private onchangeEvent: Function;
  67.  
  68.   constructor(
  69.     private translateService: TranslateService
  70.   ) {
  71.     this.id = 'app-jexcel';
  72.     this.dateFormatPipe = new DateFormatPipe();
  73.  
  74.     this.options = {
  75.       editable: true,
  76.       columnResize: true,
  77.       allowInsertRow: false,
  78.       allowManualInsertRow: false,
  79.       allowInsertColumn: false,
  80.       allowManualInsertColumn: false,
  81.       allowDeleteRow: false,
  82.       allowDeleteColumn: false,
  83.       allowComments: false,
  84.       toolbar: false,
  85.       onchange: undefined
  86.     };
  87.  
  88.     this.configuration = {
  89.       data: [],
  90.       colHeaders: [],
  91.       colWidths: [],
  92.       columns: []
  93.     };
  94.  
  95.     this.onchange = new EventEmitter();
  96.  
  97.     this.onchangeEvent = (obj, cell, val) => {
  98.       this.getValues();
  99.       this.onchange.emit(this.data);
  100.     };
  101.   }
  102.  
  103.   ngOnDestroy() {
  104.     this.getInstance().jexcel('destroy');
  105.   }
  106.  
  107.   public propagateChange = (_: any) => { /* do nothing */ };
  108.   public propagateTouch = (_: any) => { /* do nothing */ };
  109.  
  110.   public writeValue(value: any): void {
  111.     this.data = value;
  112.   }
  113.  
  114.   public registerOnChange(fn: (_: any) => {}): void {
  115.     this.propagateChange = fn;
  116.   }
  117.  
  118.   public registerOnTouched(fn: (_: any) => {}): void {
  119.     this.propagateTouch = fn;
  120.   }
  121.  
  122.   public setDisabledState(isDisabled: boolean): void { }
  123.  
  124.   public setSpreadsheet(columns: JExcelColumn[], options: JExcelOptions, translate: boolean = true) {
  125.     this.errors = [];
  126.     this.columns = lodash.cloneDeep(columns);
  127.     this.translate = translate;
  128.     this.options = lodash.cloneDeep(options);
  129.  
  130.     if (ObjectHelper.isEmpty(this.columns)) {
  131.       this.errors.push({ code: 'jexcel.columns.invalid' });
  132.       console.error('JExcel errors : ', this.errors);
  133.     }
  134.  
  135.     if (this.errors.length === 0) {
  136.       this.initConfiguration();
  137.       this.getInstance().jexcel(this.configuration);
  138.     }
  139.   }
  140.  
  141.   private getInstance() {
  142.     return $('#' + this.id);
  143.   }
  144.  
  145.   private initConfiguration() {
  146.     this.configuration.colAlignments = [];
  147.     this.configuration.colHeaders = [];
  148.     this.configuration.colWidths = [];
  149.     this.configuration.columns = [];
  150.  
  151.     let index = 0;
  152.     for (const column of this.columns) {
  153.       if (ObjectHelper.isEmpty(column)) {
  154.         this.errors.push({ code: 'jexcel.column.required', args: [(index + 1)] });
  155.         console.error('JExcel errors : ', this.errors);
  156.         break;
  157.       }
  158.  
  159.       // Header text
  160.       if (ObjectHelper.isEmpty(column.headerText)) {
  161.         // TODO : set content alert LOL!
  162.         this.errors.push({ code: 'jexcel.header.required', args: [(index + 1)] });
  163.         console.error('JExcel errors : ', this.errors);
  164.         break;
  165.       } else {
  166.         if (this.translate) {
  167.           this.translateService.get(column.headerText).subscribe(
  168.             (translated) => {
  169.               this.configuration.colHeaders.push(translated);
  170.             }
  171.           );
  172.         } else {
  173.           this.configuration.colHeaders.push(column.headerText);
  174.         }
  175.       }
  176.  
  177.       // Width
  178.       if (ObjectHelper.isEmpty(column.width)) {
  179.         this.configuration.colWidths.push(this.defaultColumnWidth);
  180.       } else {
  181.         this.configuration.colWidths.push(column.width);
  182.       }
  183.  
  184.       // Alignment
  185.       if (ObjectHelper.isEmpty(column.alignment)) {
  186.         this.configuration.colAlignments.push('left');
  187.       } else {
  188.         this.configuration.colAlignments.push(column.alignment);
  189.       }
  190.  
  191.       // Column
  192.       const validColumn = lodash.cloneDeep(column);
  193.       if (ObjectHelper.isEmpty(validColumn.type)) {
  194.         validColumn.type = this.defaultColumnType;
  195.       }
  196.       if (ObjectHelper.isEmpty(validColumn.readOnly)) {
  197.         validColumn.readOnly = false;
  198.       }
  199.       if (validColumn.type === 'dropdown' || validColumn.type === 'autocomplete') {
  200.         validColumn.source.map(item => {
  201.           if (typeof item === 'object') {
  202.             const name = validColumn.sourceKey ? validColumn.sourceKey : (Object.keys(item).find(key => key.indexOf('name') > -1 || key.indexOf('nama') > -1));
  203.             item.oid = item.id;
  204.             item.id = item[name];
  205.           }
  206.         });
  207.         console.log('source : ', validColumn.source);
  208.       }
  209.       this.configuration.columns.push(validColumn);
  210.  
  211.       // Configuration
  212.       Object.assign(this.configuration, this.options);
  213.  
  214.       // Data
  215.       this.initData();
  216.  
  217.       // Event
  218.       this.initEvents();
  219.  
  220.       index++;
  221.     }
  222.   }
  223.  
  224.   public getValues() {
  225.     const spreadsheetValues = this.getInstance().jexcel('getData', false) as any[];
  226.     spreadsheetValues.forEach((row: any[], rowIndex: number) => {
  227.       row.forEach((col: any, colIndex: number) => {
  228.         this.data[rowIndex][this.columns[colIndex].columnName] = this.getColValue(this.columns[colIndex], col);
  229.       });
  230.     });
  231.     return this.data;
  232.   }
  233.  
  234.   private initData() {
  235.     const values: any = [];
  236.     let rowIndex = 0;
  237.     let colIndex = 0;
  238.     for (const obj of this.data) {
  239.       colIndex = 0;
  240.       values[rowIndex] = [];
  241.       for (const column of this.columns) {
  242.         values[rowIndex][colIndex] = obj[column.columnName];
  243.         colIndex++;
  244.       }
  245.       rowIndex++;
  246.     }
  247.     this.configuration.data = values;
  248.   }
  249.  
  250.   private initEvents() {
  251.     this.options.onchange = this.options.onchange === undefined || this.options.onchange === null ? this.onchangeEvent : this.options.onchange;
  252.   }
  253.  
  254.   private getColValue(column: JExcelColumn, value): any {
  255.     if (column) {
  256.       if (ObjectHelper.isEmpty(value)) {
  257.         return null;
  258.       } else {
  259.         if (column.type === 'text') {
  260.           return String(value);
  261.         } else if (column.type === 'numeric') {
  262.           return Number(value);
  263.         } else if (column.type === 'calendar') {
  264.           return new Date(value);
  265.         } else if (column.type === 'dropdown' || column.type === 'autocomplete') {
  266.           const objValue = column.source.find(item => {
  267.             if (typeof item === 'object') {
  268.               const name = column.sourceKey ? column.sourceKey : (Object.keys(item).find(key => key.indexOf('name') > -1 || key.indexOf('nama') > -1));
  269.               return item[name] === value;
  270.             } else {
  271.               return item === value;
  272.             }
  273.           });
  274.           return objValue ? objValue : null;
  275.         } else {
  276.           return value;
  277.         }
  278.       }
  279.     }
  280.     return null;
  281.   }
  282.  
  283.   public update(data: any[]) {
  284.     this.data = lodash.cloneDeep(data);
  285.     console.log('data-param : ', data);
  286.     console.log('data : ', this.data);
  287.     this.initData();
  288.     this.getInstance().jexcel('setData', this.configuration.data, false);
  289.   }
  290.  
  291.   validate(c: AbstractControl): { [key: string]: any } {
  292.     return null;
  293.   }
  294. }
Advertisement
Add Comment
Please, Sign In to add comment