summaryrefslogtreecommitdiffstats
path: root/web/client.js
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-06 11:34:26 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-02-12 12:38:31 +0200
commitcbd09bd37c87539889f6be688276a84bc57e5bf5 (patch)
treed116b74b81a9aebf1979a811cb910f069ce955db /web/client.js
parent62c559013516b74d59ef54ea316f8dc35ef2f477 (diff)
downloadaconf-cbd09bd37c87539889f6be688276a84bc57e5bf5.tar.bz2
aconf-cbd09bd37c87539889f6be688276a84bc57e5bf5.tar.xz
web client: use RequireJS for dependency management
Diffstat (limited to 'web/client.js')
-rw-r--r--web/client.js2558
1 files changed, 1290 insertions, 1268 deletions
diff --git a/web/client.js b/web/client.js
index f4fd89d..25cf988 100644
--- a/web/client.js
+++ b/web/client.js
@@ -3,1494 +3,1516 @@
* See LICENSE file for license details
*/
-$(function() {
- $("#login").submit(function() {
-
- var statusBar = (function() {
- function set(status, msg, mode) {
- $("#status").prop("class", status);
- $("#status p").text(msg);
- $("#logout").prop("class", mode ? "hidden" : null);
- $("#status div").prop("class", mode == "txn" ? null : "hidden");
- $("#commit").prop("disabled", status == "invalid");
- }
-
- function setError(msg, mode) { set("invalid", msg, mode); };
-
- return {
- reset: function() { set(null, ""); },
- setError: setError,
- validationReady: function(txnValid) {
- if (txnValid)
- set("changed", "You have uncommitted changes", "txn");
- else setError("Some values need checking", "txn");
- }
- }
- })();
-
- $.ajax("/login", {
- type: "POST",
- data: JSON.stringify({
- username: $("#username").val(), password: $("#password").val()
- })
- }).done(function(data, status, xhr) {
-
- function split(path) {
- var res = [];
- while (path && path != "/") {
- var comp = path.match(/^\/([^\\\/]|\\.)+/)[0];
- res.push(comp.substring(1));
- path = path.substring(comp.length);
- }
- return res;
- }
-
- function escape(name) {
- if (!_.isString(name)) return String(name);
- name = name.replace(/([\\\/])/g, "\\$1");
- if (isNaN(Number(name))) return name;
- return "\\" + name;
- }
-
- function join() {
- var arg = _.toArray(arguments);
- if (arg.length == 1) return arg[0];
-
- var path = arg.shift();
- var name = arg.shift();
-
- arg.unshift((path == "/" ? "" : path) + "/" + escape(name));
-
- return join.apply(undefined, arg);
- }
-
- function isSubordinate(p1, p2, real) {
- p1 = split(p1);
- p2 = split(p2);
- if (real && p1.length <= p2.length) return false;
- for (var i = 0; i < p2.length; i++)
- if (p1[i] != p2[i]) return false;
- return true;
- }
-
- function isList(meta) {
- return _.contains(["list", "set"], meta.type);
- }
-
- function isCollection(meta) {
- return meta.type == "collection" || isList(meta);
- }
-
- function isTreeNode(meta) {
- return meta.type == "model" || isCollection(meta);
- }
-
-
- var txnMgr = (function(token, saveRequired) {
- var txn, changed, invalid;
-
- function reset() {
- txn = null;
- changed = {};
- invalid = {};
+requirejs.config({
+ baseUrl: "lib",
+ shim: {
+ underscore: {exports: "_"},
+ "jquery-bbq": {deps: ["jquery"]},
+ "jquery-blockui": {deps: ["jquery"]},
+ "jquery-ui/core": {deps: ["jquery"]},
+ "jquery-ui/mouse": {deps: ["jquery-ui/widget"]},
+ "jquery-ui/sortable": {deps: ["jquery-ui/core", "jquery-ui/mouse"]},
+ "jquery-ui/widget": {deps: ["jquery"]},
+ }
+});
+
+require(
+ [
+ "jquery",
+ "underscore",
+ "jquery-bbq",
+ "jquery-blockui",
+ "jquery-ui/sortable"
+ ],
+ function($, _) {
+ $("#login").submit(function() {
+
+ var statusBar = (function() {
+ function set(status, msg, mode) {
+ $("#status").prop("class", status);
+ $("#status p").text(msg);
+ $("#logout").prop("class", mode ? "hidden" : null);
+ $("#status div").prop("class", mode == "txn" ? null : "hidden");
+ $("#commit").prop("disabled", status == "invalid");
}
- reset();
- function isValid() { return !(_.size(invalid)); }
+ function setError(msg, mode) { set("invalid", msg, mode); };
- function request(url, options) {
- options = options || {};
- options.headers = {"X-ACF-Auth-Token": token};
- if (txn) options.headers["X-ACF-Transaction-ID"] = txn;
- if (options.data != undefined)
- options.data = JSON.stringify(options.data);
- return $.ajax(url, options);
+ return {
+ reset: function() { set(null, ""); },
+ setError: setError,
+ validationReady: function(txnValid) {
+ if (txnValid)
+ set("changed", "You have uncommitted changes", "txn");
+ else setError("Some values need checking", "txn");
+ }
}
+ })();
- function abort() {
- request("/transaction", {type: "DELETE"});
- reset();
+ $.ajax("/login", {
+ type: "POST",
+ data: JSON.stringify({
+ username: $("#username").val(), password: $("#password").val()
+ })
+ }).done(function(data, status, xhr) {
+
+ function split(path) {
+ var res = [];
+ while (path && path != "/") {
+ var comp = path.match(/^\/([^\\\/]|\\.)+/)[0];
+ res.push(comp.substring(1));
+ path = path.substring(comp.length);
+ }
+ return res;
}
-
- function objRequest(path, options) {
- return request("/config" + path, options);
+
+ function escape(name) {
+ if (!_.isString(name)) return String(name);
+ name = name.replace(/([\\\/])/g, "\\$1");
+ if (isNaN(Number(name))) return name;
+ return "\\" + name;
}
- function exclusive(task) {
- $.blockUI();
+ function join() {
+ var arg = _.toArray(arguments);
+ if (arg.length == 1) return arg[0];
- var def = $.Deferred();
- function resolve(txnValid) { def.resolve(txnValid); }
- function reject() { def.reject(); }
+ var path = arg.shift();
+ var name = arg.shift();
- var tasks = _.filter(
- _.pluck(_.values(invalid), 1), function(d) {
- return d && d.state() == "pending";
- }
- );
+ arg.unshift((path == "/" ? "" : path) + "/" + escape(name));
- if (tasks.length)
- tasks[0].always(function() {
- exclusive(task).done(resolve).fail(reject);
- });
- else task().always($.unblockUI).done(resolve).fail(reject);
-
- return def;
+ return join.apply(undefined, arg);
+ }
+
+ function isSubordinate(p1, p2, real) {
+ p1 = split(p1);
+ p2 = split(p2);
+ if (real && p1.length <= p2.length) return false;
+ for (var i = 0; i < p2.length; i++)
+ if (p1[i] != p2[i]) return false;
+ return true;
+ }
+
+ function isList(meta) {
+ return _.contains(["list", "set"], meta.type);
+ }
+
+ function isCollection(meta) {
+ return meta.type == "collection" || isList(meta);
+ }
+
+ function isTreeNode(meta) {
+ return meta.type == "model" || isCollection(meta);
}
+
- function query(path) {
- var def = $.Deferred();
+ var txnMgr = (function(token, saveRequired) {
+ var txn, changed, invalid;
+
+ function reset() {
+ txn = null;
+ changed = {};
+ invalid = {};
+ }
+ reset();
- objRequest(path).done(function(data) {
- if (isTreeNode(data.meta) && !_.size(data.data))
- data.data = isList(data.meta) ? [] : {};
+ function isValid() { return !(_.size(invalid)); }
- function index(name) {
- return _.isArray(data.data) ? name - 1 : name;
- }
+ function request(url, options) {
+ options = options || {};
+ options.headers = {"X-ACF-Auth-Token": token};
+ if (txn) options.headers["X-ACF-Transaction-ID"] = txn;
+ if (options.data != undefined)
+ options.data = JSON.stringify(options.data);
+ return $.ajax(url, options);
+ }
+
+ function abort() {
+ request("/transaction", {type: "DELETE"});
+ reset();
+ }
+
+ function objRequest(path, options) {
+ return request("/config" + path, options);
+ }
- data.get = function(name, valid) {
- var p = join(path, name);
- if (!valid && p in invalid) return invalid[p][0];
+ function exclusive(task) {
+ $.blockUI();
- if (data.meta.type == "set") {
- return _.contains(
- data.data, name
- ) ? name : null;
- }
+ var def = $.Deferred();
+ function resolve(txnValid) { def.resolve(txnValid); }
+ function reject() { def.reject(); }
- return data.data[index(name)];
- };
-
- data.metaRequest = function(name) {
- return request("/meta" + join(path, name));
- };
-
- data.match = function(filter) {
- if (!filter) return true;
- return _.every(_.map(filter, function(values, key) {
- return _.contains(values, data.data[key]);
- }));
- };
-
- data.status = function(name) {
- var p = name ? join(path, name) : path;
- function scan(objs) {
- return _.size(_.filter(
- _.keys(objs), function(obj) {
- return isSubordinate(obj, p);
- }
- ));
+ var tasks = _.filter(
+ _.pluck(_.values(invalid), 1), function(d) {
+ return d && d.state() == "pending";
}
+ );
+
+ if (tasks.length)
+ tasks[0].always(function() {
+ exclusive(task).done(resolve).fail(reject);
+ });
+ else task().always($.unblockUI).done(resolve).fail(reject);
+
+ return def;
+ }
+
+ function query(path) {
+ var def = $.Deferred();
- if (scan(invalid)) return "invalid";
- if (scan(changed)) return "changed";
- return null;
- };
-
- data.validate = function() {
- var valid = true;
- if (data.meta.required) {
- valid = _.size(data.data);
- if (valid) delete invalid[path];
- else invalid[path] = [path];
+ objRequest(path).done(function(data) {
+ if (isTreeNode(data.meta) && !_.size(data.data))
+ data.data = isList(data.meta) ? [] : {};
+
+ function index(name) {
+ return _.isArray(data.data) ? name - 1 : name;
}
- return valid && isValid();
- };
- data.set = function(name, newValue) {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
+ data.get = function(name, valid) {
+ var p = join(path, name);
+ if (!valid && p in invalid) return invalid[p][0];
- var mpath = join(path, name);
+ if (data.meta.type == "set") {
+ return _.contains(
+ data.data, name
+ ) ? name : null;
+ }
- var value = data.get(name, true);
- if (value == undefined) value = null;
+ return data.data[index(name)];
+ };
+
+ data.metaRequest = function(name) {
+ return request("/meta" + join(path, name));
+ };
+
+ data.match = function(filter) {
+ if (!filter) return true;
+ return _.every(_.map(filter, function(values, key) {
+ return _.contains(values, data.data[key]);
+ }));
+ };
+
+ data.status = function(name) {
+ var p = name ? join(path, name) : path;
+ function scan(objs) {
+ return _.size(_.filter(
+ _.keys(objs), function(obj) {
+ return isSubordinate(obj, p);
+ }
+ ));
+ }
- var tn = _.isObject(newValue);
- var npv = tn ? mpath : newValue;
+ if (scan(invalid)) return "invalid";
+ if (scan(changed)) return "changed";
+ return null;
+ };
+
+ data.validate = function() {
+ var valid = true;
+ if (data.meta.required) {
+ valid = _.size(data.data);
+ if (valid) delete invalid[path];
+ else invalid[path] = [path];
+ }
+ return valid && isValid();
+ };
- function ignore(path) {
- _.each(_.keys(invalid), function(p) {
- if (isSubordinate(p, path))
- delete invalid[p];
- });
- }
+ data.set = function(name, newValue) {
+ var def = $.Deferred();
+ function reject(xhr) { def.reject(xhr); }
- function resolve() {
- if (mpath in invalid &&
- invalid[mpath][1] == def) {
-
- var del = invalid[mpath][0] == null;
+ var mpath = join(path, name);
+
+ var value = data.get(name, true);
+ if (value == undefined) value = null;
- delete invalid[mpath];
- if (del) ignore(mpath);
+ var tn = _.isObject(newValue);
+ var npv = tn ? mpath : newValue;
+
+ function ignore(path) {
+ _.each(_.keys(invalid), function(p) {
+ if (isSubordinate(p, path))
+ delete invalid[p];
+ });
}
-
- def.resolve(isValid());
- }
- function validate() {
- var del = newValue == null;
- var set = data.meta.type == "set";
+ function resolve() {
+ if (mpath in invalid &&
+ invalid[mpath][1] == def) {
+
+ var del = invalid[mpath][0] == null;
- var options;
- if (!del)
- options = {
- type: set ? "POST" : "PUT",
- data: newValue
- };
- else if (data.get(name, true) != null)
- options = {type: "DELETE"};
-
- if (!options) {
- if (data.meta.type == "model" &&
- _.findWhere(
- data.meta.fields, {name: name}
- ).required)
- def.reject("Required value not set");
- else resolve();
- return;
+ delete invalid[mpath];
+ if (del) ignore(mpath);
+ }
+
+ def.resolve(isValid());
}
-
- objRequest(
- set && !del ? path : mpath, options
- ).done(function() {
- if (!(mpath in changed))
- changed[mpath] = value;
- if (!tn && newValue == changed[mpath])
- delete changed[mpath];
+
+ function validate() {
+ var del = newValue == null;
+ var set = data.meta.type == "set";
+
+ var options;
+ if (!del)
+ options = {
+ type: set ? "POST" : "PUT",
+ data: newValue
+ };
+ else if (data.get(name, true) != null)
+ options = {type: "DELETE"};
+
+ if (!options) {
+ if (data.meta.type == "model" &&
+ _.findWhere(
+ data.meta.fields, {name: name}
+ ).required)
+ def.reject("Required value not set");
+ else resolve();
+ return;
+ }
- if (npv == null)
- _.each(
- _.keys(changed),
- function(p) {
- if (isSubordinate(p, mpath, true))
- delete changed[p];
- }
- );
+ objRequest(
+ set && !del ? path : mpath, options
+ ).done(function() {
+ if (!(mpath in changed))
+ changed[mpath] = value;
+ if (!tn && newValue == changed[mpath])
+ delete changed[mpath];
+
+ if (npv == null)
+ _.each(
+ _.keys(changed),
+ function(p) {
+ if (isSubordinate(p, mpath, true))
+ delete changed[p];
+ }
+ );
+
+ if (data.meta.type == "list" && del)
+ data.data.splice(name - 1, 1);
+ else if (!set) data.data[index(name)] = npv;
+ else if (del)
+ data.data.splice(
+ data.data.indexOf(name), 1
+ );
+ else data.data.push(name);
+
+ data.validate();
+
+ if (data.meta.type == "model")
+ _.each(
+ data.meta.fields, function(field) {
+ if (field.condition &&
+ field.condition[name] &&
+ !_.contains(
+ field.condition[name],
+ newValue
+ ))
+ ignore(
+ join(path, field.name)
+ );
+ }
+ );
+
+ if (tn && !set)
+ query(mpath).done(function(data) {
+
+ if (mpath in invalid) {
+ if (data.meta.type == "model")
+ _.each(
+ data.meta.fields,
+ function(field) {
+ var mmpath = join(
+ mpath,
+ field.name
+ );
+ if (field.required &&
+ data.match(
+ field.condition
+ ) &&
+ !(mmpath in invalid) &&
+ (isCollection(
+ field
+ ) || data.get(
+ field.name
+ ) == null)) {
+ invalid[
+ mmpath
+ ] = [
+ null
+ ];
+ }
+ });
+
+ else if (isCollection(data.meta) &&
+ data.meta.required)
+ invalid[mpath] = [mpath];
+ }
+
+ resolve();
+ }).fail(reject);
+
+ else resolve();
+
+ }).fail(reject);
+ }
+
+ var prevTask;
+ if (mpath in invalid) prevTask = invalid[mpath][1];
- if (data.meta.type == "list" && del)
- data.data.splice(name - 1, 1);
- else if (!set) data.data[index(name)] = npv;
- else if (del)
- data.data.splice(
- data.data.indexOf(name), 1
- );
- else data.data.push(name);
+ invalid[mpath] = [npv, def];
- data.validate();
+ if (prevTask) prevTask.always(validate);
+ else validate();
- if (data.meta.type == "model")
+ return def;
+ };
+
+ data.add = function(name) {
+ return data.set(name, name);
+ };
+
+ function adjustListIndex(oldIndex, newIndex) {
+ var opath = join(path, oldIndex);
+ var npath = join(path, newIndex);
+ _.each(
+ [changed, invalid],
+ function(map) {
_.each(
- data.meta.fields, function(field) {
- if (field.condition &&
- field.condition[name] &&
- !_.contains(
- field.condition[name],
- newValue
- ))
- ignore(
- join(path, field.name)
- );
- }
- );
-
- if (tn && !set)
- query(mpath).done(function(data) {
-
- if (mpath in invalid) {
- if (data.meta.type == "model")
- _.each(
- data.meta.fields,
- function(field) {
- var mmpath = join(
- mpath,
- field.name
- );
- if (field.required &&
- data.match(
- field.condition
- ) &&
- !(mmpath in invalid) &&
- (isCollection(
- field
- ) || data.get(
- field.name
- ) == null)) {
- invalid[
- mmpath
- ] = [
- null
- ];
- }
- });
-
- else if (isCollection(data.meta) &&
- data.meta.required)
- invalid[mpath] = [mpath];
- }
+ _.keys(map),
+ function(p) {
+ if (isSubordinate(
+ p, opath
+ )) {
+ map[npath +
+ p.substring(
+ opath.length
+ )] = map[p];
+ delete map[p];
+ }
+ });
+ }
+ );
+ }
- resolve();
- }).fail(reject);
-
- else resolve();
-
- }).fail(reject);
+ function adjustListIndices(start, end) {
+ var offset = start < end ? 1 : -1;
+ for (var i = start; i != end; i += offset)
+ adjustListIndex(i + offset, i);
}
- var prevTask;
- if (mpath in invalid) prevTask = invalid[mpath][1];
+ function _delete(name) {
+ var def = $.Deferred();
+ var length = data.data.length;
- invalid[mpath] = [npv, def];
+ data.set(name, null).done(function(txnValid) {
+ if (isTreeNode(data.meta) &&
+ data.meta.type != "set") {
- if (prevTask) prevTask.always(validate);
- else validate();
+ delete changed[join(path, name)];
+ changed[path] = path;
- return def;
- };
-
- data.add = function(name) {
- return data.set(name, name);
- };
-
- function adjustListIndex(oldIndex, newIndex) {
- var opath = join(path, oldIndex);
- var npath = join(path, newIndex);
- _.each(
- [changed, invalid],
- function(map) {
- _.each(
- _.keys(map),
- function(p) {
- if (isSubordinate(
- p, opath
- )) {
- map[npath +
- p.substring(
- opath.length
- )] = map[p];
- delete map[p];
- }
- });
- }
- );
- }
+ if (data.meta.type == "list")
+ adjustListIndices(name, length);
+ }
+ def.resolve(txnValid);
- function adjustListIndices(start, end) {
- var offset = start < end ? 1 : -1;
- for (var i = start; i != end; i += offset)
- adjustListIndex(i + offset, i);
- }
+ }).fail(function() { def.reject(); });
- function _delete(name) {
- var def = $.Deferred();
- var length = data.data.length;
+ return def;
+ }
- data.set(name, null).done(function(txnValid) {
- if (isTreeNode(data.meta) &&
- data.meta.type != "set") {
+ data.delete = function(name) {
+ return exclusive(function() {
+ return _delete(name);
+ });
+ };
- delete changed[join(path, name)];
- changed[path] = path;
+ data.move = function(oldIndex, newIndex) {
+ if (oldIndex == newIndex)
+ return $.Deferred().resolve(isValid());
- if (data.meta.type == "list")
- adjustListIndices(name, length);
- }
- def.resolve(txnValid);
+ var value = data.get(oldIndex);
+ var length = data.data.length;
- }).fail(function() { def.reject(); });
+ return exclusive(function() {
+ var def = $.Deferred();
+ function reject() { def.reject(); }
- return def;
- }
+ if (oldIndex > newIndex) oldIndex++;
+ else newIndex++;
- data.delete = function(name) {
- return exclusive(function() {
- return _delete(name);
- });
- };
+ objRequest(path, {type: "POST", data: {
+ index: newIndex,
+ data: isTreeNode(data.meta.members) ?
+ join(path, oldIndex) : value
+ }}).done(function() {
- data.move = function(oldIndex, newIndex) {
- if (oldIndex == newIndex)
- return $.Deferred().resolve(isValid());
+ data.data.splice(newIndex - 1, 0, value);
- var value = data.get(oldIndex);
- var length = data.data.length;
+ adjustListIndices(length + 1, newIndex);
+ adjustListIndex(oldIndex, newIndex);
- return exclusive(function() {
- var def = $.Deferred();
- function reject() { def.reject(); }
+ data.delete(oldIndex)
+ .done(function(txnValid) {
+ def.resolve(txnValid);
+ })
+ .fail(reject);
- if (oldIndex > newIndex) oldIndex++;
- else newIndex++;
+ }).fail(reject);
- objRequest(path, {type: "POST", data: {
- index: newIndex,
- data: isTreeNode(data.meta.members) ?
- join(path, oldIndex) : value
- }}).done(function() {
+ return def;
+ });
+ };
- data.data.splice(newIndex - 1, 0, value);
+ data.invoke = function(name) {
+ return objRequest(join(path, name), {type: "POST"});
+ };
- adjustListIndices(length + 1, newIndex);
- adjustListIndex(oldIndex, newIndex);
+ def.resolve(data);
+ }).fail(function() { def.reject(); });
+
+ return def;
+ }
- data.delete(oldIndex)
- .done(function(txnValid) {
- def.resolve(txnValid);
- })
- .fail(reject);
+ return {
+ start: function() {
+ var def = $.Deferred();
+ if (txn && isValid() && !(_.size(changed))) abort();
- }).fail(reject);
+ if (txn)
+ def.resolve();
- return def;
- });
- };
+ else request("/transaction", {type: "POST"})
+ .done(function(data, status, xhr) {
+ txn = xhr.getResponseHeader(
+ "X-ACF-Transaction-ID"
+ );
+ def.resolve();
+ })
+ .fail(function() { def.reject(); });
- data.invoke = function(name) {
- return objRequest(join(path, name), {type: "POST"});
- };
+ return def;
+ },
- def.resolve(data);
- }).fail(function() { def.reject(); });
-
- return def;
- }
+ commit: function() {
+ var def = $.Deferred();
+ function reject(xhr) { def.reject(xhr); }
+ request(
+ "/transaction", {type: "PUT"}
+ ).done(function() {
+ reset();
+ if (saveRequired)
+ request(
+ "/save", {type: "POST"}
+ ).done(function() {
+ def.resolve();
+ }).fail(reject);
+ else def.resolve();
+ }).fail(reject);
+ return def;
+ },
- return {
- start: function() {
- var def = $.Deferred();
- if (txn && isValid() && !(_.size(changed))) abort();
+ abort: abort,
- if (txn)
- def.resolve();
+ query: query,
- else request("/transaction", {type: "POST"})
- .done(function(data, status, xhr) {
- txn = xhr.getResponseHeader(
- "X-ACF-Transaction-ID"
- );
- def.resolve();
- })
- .fail(function() { def.reject(); });
+ logout: function() {
+ return request("/login", {type: "DELETE"});
+ }
+ };
+ })(
+ xhr.getResponseHeader("X-ACF-Auth-Token"),
+ xhr.getResponseHeader("X-ACF-Save-Required") == "1"
+ );
+
- return def;
- },
- commit: function() {
- var def = $.Deferred();
- function reject(xhr) { def.reject(xhr); }
- request(
- "/transaction", {type: "PUT"}
- ).done(function() {
- reset();
- if (saveRequired)
- request(
- "/save", {type: "POST"}
- ).done(function() {
- def.resolve();
- }).fail(reject);
- else def.resolve();
- }).fail(reject);
- return def;
- },
+ function formatError(msg, xhr) {
+ msg += " " + xhr.statusCode().status;
+ if (xhr.responseText) msg += ': ' + xhr.responseText;
+ return msg;
+ }
- abort: abort,
- query: query,
+ function href() {
+ return $("<a>").attr({href: "javascript:void(0);"});
+ }
- logout: function() {
- return request("/login", {type: "DELETE"});
+ function objectRef(value, el) {
+ el = el || href();
+ if (value) {
+ el.click(function() {
+ $.bbq.pushState("#" + value);
+ }).text("Show");
}
+ return el;
};
- })(
- xhr.getResponseHeader("X-ACF-Auth-Token"),
- xhr.getResponseHeader("X-ACF-Save-Required") == "1"
- );
-
-
-
- function formatError(msg, xhr) {
- msg += " " + xhr.statusCode().status;
- if (xhr.responseText) msg += ': ' + xhr.responseText;
- return msg;
- }
-
-
- function href() {
- return $("<a>").attr({href: "javascript:void(0);"});
- }
-
- function objectRef(value, el) {
- el = el || href();
- if (value) {
- el.click(function() {
- $.bbq.pushState("#" + value);
- }).text("Show");
+
+ function makeRow(el) {
+ if (el.is("td")) return $("<tr>").html(el);
+ return el;
}
- return el;
- };
- function makeRow(el) {
- if (el.is("td")) return $("<tr>").html(el);
- return el;
- }
+ function setStatus(el, status) { el.prop("class", status); }
+
- function setStatus(el, status) { el.prop("class", status); }
+ 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);
+ },
- var Widget = {
- extend: function(spec) {
- var res = Object.create(this);
- for (key in spec) res[key] = spec[key];
- res.base = this;
- return res;
- },
+ new: function(data, name, meta, level, editable, removable) {
+ return Object.create(this).init(
+ data, name, meta, level, editable, removable
+ );
+ },
- super: function() {
- var args = _.toArray(arguments);
- var cls = args.shift();
- var key = args.shift();
- return cls.base[key].apply(this, args);
- },
+ init: function(data, name, meta, level, editable, removable) {
+ this.data = data;
+ this.name = name;
+ this.meta = meta;
+ this.level = level;
- 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) {
- setStatus(el, status);
- return el;
+ var value = data.get(name);
+ var status = data.status(name);
+
+ if (!editable || !meta.editable) {
+ var el = this.staticRender(value, meta);
+ if (el) {
+ setStatus(el, status);
+ return el;
+ }
}
- }
- this.makeEl();
- this.dynamic = meta.dynamic;
+ this.makeEl();
+ this.dynamic = meta.dynamic;
- var self = this;
+ 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);
- });
- }
+ 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;
+ this.wrapped = this.wrap();
+ this.visible = true;
+
+ if (removable) {
+ var link = href().click(function() {
+ data.delete(name).done(function(txnValid) {
+ $("#content").trigger("reload", [txnValid]);
+ })
+ }).text("Delete");
+ this.wrapped = makeRow(this.wrapped);
+ if (this.wrapped.is("tr")) link = $("<td>").html(link);
+ this.wrapped.append(link);
+ }
- if (removable) {
- var link = href().click(function() {
- data.delete(name).done(function(txnValid) {
- $("#content").trigger("reload", [txnValid]);
- })
- }).text("Delete");
- this.wrapped = makeRow(this.wrapped);
- if (this.wrapped.is("tr")) link = $("<td>").html(link);
- this.wrapped.append(link);
- }
+ handleRequest(this.requestData(value, meta));
- handleRequest(this.requestData(value, meta));
+ function validate() {
+ request.done(function(value) {
+ self.validate(value);
+ });
+ }
- 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("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();
+ });
- 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;
+ },
- return this.wrapped;
- },
+ makeEl: function() { this.el = this.createEl(); },
- makeEl: function() { this.el = this.createEl(); },
+ requestData: function(value, meta) {
+ return $.Deferred().resolve(value, meta);
+ },
- 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;
+ },
- 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; },
- wrap: function() { return this.el; },
+ showStatus: true,
- showStatus: true,
+ setStatus: function(status) {
+ if (this.el && this.showStatus)
+ setStatus(this.statusEl(), status);
+ },
- setStatus: function(status) {
- if (this.el && this.showStatus)
- setStatus(this.statusEl(), status);
- },
+ statusEl: function() { return this.el; },
- statusEl: function() { return this.el; },
+ setVisible: function() {
+ this.visible = this.data.match(this.meta.condition);
+ if (this.wrapped)
+ this.wrapped.trigger("setVisible", [this.visible]);
+ },
- setVisible: function() {
- this.visible = this.data.match(this.meta.condition);
- if (this.wrapped)
- this.wrapped.trigger("setVisible", [this.visible]);
- },
+ validate: function(value) { this.setVisible(); }
+ };
- validate: function(value) { this.setVisible(); }
- };
+ var Field = Widget.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.editable = editable && meta.editable;
- var Field = Widget.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.editable = editable && meta.editable;
+ var el = this.super(
+ Field,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
- var el = this.super(
- Field,
- "init",
- data,
- name,
- meta,
- level,
- editable,
- removable
- );
+ if (this.editable)
+ this.field.change(_.bind(this.validateChange, this));
+
+ return el;
+ },
- if (this.editable)
- this.field.change(_.bind(this.validateChange, this));
-
- return el;
- },
-
- staticRender: function(value, meta) {
- return $("<td>").text(value);
- },
-
- makeEl: function() {
- this.super(Field, "makeEl");
- if (!this.field) this.field = this.el;
- },
-
- createEl: function() { return $("<input>"); },
-
- render: function(value, meta) {
- this.field.attr({type: "text", value: value});
- },
-
- wrap: function() {
- var td = $("<td>");
- this.msg = $("<div>");
- td.append(this.msg);
- td.append(this.el);
- return td;
- },
-
- validate: function(value) {
- this.super(Field, "validate", value);
- if (!this.visible || !this.editable) return;
- this.validateChange();
- },
-
- validateChange: function() {
- this.msg.text("[checking]");
- statusBar.setError("Validating changes", "validate");
-
- 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);
- });
- },
+ staticRender: function(value, meta) {
+ return $("<td>").text(value);
+ },
- get: function() {
- return this.editable ? (
- this.field.val() || null
- ) : this.data.get(this.name);
- }
- });
+ makeEl: function() {
+ this.super(Field, "makeEl");
+ if (!this.field) this.field = this.el;
+ },
+ createEl: function() { return $("<input>"); },
- var ComboBox = Field.extend({
- createEl: function() { return $("<select>"); },
+ render: function(value, meta) {
+ this.field.attr({type: "text", value: value});
+ },
+
+ wrap: function() {
+ var td = $("<td>");
+ this.msg = $("<div>");
+ td.append(this.msg);
+ td.append(this.el);
+ return td;
+ },
+
+ validate: function(value) {
+ this.super(Field, "validate", value);
+ if (!this.visible || !this.editable) return;
+ this.validateChange();
+ },
- staticRender: function(value, meta) {
- return this.super(
- ComboBox,
- "staticRender",
- _.findWhere(meta.choice, {value: value})["ui-value"],
- meta
- );
- },
+ validateChange: function() {
+ this.msg.text("[checking]");
+ statusBar.setError("Validating changes", "validate");
- render: function(value, meta) {
- var el = this.field.empty();
+ 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 = Field.extend({
- staticRender: function(value, meta) {
- return $("<td>").text(value ? "Yes" : "No");
- },
+ staticRender: function(value, meta) {
+ return this.super(
+ ComboBox,
+ "staticRender",
+ _.findWhere(meta.choice, {value: value})["ui-value"],
+ meta
+ );
+ },
- statusEl: function() { return this.el.parent(); },
+ render: function(value, meta) {
+ var el = this.field.empty();
- render: function(value, meta) {
- this.field.attr({type: "checkbox", checked: value});
- },
+ function opt(value, ui_value, selected) {
+ el.append($("<option>").attr(
+ {value: value, selected: selected}
+ ).text(ui_value));
+ }
- get: function() { return this.field.is(":checked"); }
- });
+ 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 Link = Widget.extend({
- staticRender: function(value, meta) {
- return $("<td>").html(objectRef(value));
- },
+ var CheckBox = Field.extend({
+ staticRender: function(value, meta) {
+ return $("<td>").text(value ? "Yes" : "No");
+ },
- createEl: href,
+ statusEl: function() { return this.el.parent(); },
- render: function(value, meta) { objectRef(value, this.el) },
+ render: function(value, meta) {
+ this.field.attr({type: "checkbox", checked: value});
+ },
- wrap: function() { return $("<td>").html(this.el); },
-
- get: function() { return {}; }
- });
+ get: function() { return this.field.is(":checked"); }
+ });
- 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
- );
- },
+ var Link = Widget.extend({
+ staticRender: function(value, meta) {
+ return $("<td>").html(objectRef(value));
+ },
- staticRender: function(value, meta) { return null; },
+ createEl: href,
- createEl: function() { return $("<div>"); },
+ render: function(value, meta) { objectRef(value, this.el) },
- showStatus: false,
-
- requestData: function(value, meta) {
- this.path = value;
- return this.refreshData();
- },
-
- refreshData: function() {
- var def = $.Deferred();
- txnMgr.query(this.path).done(function(data) {
- def.resolve(data, data.meta);
- });
- return def;
- },
+ wrap: function() { return $("<td>").html(this.el); },
+
+ get: function() { return {}; }
+ });
- showHeading: true,
- render: function(data, meta) {
- if (this.showHeading)
- this.el.html(
- $("<h" + this.level + ">").text(meta["ui-name"])
+ 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
);
- },
+ },
- wrap: function() { return this.el; },
+ staticRender: function(value, meta) { return null; },
- validate: function(data) {
- this.super(Inline, "validate", data);
+ createEl: function() { return $("<div>"); },
+
+ showStatus: false,
- if (this.data.match(this.meta.condition)) {
- var valid = data.validate();
- this.setStatus(data.status());
- statusBar.validationReady(valid);
- }
-
- if (this.fields)
- _.each(this.fields, function(field) {
- field.trigger("updated");
- });
- }
- });
+ requestData: function(value, meta) {
+ this.path = value;
+ return this.refreshData();
+ },
+ refreshData: function() {
+ var def = $.Deferred();
+ txnMgr.query(this.path).done(function(data) {
+ def.resolve(data, data.meta);
+ });
+ return def;
+ },
- var InlineFields = Inline.extend({
+ showHeading: true,
- render: function(data, meta) {
- this.super(InlineFields, "render", data, meta);
+ render: function(data, meta) {
+ if (this.showHeading)
+ this.el.html(
+ $("<h" + this.level + ">").text(meta["ui-name"])
+ );
+ },
- this.appendAboveFields(data, meta);
+ wrap: function() { return this.el; },
- this.reqData = data;
- var self = this;
-
- if (meta.type == "model") {
- this.fields = {};
- _.each(meta.fields, function(field) {
- if (field.visible)
- self.fields[field.name] = self.renderField(
- field.name,
- field,
- field["ui-name"],
- true,
- false
- );
- });
+ validate: function(data) {
+ this.super(Inline, "validate", data);
- _.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();
- });
+ if (this.data.match(this.meta.condition)) {
+ var valid = data.validate();
+ this.setStatus(data.status());
+ statusBar.validationReady(valid);
+ }
+
+ if (this.fields)
+ _.each(this.fields, function(field) {
+ field.trigger("updated");
});
- });
-
- _.each(this.fields, function(field) {
- field.trigger("start");
- });
}
-
- else _.each(data.data, function(value, name) {
- if (meta.type == "set") name = data.data[name];
- else if (_.isArray(data.data)) name++;
- self.renderCollectionMember(name, meta);
- });
+ });
- this.appendBelowFields(data, meta);
- },
-
- appendAboveFields: function(data, meta) {},
- appendBelowFields: function(data, meta) {},
-
- 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;
- },
-
- renderCollectionMember: function(name, meta) {
- var set = meta.type == "set";
- this.renderField(
- name,
- meta.members,
- meta["ui-member"] + " " + name,
- !set,
- !set && _.contains(meta.removable, name)
- ).trigger("start");
- },
-
- widget: function(meta) { return widgets[meta.widget]; }
- });
+ var InlineFields = Inline.extend({
- var Horizontal = InlineFields.extend({
- createEl: function() {
- this.previous = null;
- return $("<tr>").html($("<td>").prop(
- "class", "placeholder"
- ));
- },
+ render: function(data, meta) {
+ this.super(InlineFields, "render", data, meta);
- showHeading: false,
+ this.appendAboveFields(data, meta);
- 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.reqData = data;
+ var self = this;
+
+ if (meta.type == "model") {
+ this.fields = {};
+ _.each(meta.fields, function(field) {
+ if (field.visible)
+ 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(field) {
+ field.trigger("start");
+ });
+ }
+
+ else _.each(data.data, function(value, name) {
+ if (meta.type == "set") name = data.data[name];
+ else if (_.isArray(data.data)) name++;
+ self.renderCollectionMember(name, meta);
+ });
- var HeaderHorizontal = Horizontal.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.header = $("<tr>");
- var table = $("<table>");
- table.append($("<thead>").html(this.header));
- table.append($("<tbody>").html(
- this.super(
- HeaderHorizontal,
- "init",
- data,
+ this.appendBelowFields(data, meta);
+ },
+
+ appendAboveFields: function(data, meta) {},
+ appendBelowFields: function(data, meta) {},
+
+ renderField: function(
+ name, meta, label, editable, removable
+ ) {
+ var widget = this.widget(meta).new(
+ this.reqData,
name,
meta,
- level,
+ this.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 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 && _.contains(meta.removable, name)
+ ).trigger("start");
+ },
+
+ widget: function(meta) { return widgets[meta.widget]; }
+ });
- var Vertical = InlineFields.extend({
- wrap: function() { return $("<div>").html(this.el); },
-
- appendAboveFields: function(data, meta) {
- this.div = $("<div>");
- this.el.append(this.div);
+ var Horizontal = InlineFields.extend({
+ createEl: function() {
+ this.previous = null;
+ return $("<tr>").html($("<td>").prop(
+ "class", "placeholder"
+ ));
+ },
+
+ showHeading: false,
+
+ 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;
+ }
+ });
- var self = this;
+
+ var HeaderHorizontal = Horizontal.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.header = $("<tr>");
+ var table = $("<table>");
+ table.append($("<thead>").html(this.header));
+ table.append($("<tbody>").html(
+ this.super(
+ HeaderHorizontal,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ )
+ ));
+ return table;
+ },
- if (meta.type == "model")
- _.each(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");
- });
- }));
- });
- },
+ appendWidget: function(el, label) {
+ el = this.super(
+ HeaderHorizontal, "appendWidget", el, label
+ );
+ if (el) this.header.append($("<th>").text(label));
+ return el;
+ }
+ });
+
+
+ var Vertical = InlineFields.extend({
+ wrap: function() { return $("<div>").html(this.el); },
- appendBelowFields: function(data, meta) {
- if (meta.editable &&
- _.contains(["collection", "list"], meta.type)) {
- if (!this.table) this.makeSortable(this.div);
+ appendAboveFields: function(data, meta) {
+ this.div = $("<div>");
+ this.el.append(this.div);
var self = this;
- var keys = _.clone(_.keys(data.data));
- var button = $("<input>").attr(
- {type: "submit", value: "Insert"}
- ).click(function() {
-
- var getter;
+ if (meta.type == "model")
+ _.each(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");
+ });
+ }));
+ });
+ },
+
+ appendBelowFields: function(data, meta) {
+ if (meta.editable &&
+ _.contains(["collection", "list"], meta.type)) {
+ if (!this.table) this.makeSortable(this.div);
+
+ var self = this;
+ var keys = _.clone(_.keys(data.data));
- function insert() {
- var name = getter();
+ var button = $("<input>").attr(
+ {type: "submit", value: "Insert"}
+ ).click(function() {
- if (_.contains(keys, name)) {
- button.prop("class", null);
- return;
+ var getter;
+
+ function insert() {
+ var name = getter();
+
+ if (_.contains(keys, name)) {
+ button.prop("class", null);
+ return;
+ }
+ keys.push(name);
+
+ data.set(
+ name,
+ isTreeNode(meta.members) ? {} : null
+ ).done(function(txnValid) {
+ if (_.isObject(meta.removable))
+ meta.removable = [];
+ meta.removable.push(name);
+
+ self.renderCollectionMember(name, meta);
+ button.prop("class", null);
+ statusBar.validationReady(txnValid);
+ });
}
- keys.push(name);
+
+ button.prop("class", "hidden");
- data.set(
- name,
- isTreeNode(meta.members) ? {} : null
- ).done(function(txnValid) {
- if (_.isObject(meta.removable))
- meta.removable = [];
- meta.removable.push(name);
+ if (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));
+ }
+ },
- self.renderCollectionMember(name, meta);
- button.prop("class", null);
- statusBar.validationReady(txnValid);
+ 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")) {
+ this.makeSortable(el.find("tbody"));
+ var td;
+ el.find("tr").each(function(index, row) {
+ td = $("<td>");
+ $(row).prepend(td);
});
+ td.text(label);
+ this.table = el;
}
+ else this.table = null;
+ this.div.append(el);
+ }
+
+ return el;
+ },
+
+ appendRow: function(row) {
+ if (!this.table) {
+ this.table = this.makeSortable($("<tbody>"));
+ this.div.append($("<table>").html(this.table));
+ }
+ this.table.append(row);
+ },
- button.prop("class", "hidden");
-
- if (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;
+ makeSortable: function(el) {
+ var data = this.reqData;
+
+ if (data.meta.type == "list")
+ el.sortable({
+ start: function(event, ui) {
+ $(":focus").change();
+ ui.item.data("index", ui.item.index());
+ },
+ stop: function(event, ui) {
+ var oldIndex = ui.item.data("index") + 1;
+ var newIndex = ui.item.index() + 1;
+ if (newIndex != oldIndex)
+ data.move(oldIndex, newIndex)
+ .done(function(txnValid) {
+ $("#content").trigger(
+ "reload", [txnValid]
+ );
+ });
}
- field.change(insert);
- self.appendRow(row);
- }
- else {
- getter = function() {
- return data.data.length + 1;
- };
- insert();
- }
- });
- this.el.append($("<p>").html(button));
- }
- },
-
- 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")) {
- this.makeSortable(el.find("tbody"));
- var td;
- el.find("tr").each(function(index, row) {
- td = $("<td>");
- $(row).prepend(td);
});
- td.text(label);
- this.table = el;
- }
- else this.table = null;
- this.div.append(el);
- }
-
- return el;
- },
-
- appendRow: function(row) {
- if (!this.table) {
- this.table = this.makeSortable($("<tbody>"));
- this.div.append($("<table>").html(this.table));
+ return el;
}
- this.table.append(row);
- },
+ });
- makeSortable: function(el) {
- var data = this.reqData;
- if (data.meta.type == "list")
- el.sortable({
- start: function(event, ui) {
- $(":focus").change();
- ui.item.data("index", ui.item.index());
- },
- stop: function(event, ui) {
- var oldIndex = ui.item.data("index") + 1;
- var newIndex = ui.item.index() + 1;
- if (newIndex != oldIndex)
- data.move(oldIndex, newIndex)
- .done(function(txnValid) {
- $("#content").trigger(
- "reload", [txnValid]
- );
- });
- }
- });
- return el;
- }
- });
+ var CheckBoxes = Inline.extend({
+ showStatus: true,
+ setStatus: function(status) {
+ this.super(
+ CheckBoxes,
+ "setStatus",
+ status == "invalid" ? "invalid" : null
+ );
+ },
+
+ render: function(data, meta) {
+ this.dynamic = meta.members.dynamic;
+
+ this.super(CheckBoxes, "render", data, meta);
+
+ var table = $("<tbody>");
+ this.el.append($("<table>").html(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);
+ });
+ });
- var CheckBoxes = Inline.extend({
- showStatus: true,
+ table.append(row);
+ });
+ }
+ });
- setStatus: function(status) {
- this.super(
- CheckBoxes,
- "setStatus",
- status == "invalid" ? "invalid" : null
- );
- },
-
- render: function(data, meta) {
- this.dynamic = meta.members.dynamic;
- this.super(CheckBoxes, "render", data, meta);
+ var Reference = ComboBox.extend({
+ init: function(
+ data, name, meta, level, editable, removable
+ ) {
+ this.field = ComboBox.createEl();
+ return this.super(
+ Reference,
+ "init",
+ data,
+ name,
+ meta,
+ level,
+ editable,
+ removable
+ );
+ },
- var table = $("<tbody>");
- this.el.append($("<table>").html(table));
+ staticRender: function(value, meta) {
+ return $("<td>").html(objectRef(value).text(value));
+ },
- var self = this;
+ statusEl: function() { return this.el.find("select"); },
+
+ createEl: function() { return $("<div>"); },
- _.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
- });
+ render: function(value, meta) {
+ this.super(Reference, "render", value, meta);
- 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);
+ this.el.html(this.field);
+ this.el.append(" ");
- function setRowStatus() {
- setStatus(row, data.status(choice.value));
- }
- setRowStatus();
+ var link = $("<div>");
+ var update = _.bind(function() {
+ link.html(objectRef(this.get()));
+ }, this);
+ this.el.append(link);
- 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);
- });
- });
+ this.field.change(update);
+ update();
+ }
+ });
- table.append(row);
- });
- }
- });
+ var widgets = {
+ boolean: CheckBox,
+ checkboxes: CheckBoxes,
+ combobox: ComboBox,
+ field: Field,
+ inline: Vertical,
+ link: Link,
+ reference: Reference
+ };
- var Reference = ComboBox.extend({
- init: function(
- data, name, meta, level, editable, removable
- ) {
- this.field = ComboBox.createEl();
- return this.super(
- Reference,
- "init",
- data,
- name,
- meta,
- level,
- editable,
- removable
- );
- },
-
- staticRender: function(value, meta) {
- return $("<td>").html(objectRef(value).text(value));
- },
-
- statusEl: function() { return this.el.find("select"); },
- 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);
+ var Tabular = Vertical.extend({
+ render: function(data, meta) {
+ this.header = true;
+ this.super(Tabular, "render", data, meta);
+ },
- this.field.change(update);
- update();
- }
- });
+ widget: function(meta) {
+ if (!isTreeNode(meta))
+ return this.super(Tabular, "widget", meta);
+ if (!this.header) return Horizontal;
+ this.header = false;
+ return HeaderHorizontal;
+ }
+ });
- var widgets = {
- boolean: CheckBox,
- checkboxes: CheckBoxes,
- combobox: ComboBox,
- field: Field,
- inline: Vertical,
- link: Link,
- reference: Reference
- };
+ var Stacked = Vertical.extend({
+ widget: function(meta) {
+ return isTreeNode(meta) ?
+ Vertical : this.super(Stacked, "widget", meta);
+ }
+ });
- 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 layouts = {stacked: Stacked, tabular: Tabular};
- var Stacked = Vertical.extend({
- widget: function(meta) {
- return isTreeNode(meta) ?
- Vertical : this.super(Stacked, "widget", meta);
- }
- });
+ function redirect(path) { $.bbq.pushState("#" + path); }
+ function renderObject(path, data) {
+ path = path || $.param.fragment();
- var layouts = {stacked: Stacked, tabular: Tabular};
+ return (
+ data ? $.Deferred().resolve(data) : txnMgr.query(path)
+ ).done(function(data) {
+ var layout = data.meta.widget;
+ var name = split(path).pop();
+ (layout ? layouts[layout] : Vertical).extend({
+ createEl: function() { return $("#content").empty(); },
+ wrap: function() { return this.el; },
+ requestData: function(value, meta) {
+ return $.Deferred().resolve(data, data.meta);
+ }
+ }).new(
+ {
+ get: function(name) { return path; },
+ status: function(name) { return null; },
+ match: function(filter) { return true; }
+ },
+ name,
+ {},
+ 0,
+ true,
+ false
+ );
+ }).fail(function() {
+ var comps = split(path);
+ comps.pop();
+ comps.unshift("/");
+ redirect(join.apply(undefined, comps));
+ });
+ };
+ $("#content").on("reload", function(event, txnValid) {
+ statusBar.validationReady(txnValid);
+ renderObject();
+ event.stopPropagation();
+ });
- function redirect(path) { $.bbq.pushState("#" + path); }
- function renderObject(path, data) {
- path = path || $.param.fragment();
+ function render() {
+ var path = $.param.fragment();
- return (
- data ? $.Deferred().resolve(data) : txnMgr.query(path)
- ).done(function(data) {
- var layout = data.meta.widget;
- var name = split(path).pop();
- (layout ? layouts[layout] : Vertical).extend({
- createEl: function() { return $("#content").empty(); },
- wrap: function() { return this.el; },
- requestData: function(value, meta) {
- return $.Deferred().resolve(data, data.meta);
- }
- }).new(
- {
- get: function(name) { return path; },
- status: function(name) { return null; },
- match: function(filter) { return true; }
- },
- name,
- {},
- 0,
- true,
- false
- );
- }).fail(function() {
- var comps = split(path);
- comps.pop();
- comps.unshift("/");
- redirect(join.apply(undefined, comps));
- });
- };
+ function renderMenu(target, path, current, selectFirst) {
+ var def = $.Deferred();
- $("#content").on("reload", function(event, txnValid) {
- statusBar.validationReady(txnValid);
- renderObject();
- event.stopPropagation();
- });
+ txnMgr.query(path).done(function(data) {
+ if (data.meta.type != "model") {
+ def.reject(data);
+ return;
+ }
+ var tnFields = [];
+ var extraFields = false;
- function render() {
- var path = $.param.fragment();
+ _.each(data.meta.fields, function(field) {
+ if (!field.visible) return;
- function renderMenu(target, path, current, selectFirst) {
- var def = $.Deferred();
+ if (!isTreeNode(field)) extraFields = true;
+ else if (data.data[field.name])
+ tnFields.push(field);
+ });
- txnMgr.query(path).done(function(data) {
- if (data.meta.type != "model") {
- def.reject(data);
- return;
- }
+ if (!tnFields.length) {
+ def.reject(data);
+ return;
+ }
+
+ function addItem(path, ui_name, status, current) {
+ var el = $("<li>").html(objectRef(path).text(ui_name));
+ el.prop("class", status);
+ if (current) el.addClass("current");
+ target.append(el);
+ }
- var tnFields = [];
- var extraFields = false;
+ if (extraFields) {
+ addItem(path, "General", null, !current);
+ selectFirst = false;
+ }
- _.each(data.meta.fields, function(field) {
- if (!field.visible) return;
+ _.each(tnFields, function(field, i) {
+ addItem(
+ data.get(field.name),
+ field["ui-name"],
+ data.status(field.name),
+ current == field.name || (
+ !current && !i && selectFirst
+ )
+ );
+ field.visible = false;
+ });
- if (!isTreeNode(field)) extraFields = true;
- else if (data.data[field.name])
- tnFields.push(field);
+ def.resolve(extraFields ? data : tnFields[0].name);
});
- if (!tnFields.length) {
- def.reject(data);
- return;
- }
+ return def;
+ }
- function addItem(path, ui_name, status, current) {
- var el = $("<li>").html(objectRef(path).text(ui_name));
- el.prop("class", status);
- if (current) el.addClass("current");
- target.append(el);
- }
- if (extraFields) {
- addItem(path, "General", null, !current);
- selectFirst = false;
+ if (path > "/") $("#content").text("Loading...");
+
+ txnMgr.start().done(function() {
+ var comps = split(path);
+ renderMenu($("#modules").empty(), "/", comps[0], false);
+ var tabs = $("#tabs").empty();
+
+ if (path == "/") return;
+
+ function renderTabs(p) {
+ p = join(p, comps.shift());
+ renderMenu(tabs, p, comps[0], true)
+ .done(function(data) {
+ var tabLevel = !comps.length;
+ renderObject(
+ (
+ tabLevel && _.isString(data)
+ ) ? join(p, data) : path,
+ tabLevel && _.isObject(data) ? data : null
+ );
+ })
+ .fail(function(data) {
+ if (comps.length) renderTabs(p);
+ else renderObject(p, data);
+ });
}
-
- _.each(tnFields, function(field, i) {
- addItem(
- data.get(field.name),
- field["ui-name"],
- data.status(field.name),
- current == field.name || (
- !current && !i && selectFirst
- )
- );
- field.visible = false;
- });
-
- def.resolve(extraFields ? data : tnFields[0].name);
+ renderTabs("/");
});
-
- return def;
}
-
- if (path > "/") $("#content").text("Loading...");
-
- txnMgr.start().done(function() {
- var comps = split(path);
- renderMenu($("#modules").empty(), "/", comps[0], false);
- var tabs = $("#tabs").empty();
-
- if (path == "/") return;
-
- function renderTabs(p) {
- p = join(p, comps.shift());
- renderMenu(tabs, p, comps[0], true)
- .done(function(data) {
- var tabLevel = !comps.length;
- renderObject(
- (
- tabLevel && _.isString(data)
- ) ? join(p, data) : path,
- tabLevel && _.isObject(data) ? data : null
- );
- })
- .fail(function(data) {
- if (comps.length) renderTabs(p);
- else renderObject(p, data);
- });
- }
- renderTabs("/");
+
+ function clearState() {
+ statusBar.reset();
+ render();
+ $.unblockUI();
+ }
+
+ $("#commit").click(function() {
+ $.blockUI();
+ txnMgr.commit().done(clearState).fail(function(xhr) {
+ statusBar.setError(
+ formatError("Commit failed", xhr), "txn"
+ );
+ })
});
- }
-
-
- function clearState() {
- statusBar.reset();
- render();
- $.unblockUI();
- }
-
- $("#commit").click(function() {
- $.blockUI();
- txnMgr.commit().done(clearState).fail(function(xhr) {
- statusBar.setError(
- formatError("Commit failed", xhr), "txn"
- );
- })
- });
- $("#revert").click(function() {
- $.blockUI();
- txnMgr.abort();
- clearState();
- });
-
- $("#logout").click(function() {
- txnMgr.logout().done(function() {
- $("body").html($("<p>").text("Logged out"));
+ $("#revert").click(function() {
+ $.blockUI();
+ txnMgr.abort();
+ clearState();
});
- });
-
- statusBar.reset();
- $("#content").empty();
+
+ $("#logout").click(function() {
+ txnMgr.logout().done(function() {
+ $("body").html($("<p>").text("Logged out"));
+ });
+ });
+
+ statusBar.reset();
+ $("#content").empty();
- $(window).bind("hashchange", render);
- redirect("/");
+ $(window).bind("hashchange", render);
+ redirect("/");
- }).fail(function() {
- statusBar.setError("Login failed", "login");
- });
+ }).fail(function() {
+ statusBar.setError("Login failed", "login");
+ });
- return false;
- });
+ return false;
+ });
- $("#username").focus();
-});
+ $("#username").focus();
+ }
+);