import { Component, Input, Output, EventEmitter, ExistingProvider, forwardRef, ElementRef, OnInit, OnChanges } from '@angular/core'; import { InputBase } from './inputBase'; import { RdLib } from '../../base/rdLib'; const provider: ExistingProvider = { provide: InputBase, useExisting: forwardRef(() => InputDropDownBox) } export type ViewModes = "tree" | "grid"; export type SelectionModes = "single" | "multiple"; @Component({ selector: 'rd-input-drop-down-box', template: `
`, providers: [provider] }) export class InputDropDownBox extends InputBase implements OnInit, OnChanges { constructor(private element: ElementRef) { super(); } @Input("rd-model") model; @Output("rd-modelChange") modelChange: EventEmitter> = new EventEmitter>(); @Output("rd-change") changeEvent: EventEmitter> = new EventEmitter>(); @Input("rd-data") data: Array; @Input("rd-valueExpr") valueExpr; @Input("rd-displayExpr") displayExpr; @Input("rd-parentExpr") parentIdExpr; @Input("rd-height") height: number | string = "34"; @Input("rd-required") required: boolean; @Input("rd-disabled") disabled: boolean; @Input("rd-readOnly") readOnly: boolean; @Input("rd-select-recursive") selectRecursive: boolean = true; @Input("rd-grid-columns") columns: Array = []; @Input("rd-viewMode") viewMode: ViewModes = "tree"; @Input("rd-selectionMode") selectionMode: SelectionModes = "single"; @Input("rd-placeholder") placeholder: string = RdLib.localization.translateEn("Select a value"); treeView: any; gridView: any; ngOnInit() { this.container = this.jQuery(this.element.nativeElement).find("#dxElement"); this.render(); } ngOnChanges(changes) { if (!this.dxElement) return if (changes.model) this.dxElement.option("value", this.model); if (changes.data) this.dxElement.option("dataSource", this.data); if (changes.required) this.updateValidator(); if (changes.disabled) this.dxElement.option('disabled', this.disabled); if (changes.readOnly) this.dxElement.option('readOnly', this.readOnly); } render() { this.container.dxDropDownBox({ dataSource: this.data, value: this.model, valueExpr: this.valueExpr, displayExpr: this.displayExpr, showClearButton: !this.required, disabled: this.disabled, readOnly: this.readOnly, placeholder: this.placeholder, onValueChanged: (e) => { if (this.viewMode == "tree") this.syncTreeViewSelection(e.value); else this.gridView.selectRows(e.value, false); // grid if (!e.value) this.onChange(this.selectionMode == "single" ? null : []); }, contentTemplate: (dropDown) => { if (this.viewMode == "tree") return this.getTreeView(dropDown); else return this.getGridView(dropDown); } }); this.dxElement = this.container.dxDropDownBox("instance"); } getTreeView(dropDown) { let $treeView = this.jQuery("
").dxTreeView({ dataSource: dropDown.component.option("dataSource"), dataStructure: "plain", selectionMode: this.selectionMode, showCheckBoxesMode: "normal", searchEnabled: true, selectByClick: true, selectNodesRecursive: this.selectRecursive, keyExpr: this.valueExpr, displayExpr: this.displayExpr, parentIdExpr: this.parentIdExpr, onContentReady: () => this.syncTreeViewSelection(dropDown.component.option("value")), onItemSelectionChanged: (tree) => { let nodeKeys = this.getSelectedNodes(tree.component.getNodes()); dropDown.component.option("value", nodeKeys); this.onChange(this.selectionMode == "single" ? nodeKeys[0] : nodeKeys); } }); this.treeView = $treeView.dxTreeView("instance"); return $treeView; } getGridView(dropDown) { let value = dropDown.component.option("value"); let $dataGrid = this.jQuery("
").dxDataGrid({ height: "100%", dataSource: dropDown.component.option("dataSource"), columns: this.columns, hoverStateEnabled: true, paging: { enabled: true, pageSize: 10 }, filterRow: { visible: true }, scrolling: { mode: "infinite" }, selection: { mode: this.selectionMode }, selectedRowKeys: this.selectionMode == "single" ? [value] : value, onSelectionChanged: (selectedItems) => { let keys = selectedItems.selectedRowKeys; let hasSelection = keys.length; if (this.selectionMode == "single") dropDown.component.option("value", hasSelection ? keys[0] : null); else dropDown.component.option("value", keys); this.onChange(this.selectionMode == "single" ? keys[0] : keys); } }); this.gridView = $dataGrid.dxDataGrid("instance"); return $dataGrid; } syncTreeViewSelection(value) { if (!this.treeView) return; if (value && value.length) { if (this.selectionMode == "single") this.treeView.selectItem(value); else { if (typeof value == "string") JSON.parse(value).forEach(el => { this.treeView.selectItem(el) }); else value.forEach(el => { this.treeView.selectItem(el) }); } } else this.treeView.unselectAll(); }; getSelectedNodes(nodes) { var result = []; for (let item of nodes) { if (item.selected) result.push(item.key); if (item.items.length) result = result.concat(this.getSelectedNodes(item.items)); } return result; }; }