summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-07 18:10:31 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-11 13:01:39 +0200
commitbdebf89f5d7661b0bb360b4484c85a3ddcd3e249 (patch)
tree5f5c10824867ff739b26a91d97942f5b1bf78b50 /web
parentbe2cb5052a6bc3f7c0cde79d15be9e5babc6a970 (diff)
downloadaconf-bdebf89f5d7661b0bb360b4484c85a3ddcd3e249.tar.bz2
aconf-bdebf89f5d7661b0bb360b4484c85a3ddcd3e249.tar.xz
web client: refactor widget interface
use jQuery events for inter-widget communication avoid invocation of other inherited methods other than those of the direct ancestor
Diffstat (limited to 'web')
-rw-r--r--web/client.js173
1 files changed, 90 insertions, 83 deletions
diff --git a/web/client.js b/web/client.js
index b456e07..89cb341 100644
--- a/web/client.js
+++ b/web/client.js
@@ -457,11 +457,23 @@ $(function() {
return $("<a>").attr({href: "javascript:void(0);"});
}
+ function objectRef(value, el) {
+ el = el || href();
+ if (value) {
+ el.click(function() {
+ $.bbq.pushState("#" + value);
+ }).text("Show");
+ }
+ return el;
+ };
+
function makeRow(el) {
if (el.is("td")) return $("<tr>").html(el);
return el;
}
+ function setStatus(el, status) { el.prop("class", status); }
+
var Widget = {
init: function(data, name, meta, level, editable, removable) {
@@ -474,7 +486,7 @@ $(function() {
if (!editable || meta.editable == false) {
var el = this.staticRender(value);
- this.setElStatus(el, status);
+ setStatus(el, status);
return el;
}
@@ -487,7 +499,8 @@ $(function() {
self.setStatus(status);
});
- var el = this.wrap();
+ this.wrapped = this.wrap();
+ this.visible = true;
if (removable) {
var link = href().click(function() {
@@ -496,16 +509,25 @@ $(function() {
renderObject();
})
}).text("Delete");
- el = makeRow(el);
- if (el.is("tr")) link = $("<td>").html(link);
- el.append(link);
+ this.wrapped = makeRow(this.wrapped);
+ if (this.wrapped.is("tr")) link = $("<td>").html(link);
+ this.wrapped.append(link);
}
- return el;
- },
+ this.wrapped.on("start", function(event) {
+ if (data.status(name) == "invalid") self.validate();
+ else self.setVisible();
+ event.stopPropagation();
+ });
- setElStatus: function(el, status) {
- el.prop("class", status);
+ this.wrapped.on("updated", function(event, field) {
+ if (!field ||
+ (meta.condition && field in meta.condition))
+ self.validate();
+ event.stopPropagation();
+ });
+
+ return this.wrapped;
},
makeEl: function() { this.el = this.createEl(); },
@@ -516,33 +538,22 @@ $(function() {
wrap: function() { return this.el; },
+ showStatus: true,
+
setStatus: function(status) {
- if (this.el) this.setElStatus(this.el, status);
+ if (this.el && this.showStatus)
+ setStatus(this.statusEl(), status);
},
- setContainer: function(container) {
- this.container = container;
- this.setVisible();
- },
+ statusEl: function() { return this.el; },
setVisible: function() {
- if (!this.container) return true;
- var visible = this.data.match(this.meta.condition);
- if (visible) this.container.show();
- else this.container.hide();
- return visible;
- },
-
- depends: function(field) {
- if (field.el)
- field.el.on("validated", _.bind(this.validate, this));
+ this.visible = this.data.match(this.meta.condition);
+ if (this.wrapped)
+ this.wrapped.trigger("setVisible", [this.visible]);
},
- validate: function() { this.setVisible(); },
-
- validateIfInvalid: function() {
- if (this.data.status(name) == "invalid") this.validate();
- }
+ validate: function() { this.setVisible(); }
};
@@ -588,7 +599,8 @@ $(function() {
};
Field.validate = function() {
- if (!this.setVisible() || !this.editable) return;
+ _.bind(Widget.validate, this)();
+ if (!this.visible || !this.editable) return;
this.msg.text("[checking]");
statusBar.setError("Validating changes", "validate");
@@ -657,9 +669,7 @@ $(function() {
return $("<td>").text(value ? "Yes" : "No");
};
- CheckBox.setElStatus = function(el, status) {
- Field.setElStatus(el.parent(), status);
- };
+ CheckBox.statusEl = function() { return this.el.parent(); };
CheckBox.render = function(value, meta) {
this.field.attr({type: "checkbox", checked: value});
@@ -670,15 +680,7 @@ $(function() {
var Link = Object.create(Widget);
- Link.staticRender = function(value, el) {
- el = el || href();
- if (value) {
- el.click(function() {
- $.bbq.pushState("#" + value);
- }).text("Show");
- }
- return el;
- };
+ Link.staticRender = objectRef;
Link.createEl = function() { return href(); };
@@ -706,7 +708,7 @@ $(function() {
);
};
- Inline.setStatus = function(status) {};
+ Inline.showStatus = false;
Inline.requestData = function(value, meta) {
var def = $.Deferred();
@@ -717,6 +719,10 @@ $(function() {
};
Inline.render = function(data, meta) {
+ this.renderFields(data, meta);
+ };
+
+ Inline.renderFields = function(data, meta) {
this.reqData = data;
var self = this;
@@ -732,17 +738,18 @@ $(function() {
);
});
- _.each(data.meta.fields, function(field) {
- if (field.condition)
- _.each(field.condition, function(values, key) {
- self.fields[field.name].depends(
- self.fields[key]
- );
- });
+ _.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.validateIfInvalid();
+ field.trigger("start");
});
}
@@ -756,21 +763,20 @@ $(function() {
Inline.renderField = function(
name, meta, label, editable, removable
) {
- var widget = Object.create(this.widget(meta));
- widget.setContainer(
- this.appendWidget(
- widget.init(
- this.reqData,
- name,
- meta,
- this.level,
- editable,
- removable
- ),
- label
- )
+ var widget = Object.create(this.widget(meta)).init(
+ this.reqData,
+ name,
+ meta,
+ this.level,
+ editable,
+ removable
);
- widget.setStatus(this.reqData.status(name));
+ var container = this.appendWidget(widget, label);
+ widget.on("setVisible", function(event, visible) {
+ if (visible) container.show();
+ else container.hide();
+ event.stopPropagation();
+ });
return widget;
}
@@ -782,7 +788,7 @@ $(function() {
meta["ui-member"] + " " + name,
!set,
!set
- ).validateIfInvalid();
+ ).trigger("start");
};
Inline.widget = function(meta) { return widgets[meta.widget]; };
@@ -802,7 +808,7 @@ $(function() {
if (self.fields)
_.each(self.fields, function(field) {
- field.validate();
+ field.trigger("updated");
});
});
};
@@ -891,7 +897,7 @@ $(function() {
}));
});
- _.bind(Inline.render, this)(data, meta);
+ this.renderFields(data, meta);
if (_.contains(["collection", "list"], data.meta.type)) {
var keys = _.clone(_.keys(data.data));
@@ -981,8 +987,10 @@ $(function() {
var CheckBoxes = Object.create(HeaderInline);
+ CheckBoxes.showStatus = true;
+
CheckBoxes.setStatus = function(status) {
- _.bind(Link.setStatus, this)(
+ _.bind(HeaderInline.setStatus, this)(
status == "invalid" ? "invalid" : null
);
}
@@ -1007,16 +1015,16 @@ $(function() {
row.append($("<td>").html(cbox));
var item = $("<td>");
- if (choice.ref) item.html(
- Link.staticRender(choice.ref).text(choice["ui-value"])
- );
+ if (choice.ref)
+ item.html(objectRef(choice.ref)
+ .text(choice["ui-value"]));
else item.text(choice["ui-value"]);
row.append(item);
- function setStatus() {
- self.setElStatus(row, data.status(choice.value));
+ function setRowStatus() {
+ setStatus(row, data.status(choice.value));
}
- setStatus();
+ setRowStatus();
cbox.change(function() {
(
@@ -1025,7 +1033,7 @@ $(function() {
data.delete(choice.value)
).done(function(txnValid) {
self.setStatus(data.status());
- setStatus();
+ setRowStatus();
statusBar.validationReady(txnValid);
});
});
@@ -1047,12 +1055,10 @@ $(function() {
};
Reference.staticRender = function(value) {
- return Link.staticRender(value).text(value);
+ return objectRef(value).text(value);
};
- Reference.setElStatus = function(el, status) {
- ComboBox.setElStatus(el.find("select"), status);
- };
+ Reference.statusEl = function() { return this.el.find("select"); };
Reference.createEl = function() { return $("<div>"); };
@@ -1064,7 +1070,7 @@ $(function() {
var link = $("<div>");
var update = _.bind(function() {
- link.html(Link.staticRender(this.get()));
+ link.html(objectRef(this.get()));
}, this);
this.el.append(link);
@@ -1133,7 +1139,8 @@ $(function() {
form.init(
{
get: function(name) { return path; },
- status: function(name) { return null; }
+ status: function(name) { return null; },
+ match: function(filter) { return true; }
},
name,
{},
@@ -1176,7 +1183,7 @@ $(function() {
}
var el = $("<li>");
- var link = Link.staticRender(data.get(field.name));
+ var link = objectRef(data.get(field.name));
link.text(field["ui-name"]);
el.prop("class", data.status(field.name));
if (field.name == current)