forked from verdnatura/hedera-web
260 lines
4.9 KiB
JavaScript
260 lines
4.9 KiB
JavaScript
require('./style.scss');
|
|
var ColumnText = require('../columns/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;
|
|
}
|
|
},
|
|
/**
|
|
* The row object.
|
|
*/
|
|
$: {
|
|
type: Object
|
|
,get: function() {
|
|
return this._model.getObject(this._row) || {};
|
|
}
|
|
},
|
|
params: {
|
|
type: Object
|
|
,get: function() {
|
|
return this.$;
|
|
}
|
|
}
|
|
}
|
|
|
|
,_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.classList.add('input');
|
|
button.addEventListener('mousedown',
|
|
e => this._onButtonMouseDown(e));
|
|
|
|
this.label = this.createElement('span');
|
|
button.appendChild(this.label);
|
|
|
|
const erase = new Htk.Icon({
|
|
name: 'close',
|
|
title: _('Erase')
|
|
});
|
|
erase.classList.add('erase');
|
|
erase.addEventListener('mousedown',
|
|
e => this._onEraseMouseDown(e));
|
|
button.appendChild(erase.node);
|
|
|
|
const dropDown = new Htk.Icon({
|
|
name: 'expand_more'
|
|
});
|
|
button.appendChild(dropDown.node);
|
|
}
|
|
|
|
,_setRow: function(row) {
|
|
this._row = row;
|
|
this._refreshShowText();
|
|
this.iterChanged();
|
|
}
|
|
|
|
,_onEraseMouseDown(event) {
|
|
if (event.defaultPrevented) return;
|
|
event.preventDefault();
|
|
this._setRow(-1);
|
|
this.valueChanged(undefined);
|
|
}
|
|
|
|
,_onButtonMouseDown: function(event) {
|
|
if (this._popup) {
|
|
this._popup.hide();
|
|
return;
|
|
}
|
|
|
|
if (event.defaultPrevented) return;
|
|
event.preventDefault();
|
|
|
|
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, event);
|
|
|
|
this.emit('menu-show');
|
|
}
|
|
|
|
,_onGridClicked: function(grid, e) {
|
|
let cell;
|
|
let target = e.target;
|
|
|
|
while (target !== grid.tbody) {
|
|
cell = target;
|
|
target = target.parentNode;
|
|
}
|
|
|
|
if (!cell) return;
|
|
|
|
let value;
|
|
const row = cell.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.emit('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.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.searchByIndex(this.valueColumnIndex, this._value);
|
|
else
|
|
row = -1;
|
|
|
|
this._setRow(row);
|
|
}
|
|
|
|
,putValue: function() {
|
|
this._selectOption();
|
|
}
|
|
});
|