require('./style.scss'); var ColumnText = require('../columns/text'); module.exports = new Class({ Extends: Htk.Field ,Implements: Db.Iterator ,Tag: 'htk-combo' ,Properties: { /** * The model associated to this form. */ model: { type: Db.Model ,set: function(x) { this.link({_model: x}, {'status-changed-after': this._onModelChange}); this._onModelChange(); } ,get: function() { return this._model; } }, /** * The row where the form positioned, has -1 if the row is unselected. */ row: { type: Number ,set: function(x) { if (!this._model || this._model.numRows <= x || x < -1) x = -1; if (x == this._row) return; this._row = x; this.iterChanged(); } ,get: function() { return this._row; } }, /** * The number of rows in the form. */ numRows:{ type: Number ,get: function() { if (this._model) return this._model.numRows; return 0; } }, /** * Checks if the form data is ready. */ ready:{ type: Boolean ,get: function() { return this._model && this._model.ready; } }, /** * Checks if the form data is ready. */ placeholder:{ type: String ,set: function(x) { this._placeholder = x; this._refreshShowText(x); } ,get: function() { return this._placeholder; } }, /** * Wether to allow null values. */ notNull:{ type: Boolean ,set: function(x) { this._notNull = x; } ,get: function() { return this._notNull; } }, /** * The row object. */ $: { type: Object ,get: function() { return this._model.getObject(this._row) || {}; } }, params: { type: Object ,get: function() { return this.$; } } } ,_row: -1 ,_model: null ,valueColumnIndex: 0 ,valueColumnName: null ,showColumnIndex: 1 ,showColumnName: null ,_notNull: true ,_webkitRefresh: false ,render: function() { const button = this.createRoot('button'); button.type = 'button'; button.classList.add('input'); button.addEventListener('mousedown', e => this._onButtonMouseDown(e)); this.label = this.createElement('span'); button.appendChild(this.label); const erase = new Htk.Icon({ name: 'close', title: _('Erase') }); erase.classList.add('erase'); erase.addEventListener('mousedown', e => this._onEraseMouseDown(e)); button.appendChild(erase.node); const dropDown = new Htk.Icon({ name: 'expand_more' }); button.appendChild(dropDown.node); } ,_setRow: function(row) { this._row = row; this._refreshShowText(); this.iterChanged(); } ,_onEraseMouseDown(event) { if (event.defaultPrevented) return; event.preventDefault(); this._setRow(-1); this.valueChanged(undefined); } ,_onButtonMouseDown: function(event) { if (this._popup) { this._popup.hide(); return; } if (event.defaultPrevented) return; event.preventDefault(); var model = this._model; var menu = this.createElement('div'); menu.className = 'htk-select-menu'; var grid = new Htk.Grid({showHeader: false}); menu.appendChild(grid.node); var gridNode = grid.node; gridNode.addEventListener('click', this._onGridClicked.bind(this, grid)); var column = new ColumnText({columnIndex: this.showColumnIndex}); grid.appendColumn(column); grid.model = model; var popup = this._popup = new Htk.Popup({childNode: menu}); popup.on('closed', this._onPopupClose.bind(this)); popup.show(this.node, event); this.emit('menu-show'); } ,_onGridClicked: function(grid, e) { let cell; let target = e.target; while (target !== grid.tbody) { cell = target; target = target.parentNode; } if (!cell) return; let value; const row = cell.rowIndex - 1; if (row >= 0) value = this._model.getByIndex(row, this.valueColumnIndex); else value = null; this._setRow(row); this.valueChanged(value); this._popup.hide(); e.stopPropagation(); } ,_onPopupClose: function() { this._popup = null; this.emit('menu-hide'); } ,_refreshShowText: function() { var model = this._model; if (this._row !== -1) var showText = model.getByIndex(this._row, this.showColumnIndex); else if (model && model.status === Db.Model.Status.LOADING) var showText = _('Loading...'); else if (this._placeholder) var showText = this._placeholder; else var showText = ''; Vn.Node.setText(this.label, showText); } ,_onModelChange: function() { var model = this._model; this.emit('status-changed'); if (this._popup) this._popup.reset(); if (model && model.ready) { this._selectOption(); this.emit('ready'); } else this._setRow(-1); } ,setEditable: function(editable) { this.node.disabled = !editable; } ,_selectOption: function() { var row; if (this._model && this._model.ready) row = this._model.searchByIndex(this.valueColumnIndex, this._value); else row = -1; this._setRow(row); } ,putValue: function() { this._selectOption(); } });