var ColumnText = require('../column/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; } } } ,_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.className = 'htk-select input'; button.addEventListener('mousedown', this._onButtonMouseDown.bind(this)); this.label = this.createElement('span'); button.appendChild(this.label); const dropDown = new Htk.Icon({ name: 'expand_more' }); button.appendChild(dropDown.node); } ,on: function(id, callback, instance) { switch (id) { case 'click': case 'mousedown': case 'focusout': this.node.addEventListener(id, callback.bind(instance, this)); break; default: this.parent(id, callback, instance); } } ,_setRow: function(row) { this._row = row; this._refreshShowText(); this.iterChanged(); } ,_onButtonMouseDown: function(e) { if (this._popup) { this._popup.hide(); return; } 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); this.signalEmit('menu-show'); e.stopPropagation(); } ,_onGridClicked: function(grid, e) { var target = e.target; var parentNode = target.parentNode; while (parentNode !== grid.tbody) { target = parentNode; parentNode = parentNode.parentNode; } var value; var row = target.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.signalEmit('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.signalEmit('status-changed'); if (this._popup) this._popup.reset(); if (model && model.ready) { this._selectOption(); this.signalEmit('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(value) { this._selectOption(); } });