/* * Copyright (c) 2012-2014 Kaarle Ritvanen * See LICENSE file for license details */ define( ["aconf/dom", "aconf/error", "jquery", "underscore"], function(dom, formatError, $, _) { return { extend: function(spec) { var res = Object.create(this); for (key in spec) res[key] = spec[key]; return res; }, new: function(data, name, meta, level, editable, removable) { return Object.create(this).init( data, name, meta, level, editable, removable ); }, init: function(data, name, meta, level, editable, removable) { this.data = data; this.name = name; this.meta = meta; this.level = level; function appendRemoveButton(el) { if (removable) { var link = dom.href().click(function() { data.delete(name).done(function(txnValid) { $("#content").trigger("reload", [txnValid]); }) }).text("Delete"); el = dom.makeRow(el); if (el.is("tr")) link = $("").html(link); el.append(link); } return el; } var value = data.get(name); if (!editable || !meta.editable) { var el = this.staticRender(value, meta); if (el) { el = appendRemoveButton(el); _.each(["start", "updated"], function(event) { el.on(event, function(event) { event.stopPropagation(); }); }); dom.setStatus(el, data.status(name)); return el; } } this.makeEl(); this.dynamic = meta.dynamic; this.visible = true; this.wrapped = appendRemoveButton(this.wrap()); this.wrapped.data("description", meta.description); this.handleResponse(this.requestData(value, meta)); var self = this; function validate() { self.request.done(function(value) { self.validate(value); }); } this.wrapped.on("start", function(event) { if (data.status(name) == "invalid") validate(); else self.setVisible(); event.stopPropagation(); }); this.wrapped.on("updated", function(event, field) { if (self.dynamic) self.refresh(); if (!field || self.dynamic || (meta.condition && field in meta.condition)) validate(); event.stopPropagation(); }); return this.wrapped; }, makeEl: function() { this.el = this.createEl(); }, requestData: function(value, meta) { return $.Deferred().resolve(value, meta); }, refreshData: function() { var def = $.Deferred(); var self = this; this.data.metaRequest(this.name).done(function(data) { def.resolve(self.get(), data); }); return def; }, handleResponse: function(request) { this.request = request; var self = this; request.done(function(value, meta) { if (request != self.request) return; self.render(value, meta); self.updateStatus(); }); }, refresh: function() { this.handleResponse(this.refreshData()); }, wrap: function() { return this.el; }, updateStatus: function() { this.setStatus(this.data.status(this.name)); }, showStatus: true, setStatus: function(status) { if (this.el && this.showStatus) dom.setStatus(this.statusEl(), status); }, statusEl: function() { return this.el; }, setVisible: function() { this.visible = this.data.match(this.meta.condition); if (this.wrapped) this.wrapped.trigger("setVisible", [this.visible]); }, validate: function(value) { this.setVisible(); }, formatValidationError: function(xhr) { if (_.isString(xhr)) return xhr; if (xhr.statusCode().status == 422) return _.values($.parseJSON(xhr.responseText)).join("\n"); return formatError("Error", xhr); } }; } );