Htk.Select = 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': 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._ready; } }, /** * Checks if the form data is ready. **/ placeholder: { type: String ,set: function (x) { this._placeholder = x; if (this._placeholderNode) Vn.Node.setText (this._placeholderNode, x); } ,get: function () { return this._placeholder; } } } ,_row: -1 ,_model: null ,valueColumnIndex: 0 ,valueColumnName: null ,showColumnIndex: 1 ,showColumnName: null ,initialize: function (props) { this.parent (props); this.createElement ('select'); this.node.addEventListener ('change', this.changed.bind (this)); } ,on: function (id, callback, instance) { switch (id) { case 'click': this.node.addEventListener (id, callback.bind (instance, this)); break; default: this.parent (id, callback, instance); } } ,setRow: function (row) { this._row = row; this.iterChanged (); } ,changed: function (event) { var value; var row = this.node.selectedIndex - 1; if (row >= 0) value = this._model.getByIndex (row, this.valueColumnIndex); else value = null; this.valueChanged (value); this.setRow (row); } ,addOption: function (value, text) { var option = document.createElement ('option'); option.value = value; if (text) option.appendChild (document.createTextNode (text)); this.node.appendChild (option); } ,addPlaceholder: function (text) { var option = document.createElement ('option'); option.disabled = true; option.selected = true; option.value = null; if (text) option.appendChild (document.createTextNode (text)); this.node.appendChild (option); this._placeholderNode = option; } ,onModelChange: function () { var placeholder = ''; var model = this._model; this.signalEmit ('status-changed'); Vn.Node.removeChilds (this.node); switch (model.status) { case Db.Model.Status.READY: { var data = model.data; this.addPlaceholder (this._placeholder); for (var i = 0; i < data.length; i++) this.addOption (data[i][this.showColumnIndex], data[i][1]); this.selectOption (); break; } case Db.Model.Status.ERROR: placeholder = 'Error'; break; case Db.Model.Status.LOADING: placeholder = 'Loading...'; default: this.addPlaceholder (_(placeholder)); this.setRow (-1); } } ,setEditable: function (editable) { this.node.disabled = !editable; } ,selectOption: function () { var row; if (this._model && this._model.status == Db.Model.Status.READY) { row = this._model.searchByIndex (this.valueColumnIndex, this._value); if (row != -1) this.node.selectedIndex = row + 1; } else row = -1; this.setRow (row); } ,putValue: function (value) { this.selectOption (); } });