258 lines
4.5 KiB
JavaScript
Executable File
258 lines
4.5 KiB
JavaScript
Executable File
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._onChange.bind (this));
|
|
this._addPlaceholder (this._placeholder);
|
|
}
|
|
|
|
,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++;
|
|
|
|
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;
|
|
|
|
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 ();
|
|
}
|
|
});
|