;(function(){ _App.Template = function() { this.initialize(); }; _App.Template.prototype = { tempStore : {}, templateStore : {}, instanceCounter : 0, initialize : function() { // Nothing to do. }, /** * Retrieve a template from the server. * @param type * @param name * @param lifespan */ retrieve : function( type, name, lifespan, callback ) { if (!this.templateStore[name]) { this.templateStore[name] = {}; this.tempStore[name] = {}; this.tempStore[name]["callback"] = callback; var rnd = new Date().getTime(); App.Ajax.GET({ id : name, url : 'templates/' + type + '/' + name + '.html?t=' + rnd }, $.proxy( this._retrievedHtml, this )); App.Ajax.SCRIPT({ id : name, url : 'templates/' + type + '/' + name + '.js?t=' + rnd }, $.proxy( this._retrievedJs, this )); } else { if (undefined != callback && 'function' == typeof callback) { callback(name); } } }, _retrievedJs : function ( name, data) { this.tempStore[name]['class'] = "template_" + name; if (this.tempStore[name]['html']) { this.templateStore[name] = new window[this.tempStore[name]['class']]( this.tempStore[name]['html'] ); if (this.tempStore[name]["callback"]) { this.tempStore[name]["callback"](name); } delete this.tempStore[name]; //App.Event.trigger('Template.Retrieved:' + name, {"name": name}); } }, _retrievedHtml : function ( name, data) { this.tempStore[name]['html'] = data; if (this.tempStore[name]['class']) { this.templateStore[name] = new window[this.tempStore[name]['class']]( this.tempStore[name]['html'] ); if (this.tempStore[name]["callback"]) { this.tempStore[name]["callback"](name); } delete this.tempStore[name]; //App.Event.trigger('Template.Retrieved:' + name, {"name": name}); } }, /** * Register a new template instance. * Template must already have been retrieved from server. * @param id * @param name * @param target * @param data * @returns */ register : function( id, type, name, target, data, callback ) { _t[id] = new this._templateInstance( this.instanceCounter, null, target, data ); App.Event.trigger( 'Template.Ready:' + name, {"id": name, "pageName": name} ); if (!this.templateStore[name]) { this.retrieve(type, name, true, $.proxy( this._hydrateTemplate, this, callback, id )); } else { _t[id].setTemplate(this.templateStore[name]); callback(id, name); } this.instanceCounter++; return _t[id]; }, _hydrateTemplate : function ( callback, id, name ) { _t[id].setTemplate(this.templateStore[name]); callback(id, name); }, _templateInstance : function( tid, template, target, data ) { this.tid = tid; this.template = template; this.target = target; this.data = null; this.published = false; this.autoPublish = []; if (this.template && this.template.static) { this.construct = this.template.static.replaceAll('[tid]', this.tid); if (undefined != this.template.init) { this.template.init(this); } } /** * Do something when we publish. */ this.onPublish = function ( callback ) { if (!this.published) { this.autoPublish.push(callback); } else { callback(); } }; /** * Set the template to work with for this instance. * @param template */ this.setTemplate = function ( template ) { this.template = template; this.construct = this.template.static ? this.template.static.replaceAll('[tid]', this.tid) : ''; if (undefined != this.template.init) { this.template.init(this); } if (this.data) { this.hydrate(this.data); } }; /** * Hydrate template with dataset. * This can be called before and after template publication. * @param data */ this.hydrate = function( data ) { this.data = data; if (this.template) { for (var element in this.template.elements) { var elem = this.template.elements[element]; value = (data[element]) ? data[element] : null; if (this.published) { elem.hydrateLive(this.tid, value); } else { this.construct = elem.hydrate(this.construct, value); } } if (this.published) { $('.selectpicker').selectpicker(); } } }; if (this.template && this.data) { this.hydrate(this.data); } this.hydratePartial = function( data ) { if (!this.data) { this.data = {}; } if (this.template && this.template.elements) { for (var element in data) { if (this.template.elements[element]) { var elem = this.template.elements[element]; value = (data[element]) ? data[element] : null; this.data[element] = value; if (this.published) { elem.hydrateLive(this.tid, value); } else { this.construct = elem.hydrate(this.construct, value); } } } if (this.published) { $('.selectpicker').selectpicker(); } } }; /** * Hydrate template with a single parameter. * This can be called before and after template publication. * @param param * @param value */ this.hydrateParam = function( param, value ) { if (!this.data) { this.data = {}; } this.data[param] = value; if (this.template && this.template.elements && this.template.elements[param]) { var elem = this.template.elements[param]; if (this.published) { elem.hydrateLive(this.tid, value); $('.selectpicker').selectpicker(); } else { this.construct = elem.hydrate(this.construct, value); } } }; /** * Publish template to registered target. */ this.publish = function() { $('#' + this.target).html( '