hedera-web/js/htk/field/select.js

245 lines
4.6 KiB
JavaScript

var ColumnText = require('../column/text');
module.exports = 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-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.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._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;
}
}
}
,_row: -1
,_model: null
,valueColumnIndex: 0
,valueColumnName: null
,showColumnIndex: 1
,showColumnName: null
,_notNull: true
,_webkitRefresh: false
,render: function() {
const button = this.createRoot('button');
button.type = 'button';
button.className = 'htk-select input';
button.addEventListener('mousedown', this._onButtonMouseDown.bind(this));
this.label = this.createElement('span');
button.appendChild(this.label);
const dropDown = new Htk.Icon({
name: 'expand_more'
});
button.appendChild(dropDown.node);
}
,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) {
this._row = row;
this._refreshShowText();
this.iterChanged();
}
,_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);
this.signalEmit('menu-show');
e.stopPropagation();
}
,_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.signalEmit('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.label, showText);
}
,_onModelChange: function() {
var model = this._model;
this.signalEmit('status-changed');
if (this._popup)
this._popup.reset();
if (model && model.ready) {
this._selectOption();
this.signalEmit('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(value) {
this._selectOption();
}
});