248 lines
4.5 KiB
JavaScript
248 lines
4.5 KiB
JavaScript
|
|
var Widget = require ('./widget');
|
|
|
|
module.exports = new Class
|
|
({
|
|
Extends: Widget
|
|
,Tag: 'htk-repeater'
|
|
,Child: 'model'
|
|
,Properties:
|
|
{
|
|
/**
|
|
* The source data model.
|
|
*/
|
|
model:
|
|
{
|
|
type: Db.Model
|
|
,set: function (x)
|
|
{
|
|
this.link ({_model: x},
|
|
{
|
|
'status-changed': this._onModelChange
|
|
,'row-deleted': this._onRowDelete
|
|
,'row-updated': this._onRowUpdate
|
|
,'row-inserted': this._onRowInsert
|
|
});
|
|
|
|
this._onModelChange ();
|
|
}
|
|
,get: function ()
|
|
{
|
|
this._model;
|
|
}
|
|
}
|
|
/**
|
|
* The identifier for internal iterator.
|
|
*/
|
|
,formId:
|
|
{
|
|
type: String
|
|
,set: function (x)
|
|
{
|
|
this._formId = x;
|
|
}
|
|
,get: function ()
|
|
{
|
|
this._formId;
|
|
}
|
|
}
|
|
/**
|
|
* {Function (Vn.BuilderResult, Db.Form)} Function to call after every
|
|
* box rendering.
|
|
*/
|
|
,renderer:
|
|
{
|
|
type: Function
|
|
,set: function (x)
|
|
{
|
|
this._renderer = x;
|
|
}
|
|
,get: function ()
|
|
{
|
|
this._renderer;
|
|
}
|
|
}
|
|
/**
|
|
* Message that should be displayed when source model is not ready.
|
|
*/
|
|
,emptyMessage:
|
|
{
|
|
type: String
|
|
,value: null
|
|
}
|
|
}
|
|
|
|
,_builder: null
|
|
,_formId: 'form'
|
|
|
|
,render: function ()
|
|
{
|
|
var div = this.createRoot ('div');
|
|
|
|
this._container = this.createElement ('div');
|
|
this._container.className = 'htk-repeater';
|
|
div.appendChild (this._container);
|
|
}
|
|
|
|
,loadXml: function (builderResult, node)
|
|
{
|
|
this.parent (builderResult, node);
|
|
|
|
var builder = this._builder = new Vn.Builder ();
|
|
builder.setParent (builderResult);
|
|
builder.loadXmlFromNode (node.firstElementChild);
|
|
|
|
this._onModelChange ();
|
|
}
|
|
|
|
,getChild: function (index)
|
|
{
|
|
return this._container.childNodes[index];
|
|
}
|
|
|
|
,getBuilder: function (index)
|
|
{
|
|
return this._childsData[index].builder;
|
|
}
|
|
|
|
,getForm: function (index)
|
|
{
|
|
return this._childsData[index].set;
|
|
}
|
|
|
|
,_buildBox: function (index)
|
|
{
|
|
var set = new Db.SimpleIterator ({
|
|
model: this._model,
|
|
row: index
|
|
});
|
|
|
|
this._builder.add (this._formId, set);
|
|
var res = this._builder.load ();
|
|
res.link ();
|
|
|
|
this._childsData.push ({
|
|
builder: res,
|
|
set: set
|
|
});
|
|
|
|
if (this._renderer)
|
|
this._renderer (res, set);
|
|
|
|
return res.getMain ();
|
|
}
|
|
|
|
,_onModelChange: function ()
|
|
{
|
|
if (!this._model || !this._builder)
|
|
return;
|
|
|
|
this.node.removeChild (this._container);
|
|
Vn.Node.removeChilds (this._container);
|
|
|
|
this._freeChildsData ();
|
|
this._childsData = [];
|
|
|
|
switch (this._model.status)
|
|
{
|
|
case Db.Model.Status.READY:
|
|
{
|
|
for (var i = 0; i < this._model.numRows; i++)
|
|
this._container.appendChild (this._buildBox (i));
|
|
|
|
this._showNoRecordsFound ();
|
|
break;
|
|
}
|
|
case Db.Model.Status.LOADING:
|
|
this._showMessage (_('Loading'), null);
|
|
break;
|
|
case Db.Model.Status.CLEAN:
|
|
{
|
|
var emptyMessage = this.emptyMessage ?
|
|
this.emptyMessage : _('NoData');
|
|
this._showMessage (emptyMessage, 'refresh');
|
|
break;
|
|
}
|
|
case Db.Model.Status.ERROR:
|
|
this._showMessage (_('ErrorLoadingData'), 'error');
|
|
break;
|
|
}
|
|
|
|
this.node.appendChild (this._container);
|
|
this.signalEmit ('change');
|
|
}
|
|
|
|
,_showNoRecordsFound: function (count)
|
|
{
|
|
if (this._model.numRows === 0)
|
|
this._showMessage (_('EmptyList'), 'clean');
|
|
}
|
|
|
|
,_showMessage: function (message, src)
|
|
{
|
|
var div = this.createElement ('div');
|
|
div.className = 'message';
|
|
this._container.appendChild (div);
|
|
|
|
if (src)
|
|
{
|
|
var img = this.createElement ('img');
|
|
img.alt = '';
|
|
img.src = 'image/icon/light/'+ src +'.svg';
|
|
div.appendChild (img);
|
|
}
|
|
else
|
|
{
|
|
var spinner = new Htk.Spinner ();
|
|
spinner.start ();
|
|
div.appendChild (spinner.node);
|
|
}
|
|
|
|
div.appendChild (this.createTextNode (message));
|
|
}
|
|
|
|
,_onRowDelete: function (model, row)
|
|
{
|
|
Vn.Node.remove (this._container.childNodes[row]);
|
|
this._unrefChildData (row);
|
|
this._childsData.splice (row, 1);
|
|
|
|
for (var i = row; i < this._model.numRows; i++)
|
|
this._childsData[i].set.row = i;
|
|
|
|
this._showNoRecordsFound ();
|
|
}
|
|
|
|
,_onRowUpdate: function (model, row, columns)
|
|
{
|
|
this._childsData[row].set.changed ();
|
|
}
|
|
|
|
,_onRowInsert: function (model, row)
|
|
{
|
|
var box = this._buildBox (row);
|
|
this._container.appendChild (box);
|
|
}
|
|
|
|
,_freeChildsData: function ()
|
|
{
|
|
if (this._childsData)
|
|
for (var i = 0; i < this._childsData.length; i++)
|
|
this._unrefChildData (i);
|
|
}
|
|
|
|
,_unrefChildData: function (index)
|
|
{
|
|
var childData = this._childsData[index];
|
|
childData.set.unref ();
|
|
childData.builder.unref ();
|
|
}
|
|
|
|
,_destroy: function ()
|
|
{
|
|
this._freeChildsData ();
|
|
this.parent ();
|
|
}
|
|
});
|
|
|