Htk.Repeater = new Class ({ Extends: Htk.Widget ,Tag: 'htk-repeater' ,Child: 'model' ,Properties: { 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; } } ,formId: { type: String ,set: function (x) { this._alias = x; } ,get: function () { this._alias; } } ,renderer: { type: Function ,set: function (x) { this._renderer = x; } ,get: function () { this._renderer; } } ,emptyMessage: { type: String ,value: _('NoData') } } ,xml: null ,parentBuilder: null ,_alias: 'form' ,initialize: function () { this.createElement ('div'); this.node.className = 'htk-repeater'; } ,loadXml: function (builder, node) { this.parent (builder, node); var template = node.querySelector ('template:first-of-type'); if (template) { this.xml = template.firstElementChild; this.parentBuilder = builder; this.onModelChange (); } } ,getChild: function (index) { return this.node.childNodes[index]; } ,getBuilder: function (index) { return this.childsData[index].builder; } ,getForm: function (index) { return this.childsData[index].form; } ,buildBox: function (index) { var builder = new Vn.Builder (); builder.setParent (this.parentBuilder); var form = new Db.Form (); form.model = this._model; form.row = index; builder.add (this._alias, form); this.childsData.push ({ builder: builder, form: form }); var mainNode = builder.loadXmlFromNode (this.xml); if (this._renderer) this._renderer (builder, form); this.node.appendChild (mainNode); } ,onModelChange: function () { if (!this._model || !this.xml) return; Vn.Node.removeChilds (this.node); this.freeChildsData (); this.childsData = []; switch (this._model.status) { case Db.Model.Status.READY: { for (var i = 0; i < this._model.numRows; i++) this.buildBox (i); this.showNoRecordsFound (); break; } case Db.Model.Status.LOADING: this.showMessage (_('Loading'), 'loader-black.gif'); break; case Db.Model.Status.CLEAN: this.showMessage (this.emptyMessage, 'refresh.svg'); break; case Db.Model.Status.ERROR: this.showMessage (_('ErrorLoadingData'), 'error.svg'); break; } this.signalEmit ('change'); } ,showNoRecordsFound: function (count) { if (this._model.numRows == 0) this.showMessage (_('EmptyList'), 'clean.svg'); } ,showMessage: function (message, src) { var div = document.createElement ('div'); div.className = 'message'; this.node.appendChild (div); var img = document.createElement ('img'); img.alt = ''; img.src = 'image/'+ src; div.appendChild (img); div.appendChild (document.createTextNode (message)); } ,onRowDelete: function (model, row) { Vn.Node.remove (this.node.childNodes[row]); this.showNoRecordsFound (); } ,onRowUpdate: function (model, row, columns) { // this.form[row].signalEmit ('iter-changed'); } ,onRowInsert: function (model, row) { this.buildBox (row); } ,freeChildsData: function () { if (this.childsData) for (var i = 0; i < this.childsData.length; i++) { this.childsData[i].form.unref (); this.childsData[i].builder.unref (); } } ,destroy: function () { this.freeChildsData (); this.parent (); } });