summaryrefslogtreecommitdiffstats
path: root/web/widget/abstract/base.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/widget/abstract/base.js')
-rw-r--r--web/widget/abstract/base.js134
1 files changed, 134 insertions, 0 deletions
diff --git a/web/widget/abstract/base.js b/web/widget/abstract/base.js
new file mode 100644
index 0000000..4a49e0b
--- /dev/null
+++ b/web/widget/abstract/base.js
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012-2014 Kaarle Ritvanen
+ * See LICENSE file for license details
+ */
+
+define(["acf2/dom", "jquery", "underscore"], function(dom, $, _) {
+ return {
+ extend: function(spec) {
+ var res = Object.create(this);
+ for (key in spec) res[key] = spec[key];
+ res.base = this;
+ return res;
+ },
+
+ super: function() {
+ var args = _.toArray(arguments);
+ var cls = args.shift();
+ var key = args.shift();
+ return cls.base[key].apply(this, args);
+ },
+
+ 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;
+
+ var value = data.get(name);
+ var status = data.status(name);
+
+ if (!editable || !meta.editable) {
+ var el = this.staticRender(value, meta);
+ if (el) {
+ dom.setStatus(el, status);
+ return el;
+ }
+ }
+
+ this.makeEl();
+ this.dynamic = meta.dynamic;
+
+ var self = this;
+
+ var request;
+ function handleRequest(req) {
+ request = req;
+ req.done(function(value, meta) {
+ if (req != request) return;
+ self.render(value, meta);
+ self.setStatus(status);
+ });
+ }
+
+ this.wrapped = this.wrap();
+ this.visible = true;
+
+ if (removable) {
+ var link = dom.href().click(function() {
+ data.delete(name).done(function(txnValid) {
+ $("#content").trigger("reload", [txnValid]);
+ })
+ }).text("Delete");
+ this.wrapped = dom.makeRow(this.wrapped);
+ if (this.wrapped.is("tr")) link = $("<td>").html(link);
+ this.wrapped.append(link);
+ }
+
+ handleRequest(this.requestData(value, meta));
+
+ function validate() {
+ 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) handleRequest(self.refreshData());
+ 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;
+ },
+
+ wrap: function() { return this.el; },
+
+ 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(); }
+ };
+});