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; } }, /** * 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 ,initialize: function (props) { this.createElement ('select'); this.node.addEventListener ('change', this._onChange.bind (this)); this._addPlaceholder (this._placeholder); this.parent (props); } ,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) { if (row != -1) this.node.selectedIndex = row + this.getIndexIncrement (); else if (this._placeholder) this.node.selectedIndex = 0; else this.node.selectedIndex = -1; this._row = row; this.iterChanged (); } ,_onChange: function (event) { var value; var row = this.node.selectedIndex - this.getIndexIncrement (); if (row >= 0) value = this._model.getByIndex (row, this.valueColumnIndex); else value = null; this.setRow (row); this.valueChanged (value); } ,getIndexIncrement: function () { var inc = 0; if (this._placeholder) inc++; if (!this._notNull) inc++; return inc; } ,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.className = 'htk-option'; option.disabled = true; option.selected = true; option.value = null; Vn.Node.setText (option, text ? text : ''); this.node.appendChild (option); this._placeholderNode = option; } ,onModelChange: function () { var placeholder = null; var model = this._model; this.signalEmit ('status-changed'); Vn.Node.removeChilds (this.node); switch (model.status) { case Db.Model.Status.ERROR: placeholder = _('Error'); break; case Db.Model.Status.LOADING: placeholder = _('Loading...'); break; default: placeholder = this._placeholder; } if (placeholder) this._addPlaceholder (placeholder); if (model.ready) { var data = model.data; if (!this.notNull) this.addOption (null, null); for (var i = 0; i < data.length; i++) this.addOption (data[i][this.showColumnIndex], data[i][1]); this.selectOption (); this._onTimeout (); this.signalEmit ('ready'); } else this.setRow (-1); } ,_onTimeout: function () { if (this._blockMouseDown || !navigator.userAgent.match (/WebKit/)) return; this._blockMouseDown = true; this.node.blur(); var e = document.createEvent('MouseEvents'); e.initMouseEvent ('mousedown', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); this.node.dispatchEvent(e); this._blockMouseDown = false; this.node.focus (); } ,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 (); } });