var ColumnText = require ('../column/text'); var nativeEvents = { 'click' : 1 ,'mousedown' : 1 ,'focusout' : 1 }; module.exports = new Class ({ Extends: Htk.Field ,Implements: Vn.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.rowChanged (); } ,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; } }, params: { type: Object ,set: function (x) { this.setAll (x); } ,get: function () { return this._params; } } ,$: { type: Object ,set: function (x) { this.setAll (x); } ,get: function () { return this._params; } } } ,_row: -1 ,_model: null ,valueColumnIndex: 0 ,valueColumnName: null ,showColumnIndex: 1 ,showColumnName: null ,_notNull: true ,_webkitRefresh: false ,render: function () { var button = this.createRoot ('button'); button.type = 'button'; button.className = 'htk-select input'; button.addEventListener ('mousedown', this._onButtonMouseDown.bind (this)); } ,on: function (id, callback, instance) { if (nativeEvents[id] !== undefined) this.node.addEventListener (id, callback.bind (instance, this)); else this.parent (id, callback, instance); } ,_setRow: function (row) { this._row = row; this._refreshShowText (); this.changed (); } ,_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, true, e); this.emit ('menu-show'); } ,_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.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.node, 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 (); } });