summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-10 17:21:10 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-11 13:01:39 +0200
commit3204822db1ae50aa031446b22e7ba94845a9c7c1 (patch)
tree447063175476517338c79efc54098f5568476939 /web
parentbdebf89f5d7661b0bb360b4484c85a3ddcd3e249 (diff)
downloadaconf-3204822db1ae50aa031446b22e7ba94845a9c7c1.tar.bz2
aconf-3204822db1ae50aa031446b22e7ba94845a9c7c1.tar.xz
web client: cleaner syntax for widget inheritance
Diffstat (limited to 'web')
-rw-r--r--web/client.js1012
1 files changed, 533 insertions, 479 deletions
diff --git a/web/client.js b/web/client.js
index 89cb341..3497039 100644
--- a/web/client.js
+++ b/web/client.js
@@ -476,6 +476,26 @@ $(function() {
var Widget = {
+ 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.meta = meta;
@@ -557,526 +577,563 @@ $(function() {
};
- var Field = Object.create(Widget);
-
- Field.init = function(
- data, name, meta, level, editable, removable
- ) {
- this.name = name;
- this.editable = editable && meta.editable;
-
- var el = _.bind(Widget.init, this)(
+ var Field = Widget.extend({
+ init: function(
data, name, meta, level, editable, removable
- );
-
- if (this.editable)
- this.field.change(_.bind(this.validate, this));
-
- return el;
- };
-
- Field.staticRender = function(value) {
- return $("<td>").text(value);
- };
+ ) {
+ this.name = name;
+ this.editable = editable && meta.editable;
+
+ var el = this.super(
+ Field,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
- Field.makeEl = function() {
- _.bind(Widget.makeEl, this)();
- if (!this.field) this.field = this.el;
- };
+ if (this.editable)
+ this.field.change(_.bind(this.validate, this));
+
+ return el;
+ },
- Field.createEl = function() { return $("<input>"); };
+ staticRender: function(value) {
+ return $("<td>").text(value);
+ },
- Field.render = function(value, meta) {
- this.field.attr({type: "text", value: value});
- };
+ makeEl: function() {
+ this.super(Field, "makeEl");
+ if (!this.field) this.field = this.el;
+ },
- Field.wrap = function() {
- var td = $("<td>");
- this.msg = $("<div>");
- td.append(this.msg);
- td.append(this.el);
- return td;
- };
+ createEl: function() { return $("<input>"); },
- Field.validate = function() {
- _.bind(Widget.validate, this)();
- if (!this.visible || !this.editable) return;
+ render: function(value, meta) {
+ this.field.attr({type: "text", value: value});
+ },
- this.msg.text("[checking]");
- statusBar.setError("Validating changes", "validate");
+ wrap: function() {
+ var td = $("<td>");
+ this.msg = $("<div>");
+ td.append(this.msg);
+ td.append(this.el);
+ return td;
+ },
- var self = this;
-
- this.data.set(this.name, this.get()).done(function(txnValid) {
- self.msg.empty()
- self.setStatus(self.data.status(self.name));
- statusBar.validationReady(txnValid);
- self.el.trigger("validated");
-
- }).fail(function(xhr) {
- if (_.isString(xhr)) self.msg.text(xhr);
-
- else if (xhr.statusCode().status == 422)
- self.msg.html(
- _.reduce(
- _.map($.parseJSON(xhr.responseText), _.escape),
- function(a, b) { return a + "<br/>" + b; }
- )
- );
+ validate: function() {
+ this.super(Field, "validate");
+ if (!this.visible || !this.editable) return;
- else self.msg.text(formatError("Error", xhr));
-
- self.setStatus("invalid");
- statusBar.validationReady(false);
- });
- };
-
- Field.get = function() {
- return this.editable ? (
- this.field.val() || null
- ) : this.data.get(this.name);
- };
-
+ this.msg.text("[checking]");
+ statusBar.setError("Validating changes", "validate");
- var ComboBox = Object.create(Field);
-
- ComboBox.createEl = function() { return $("<select>"); };
-
- ComboBox.render = function(value, meta) {
- var el = this.field;
+ var self = this;
+
+ this.data.set(this.name, this.get())
+ .done(function(txnValid) {
+ self.msg.empty()
+ self.setStatus(self.data.status(self.name));
+ statusBar.validationReady(txnValid);
+ self.el.trigger("validated");
+
+ })
+ .fail(function(xhr) {
+ if (_.isString(xhr)) self.msg.text(xhr);
+
+ else if (xhr.statusCode().status == 422)
+ self.msg.html(
+ _.reduce(
+ _.map(
+ $.parseJSON(xhr.responseText),
+ _.escape
+ ),
+ function(a, b) {
+ return a + "<br/>" + b;
+ }
+ )
+ );
+
+ else self.msg.text(formatError("Error", xhr));
+
+ self.setStatus("invalid");
+ statusBar.validationReady(false);
+ });
+ },
- function opt(value, ui_value, selected) {
- el.append($("<option>").attr(
- {value: value, selected: selected}
- ).text(ui_value));
+ get: function() {
+ return this.editable ? (
+ this.field.val() || null
+ ) : this.data.get(this.name);
}
+ });
- if (!meta.required)
- opt("", "(none)", value == null)
- _.each(
- meta.choice,
- function(choice) {
- var selected = value == choice.value;
- if (choice.enabled || selected)
- opt(choice.value, choice["ui-value"], selected);
- }
- );
- }
+ var ComboBox = Field.extend({
+ createEl: function() { return $("<select>"); },
- var CheckBox = Object.create(Field);
- CheckBox.staticRender = function(value) {
- return $("<td>").text(value ? "Yes" : "No");
- };
+ render: function(value, meta) {
+ var el = this.field;
- CheckBox.statusEl = function() { return this.el.parent(); };
+ function opt(value, ui_value, selected) {
+ el.append($("<option>").attr(
+ {value: value, selected: selected}
+ ).text(ui_value));
+ }
- CheckBox.render = function(value, meta) {
- this.field.attr({type: "checkbox", checked: value});
- };
+ if (!meta.required) opt("", "(none)", value == null);
- CheckBox.get = function() { return this.field.is(":checked"); };
+ _.each(
+ meta.choice,
+ function(choice) {
+ var selected = value == choice.value;
+ if (choice.enabled || selected)
+ opt(choice.value, choice["ui-value"], selected);
+ }
+ );
+ }
+ });
+ var CheckBox = Field.extend({
+ staticRender: function(value) {
+ return $("<td>").text(value ? "Yes" : "No");
+ },
- var Link = Object.create(Widget);
+ statusEl: function() { return this.el.parent(); },
- Link.staticRender = objectRef;
+ render: function(value, meta) {
+ this.field.attr({type: "checkbox", checked: value});
+ },
- Link.createEl = function() { return href(); };
+ get: function() { return this.field.is(":checked"); }
+ });
- Link.render = function(value, meta) {
- this.staticRender(value, this.el)
- };
- Link.wrap = function() { return $("<td>").html(this.el); };
+ var Link = Widget.extend({
+ staticRender: objectRef,
- Link.get = function() { return {}; };
+ createEl: href,
+ render: function(value, meta) {
+ this.staticRender(value, this.el)
+ },
- Inline = Object.create(Link);
+ wrap: function() { return $("<td>").html(this.el); },
+
+ get: function() { return {}; }
+ });
- Inline.init = function(
- data, name, meta, level, editable, removable
- ) {
- return _.bind(Link.init, this)(
- data,
- name,
- meta,
- Math.min(6, level + 1),
- editable,
- removable
- );
- };
- Inline.showStatus = false;
+ var Inline = Link.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ return this.super(
+ Inline,
+ "init",
+ data,
+ name,
+ meta,
+ Math.min(6, level + 1),
+ editable,
+ removable
+ );
+ },
- Inline.requestData = function(value, meta) {
- var def = $.Deferred();
- txnMgr.query(value).done(function(data) {
- def.resolve(data, data.meta);
- });
- return def;
- };
+ showStatus: false,
+
+ requestData: function(value, meta) {
+ var def = $.Deferred();
+ txnMgr.query(value).done(function(data) {
+ def.resolve(data, data.meta);
+ });
+ return def;
+ },
- Inline.render = function(data, meta) {
- this.renderFields(data, meta);
- };
+ render: function(data, meta) {
+ this.renderFields(data, meta);
+ },
- Inline.renderFields = function(data, meta) {
- this.reqData = data;
- var self = this;
-
- if (data.meta.type == "model") {
- this.fields = {};
- _.each(data.meta.fields, function(field) {
- self.fields[field.name] = self.renderField(
- field.name,
- field,
- field["ui-name"],
- true,
- false
- );
- });
+ renderFields: function(data, meta) {
+ this.reqData = data;
+ var self = this;
+
+ if (data.meta.type == "model") {
+ this.fields = {};
+ _.each(data.meta.fields, function(field) {
+ self.fields[field.name] = self.renderField(
+ field.name,
+ field,
+ field["ui-name"],
+ true,
+ false
+ );
+ });
+
+ _.each(this.fields, function(f1, name) {
+ _.each(self.fields, function(f2) {
+ if (f1 != f2)
+ f1.on("validated", function(event) {
+ f2.trigger("updated", [name]);
+ event.stopPropagation();
+ });
+ });
+ });
- _.each(this.fields, function(f1, name) {
- _.each(self.fields, function(f2) {
- if (f1 != f2)
- f1.on("validated", function(event) {
- f2.trigger("updated", [name]);
- event.stopPropagation();
- });
+ _.each(this.fields, function(field) {
+ field.trigger("start");
});
- });
+ }
+
+ else _.each(data.data, function(value, name) {
+ if (data.meta.type == "set") name = data.data[name];
+ else if (_.isArray(data.data)) name++;
+ self.renderCollectionMember(name, data.meta);
+ });
+ },
- _.each(this.fields, function(field) {
- field.trigger("start");
+ renderField: function(
+ name, meta, label, editable, removable
+ ) {
+ var widget = this.widget(meta).new(
+ this.reqData,
+ name,
+ meta,
+ this.level,
+ editable,
+ removable
+ );
+ var container = this.appendWidget(widget, label);
+ widget.on("setVisible", function(event, visible) {
+ if (visible) container.show();
+ else container.hide();
+ event.stopPropagation();
});
- }
+ return widget;
+ },
- else _.each(data.data, function(value, name) {
- if (data.meta.type == "set") name = data.data[name];
- else if (_.isArray(data.data)) name++;
- self.renderCollectionMember(name, data.meta);
- });
- };
-
- Inline.renderField = function(
- name, meta, label, editable, removable
- ) {
- var widget = Object.create(this.widget(meta)).init(
- this.reqData,
- name,
- meta,
- this.level,
- editable,
- removable
- );
- var container = this.appendWidget(widget, label);
- widget.on("setVisible", function(event, visible) {
- if (visible) container.show();
- else container.hide();
- event.stopPropagation();
- });
- return widget;
- }
+ renderCollectionMember: function(name, meta) {
+ var set = meta.type == "set";
+ this.renderField(
+ name,
+ meta.members,
+ meta["ui-member"] + " " + name,
+ !set,
+ !set
+ ).trigger("start");
+ },
- Inline.renderCollectionMember = function(name, meta) {
- var set = meta.type == "set";
- this.renderField(
- name,
- meta.members,
- meta["ui-member"] + " " + name,
- !set,
- !set
- ).trigger("start");
- };
+ widget: function(meta) { return widgets[meta.widget]; },
+
+ wrap: function() { return this.el; },
- Inline.widget = function(meta) { return widgets[meta.widget]; };
+ validate: function() {
+ this.super(Inline, "validate");
+
+ var self = this;
+ this.request.done(function(data, meta) {
+ if (self.data.match(self.meta.condition)) {
+ var valid = data.validate();
+ self.setStatus(data.status());
+ statusBar.validationReady(valid);
+ }
+
+ if (self.fields)
+ _.each(self.fields, function(field) {
+ field.trigger("updated");
+ });
+ });
+ }
+ });
- Inline.wrap = function() { return this.el; };
- Inline.validate = function() {
- _.bind(Link.validate, this)();
+ var Horizontal = Inline.extend({
+ createEl: function() {
+ this.previous = null;
+ return $("<tr>").html($("<td>").prop(
+ "class", "placeholder"
+ ));
+ },
- var self = this;
- this.request.done(function(data, meta) {
- if (self.data.match(self.meta.condition)) {
- var valid = data.validate();
- self.setStatus(data.status());
- statusBar.validationReady(valid);
+ appendWidget: function(el, label) {
+ if (!el.is("td")) return null;
+ if (this.previous) this.previous.after(el);
+ else {
+ var ph = this.el.find(".placeholder");
+ ph.after(el);
+ ph.remove();
}
-
- if (self.fields)
- _.each(self.fields, function(field) {
- field.trigger("updated");
- });
- });
- };
-
-
- var Horizontal = Object.create(Inline);
-
- Horizontal.createEl = function() {
- this.previous = null;
- return $("<tr>").html($("<td>").prop(
- "class", "placeholder"
- ));
- };
-
- Horizontal.appendWidget = function(el, label) {
- if (!el.is("td")) return null;
- if (this.previous) this.previous.after(el);
- else {
- var ph = this.el.find(".placeholder");
- ph.after(el);
- ph.remove();
+ this.previous = el;
+ return el;
}
- this.previous = el;
- return el;
- };
-
-
- var HeaderHorizontal = Object.create(Horizontal);
-
- HeaderHorizontal.init = function(
- data, name, meta, level, editable, removable
- ) {
- this.header = $("<tr>");
- var table = $("<table>").html(this.header);
- table.append(
- _.bind(Horizontal.init, this)(
- data, name, meta, level, editable, removable
- )
- );
- return table;
- };
+ });
- HeaderHorizontal.appendWidget = function(el, label) {
- el = _.bind(Horizontal.appendWidget, this)(el, label);
- if (el) this.header.append($("<th>").text(label));
- return el;
- };
+ var HeaderHorizontal = Horizontal.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.header = $("<tr>");
+ var table = $("<table>").html(this.header);
+ table.append(
+ this.super(
+ HeaderHorizontal,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ )
+ );
+ return table;
+ },
+
+ appendWidget: function(el, label) {
+ el = this.super(
+ HeaderHorizontal, "appendWidget", el, label
+ );
+ if (el) this.header.append($("<th>").text(label));
+ return el;
+ }
+ });
- var HeaderInline = Object.create(Inline);
- HeaderInline.createEl = function() { return $("<div>"); };
+ var HeaderInline = Inline.extend({
+ createEl: function() { return $("<div>"); },
- HeaderInline.render = function(data, meta) {
- this.el.append(
- $("<h" + this.level + ">").text(data.meta["ui-name"])
- );
- };
+ render: function(data, meta) {
+ this.el.append(
+ $("<h" + this.level + ">").text(data.meta["ui-name"])
+ );
+ }
+ });
- var Vertical = Object.create(HeaderInline);
+ var Vertical = HeaderInline.extend({
+ wrap: function() { return $("<div>").html(this.el); },
+
+ render: function(data, meta) {
+ this.super(Vertical, "render", data, meta);
+
+ if (!isTreeNode(data.meta))
+ return this.el.append(JSON.stringify(data));
+
+ this.div = $("<div>");
+ this.el.append(this.div);
- Vertical.wrap = function() { return $("<div>").html(this.el); };
+ var self = this;
+
+ if (data.meta.type == "model")
+ _.each(data.meta.actions, function(action) {
+ self.div.append($("<input>").attr(
+ {type: "submit", value: action["ui-name"]}
+ ).click(function() {
+ data.invoke(action.name).done(function() {
+ alert("Done");
+ }).fail(function() {
+ alert("Failed");
+ });
+ }));
+ });
+
+ this.renderFields(data, meta);
+
+ if (_.contains(["collection", "list"], data.meta.type)) {
+ var keys = _.clone(_.keys(data.data));
+
+ var button = $("<input>").attr(
+ {type: "submit", value: "Insert"}
+ ).click(function() {
+
+ var getter;
+
+ function insert() {
+ var name = getter();
+
+ if (_.contains(keys, name)) {
+ button.prop("class", null);
+ return;
+ }
+ keys.push(name);
+
+ data.set(
+ name,
+ isTreeNode(data.meta.members) ? {} : null
+ ).done(function(txnValid) {
+ self.renderCollectionMember(
+ name, data.meta
+ );
+ button.prop("class", null);
+ statusBar.validationReady(txnValid);
+ });
+ }
- Vertical.render = function(data, meta) {
- _.bind(HeaderInline.render, this)(data, meta);
+ button.prop("class", "hidden");
+
+ if (data.meta.type == "collection") {
+ var field = $("<input>").attr({type: "text"});
+ var row = $("<tr>").html($("<td>").html(field));
+ getter = function() {
+ var res = field.val();
+ row.remove();
+ return res;
+ }
+ field.change(insert);
+ self.appendRow(row);
+ }
+ else {
+ getter = function() {
+ return data.data.length + 1;
+ };
+ insert();
+ }
+ });
+ this.el.append($("<p>").html(button));
+ }
+ },
- if (!isTreeNode(data.meta))
- return this.el.append(JSON.stringify(data));
+ appendWidget: function(el, label) {
+ var self = this;
+ el = makeRow(el);
+
+ if (el.is("tr")) {
+ el.prepend($("<td>").text(label));
+ this.appendRow(el);
+ }
+ else if (el.is("table")) {
+ var td;
+ el.find("tr").each(function(index, row) {
+ td = $("<td>");
+ $(row).prepend(td);
+ self.appendRow(row);
+ });
+ td.text(label);
+ return null;
+ }
+ else {
+ this.table = null;
+ this.div.append(el);
+ }
+
+ return el;
+ },
- this.div = $("<div>");
- this.el.append(this.div);
+ appendRow: function(row) {
+ if (!this.table) {
+ this.table = $("<table>");
+ this.div.append(this.table);
+ }
+ this.table.append(row);
+ }
+ });
- var self = this;
-
- if (data.meta.type == "model")
- _.each(data.meta.actions, function(action) {
- self.div.append($("<input>").attr(
- {type: "submit", value: action["ui-name"]}
- ).click(function() {
- data.invoke(action.name).done(function() {
- alert("Done");
- }).fail(function() {
- alert("Failed");
- });
- }));
- });
- this.renderFields(data, meta);
+ var CheckBoxes = HeaderInline.extend({
+ showStatus: true,
- if (_.contains(["collection", "list"], data.meta.type)) {
- var keys = _.clone(_.keys(data.data));
+ setStatus: function(status) {
+ this.super(
+ CheckBoxes,
+ "setStatus",
+ status == "invalid" ? "invalid" : null
+ );
+ },
+
+ render: function(data, meta) {
+ this.super(CheckBoxes, "render", data, meta);
- var button = $("<input>").attr(
- {type: "submit", value: "Insert"}
- ).click(function() {
+ var table = $("<table>");
+ this.el.append(table);
+
+ var self = this;
+
+ _.each(meta.members.choice, function(choice) {
+ var selected = _.contains(data.data, choice.value);
+ if (!(choice.enabled || selected)) return;
- var getter;
+ var cbox = $("<input>").attr({
+ type: "checkbox", checked: selected
+ });
- function insert() {
- var name = getter();
-
- if (_.contains(keys, name)) {
- button.prop("class", null);
- return;
- }
- keys.push(name);
-
- data.set(
- name, isTreeNode(data.meta.members) ? {} : null
+ var row = $("<tr>");
+ row.append($("<td>").html(cbox));
+
+ var item = $("<td>");
+ if (choice.ref)
+ item.html(objectRef(choice.ref)
+ .text(choice["ui-value"]));
+ else item.text(choice["ui-value"]);
+ row.append(item);
+
+ function setRowStatus() {
+ setStatus(row, data.status(choice.value));
+ }
+ setRowStatus();
+
+ cbox.change(function() {
+ (
+ cbox.is(":checked") ?
+ data.add(choice.value) :
+ data.delete(choice.value)
).done(function(txnValid) {
- self.renderCollectionMember(name, data.meta);
- button.prop("class", null);
+ self.setStatus(data.status());
+ setRowStatus();
statusBar.validationReady(txnValid);
});
- }
-
- button.prop("class", "hidden");
-
- if (data.meta.type == "collection") {
- var field = $("<input>").attr({type: "text"});
- var row = $("<tr>").html($("<td>").html(field));
- getter = function() {
- var res = field.val();
- row.remove();
- return res;
- }
- field.change(insert);
- self.appendRow(row);
- }
- else {
- getter = function() {
- return data.data.length + 1;
- };
- insert();
- }
- });
- this.el.append($("<p>").html(button));
- }
- };
-
- Vertical.appendWidget = function(el, label) {
- var self = this;
- el = makeRow(el);
+ });
- if (el.is("tr")) {
- el.prepend($("<td>").text(label));
- this.appendRow(el);
- }
- else if (el.is("table")) {
- var td;
- el.find("tr").each(function(index, row) {
- td = $("<td>");
- $(row).prepend(td);
- self.appendRow(row);
+ table.append(row);
});
- td.text(label);
- return null;
- }
- else {
- this.table = null;
- this.div.append(el);
- }
-
- return el;
- };
-
- Vertical.appendRow = function(row) {
- if (!this.table) {
- this.table = $("<table>");
- this.div.append(this.table);
}
- this.table.append(row);
- };
-
-
- var CheckBoxes = Object.create(HeaderInline);
-
- CheckBoxes.showStatus = true;
-
- CheckBoxes.setStatus = function(status) {
- _.bind(HeaderInline.setStatus, this)(
- status == "invalid" ? "invalid" : null
- );
- }
-
- CheckBoxes.render = function(data, meta) {
- _.bind(HeaderInline.render, this)(data, meta);
-
- var table = $("<table>");
- this.el.append(table);
-
- var self = this;
-
- _.each(meta.members.choice, function(choice) {
- var selected = _.contains(data.data, choice.value);
- if (!(choice.enabled || selected)) return;
-
- var cbox = $("<input>").attr({
- type: "checkbox", checked: selected
- });
-
- var row = $("<tr>");
- row.append($("<td>").html(cbox));
-
- var item = $("<td>");
- if (choice.ref)
- item.html(objectRef(choice.ref)
- .text(choice["ui-value"]));
- else item.text(choice["ui-value"]);
- row.append(item);
-
- function setRowStatus() {
- setStatus(row, data.status(choice.value));
- }
- setRowStatus();
-
- cbox.change(function() {
- (
- cbox.is(":checked") ?
- data.add(choice.value) :
- data.delete(choice.value)
- ).done(function(txnValid) {
- self.setStatus(data.status());
- setRowStatus();
- statusBar.validationReady(txnValid);
- });
- });
-
- table.append(row);
- });
- };
-
+ });
- var Reference = Object.create(ComboBox);
- Reference.init = function(
- data, name, meta, level, editable, removable
- ) {
- this.field = ComboBox.createEl();
- return _.bind(ComboBox.init, this)(
+ var Reference = ComboBox.extend({
+ init: function(
data, name, meta, level, editable, removable
- );
- };
-
- Reference.staticRender = function(value) {
- return objectRef(value).text(value);
- };
-
- Reference.statusEl = function() { return this.el.find("select"); };
-
- Reference.createEl = function() { return $("<div>"); };
-
- Reference.render = function(value, meta) {
- _.bind(ComboBox.render, this)(value, meta);
-
- this.el.html(this.field);
- this.el.append(" ");
-
- var link = $("<div>");
- var update = _.bind(function() {
- link.html(objectRef(this.get()));
- }, this);
- this.el.append(link);
+ ) {
+ this.field = ComboBox.createEl();
+ return this.super(
+ Reference,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
+ },
+
+ staticRender: function(value) {
+ return objectRef(value).text(value);
+ },
+
+ statusEl: function() { return this.el.find("select"); },
- this.field.change(update);
- update();
- };
+ createEl: function() { return $("<div>"); },
+
+ render: function(value, meta) {
+ this.super(Reference, "render", value, meta);
+
+ this.el.html(this.field);
+ this.el.append(" ");
+
+ var link = $("<div>");
+ var update = _.bind(function() {
+ link.html(objectRef(this.get()));
+ }, this);
+ this.el.append(link);
+
+ this.field.change(update);
+ update();
+ }
+ });
var widgets = {
@@ -1090,26 +1147,28 @@ $(function() {
};
- var Tabular = Object.create(Vertical);
-
- Tabular.render = function(data, meta) {
- this.header = true;
- _.bind(Vertical.render, this)(data, meta);
- };
-
- Tabular.widget = function(meta) {
- if (!isTreeNode(meta)) return Vertical.widget(meta);
- if (!this.header) return Horizontal;
- this.header = false;
- return HeaderHorizontal;
- };
-
+ var Tabular = Vertical.extend({
+ render: function(data, meta) {
+ this.header = true;
+ this.super(Tabular, "render", data, meta);
+ },
+
+ widget: function(meta) {
+ if (!isTreeNode(meta))
+ return this.super(Tabular, "widget", meta);
+ if (!this.header) return Horizontal;
+ this.header = false;
+ return HeaderHorizontal;
+ }
+ });
- var Stacked = Object.create(Vertical);
- Stacked.widget = function(meta) {
- return isTreeNode(meta) ? Vertical : Vertical.widget(meta);
- };
+ var Stacked = Vertical.extend({
+ widget: function(meta) {
+ return isTreeNode(meta) ?
+ Vertical : this.super(Stacked, "widget", meta);
+ }
+ });
var layouts = {stacked: Stacked, tabular: Tabular};
@@ -1124,19 +1183,14 @@ $(function() {
data ? $.Deferred().resolve(data) : txnMgr.query(path)
).done(function(data) {
var layout = data.meta.widget;
- var form = Object.create(layout ? layouts[layout] : Vertical);
-
- form.createEl = function() {
- return $("#content").empty();
- };
- form.wrap = function() { return this.el; };
- form.requestData = function(value, meta) {
- return $.Deferred().resolve(data, meta);
- };
-
var name = split(path).pop();
-
- form.init(
+ (layout ? layouts[layout] : Vertical).extend({
+ createEl: function() { return $("#content").empty(); },
+ wrap: function() { return this.el; },
+ requestData: function(value, meta) {
+ return $.Deferred().resolve(data, meta);
+ }
+ }).new(
{
get: function(name) { return path; },
status: function(name) { return null; },