var ColumnText = require ('../column/text'); 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; } } ,valueField: { type: String, value: 'id' } ,showField: { type: String, value: 'name' } } ,_row: -1 ,_model: null ,_notNull: false ,render: function () { var node = this.createRoot ('div'); node.className = 'htk-combo'; var clearButton = this.createElement ('htk-icon'); clearButton.className = 'clear'; clearButton.icon = 'close'; clearButton.on ('click', this._onClearClick, this); node.appendChild (clearButton.node); var button = this.createElement ('button'); button.type = 'button'; button.className = 'htk-combo input'; button.addEventListener ('mousedown', this._onButtonMouseDown.bind (this)); node.appendChild (button); this.button = button; this.clearButton = clearButton; this._refreshShowText (); } ,_onClearClick: function () { this.value = null; } ,_setRow: function (row) { this._row = row; this._refreshShowText (); this.rowChanged (); } ,_onButtonMouseDown: function (e) { if (this._popup) { this._popup.hide (); return; } var model = this._model; var menu = this.createElement ('div'); menu.className = 'htk-combo-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 ({column: this.showField}); 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.get (row, this.valueField); 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.get (this._row, this.showField); else if (model && model.status === Db.Model.Status.LOADING) var showText = _('Loading...'); else if (this._placeholder) var showText = this._placeholder; else var showText = ''; if (this.node) { var visibility; if (this._value && !this._notNull) visibility = 'visible'; else visibility = 'hidden'; this.clearButton.node.style.visibility = visibility; Vn.Node.setText (this.button, 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.search (this.valueField, this._value); else row = -1; this._setRow (row); } ,putValue: function () { this._selectOption (); } });