diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-12-07 18:10:31 +0200 |
---|---|---|
committer | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-12-11 13:01:39 +0200 |
commit | bdebf89f5d7661b0bb360b4484c85a3ddcd3e249 (patch) | |
tree | 5f5c10824867ff739b26a91d97942f5b1bf78b50 /web/client.js | |
parent | be2cb5052a6bc3f7c0cde79d15be9e5babc6a970 (diff) | |
download | aconf-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/client.js')
-rw-r--r-- | web/client.js | 173 |
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) |