summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-06 15:24:30 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-12-06 15:30:01 +0200
commit7ba070891537f3da58094dc7957f06365be07400 (patch)
tree199d01ef67e5b74bbfc8d1f25b3cf54d2b4dd562 /web
parent45395b1d85172953d2cef6886f9211881da3e5d4 (diff)
downloadaconf-7ba070891537f3da58094dc7957f06365be07400.tar.bz2
aconf-7ba070891537f3da58094dc7957f06365be07400.tar.xz
web client: ensure required collections have at least 1 member
Diffstat (limited to 'web')
-rw-r--r--web/client.js124
1 files changed, 88 insertions, 36 deletions
diff --git a/web/client.js b/web/client.js
index 9790985..b456e07 100644
--- a/web/client.js
+++ b/web/client.js
@@ -77,9 +77,12 @@ $(function() {
return _.contains(["list", "set"], meta.type);
}
+ function isCollection(meta) {
+ return meta.type == "collection" || isList(meta);
+ }
+
function isTreeNode(meta) {
- return isList(meta) ||
- _.contains(["collection", "model"], meta.type);
+ return meta.type == "model" || isCollection(meta);
}
@@ -143,7 +146,7 @@ $(function() {
};
data.status = function(name) {
- var p = join(path, name);
+ var p = name ? join(path, name) : path;
function scan(objs) {
return _.size(_.filter(
_.keys(objs), function(obj) {
@@ -155,7 +158,17 @@ $(function() {
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();
+ };
data.set = function(name, newValue) {
var def = $.Deferred();
@@ -236,6 +249,8 @@ $(function() {
);
else data.data.push(name);
+ data.validate();
+
if (data.meta.type == "model")
_.each(
data.meta.fields, function(field) {
@@ -249,31 +264,43 @@ $(function() {
join(path, field.name)
);
}
- )
+ );
if (tn && !set)
query(mpath).done(function(data) {
- if (mpath in invalid &&
- 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) &&
- data.get(
+ if (mpath in invalid) {
+ if (data.meta.type == "model")
+ _.each(
+ data.meta.fields,
+ function(field) {
+ var mmpath = join(
+ mpath,
field.name
- ) == null)
- invalid[mmpath] = [
- null
- ];
- });
+ );
+ 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);
@@ -454,10 +481,11 @@ $(function() {
this.makeEl();
var self = this;
- this.requestData(value, meta).done(function(value, meta) {
- self.render(value, meta);
- self.setStatus(status);
- });
+ this.request = this.requestData(value, meta)
+ .done(function(value, meta) {
+ self.render(value, meta);
+ self.setStatus(status);
+ });
var el = this.wrap();
@@ -510,7 +538,11 @@ $(function() {
field.el.on("validated", _.bind(this.validate, this));
},
- validate: function() { this.setVisible(); }
+ validate: function() { this.setVisible(); },
+
+ validateIfInvalid: function() {
+ if (this.data.status(name) == "invalid") this.validate();
+ }
};
@@ -528,7 +560,6 @@ $(function() {
if (this.editable)
this.field.change(_.bind(this.validate, this));
- if (data.status(name) == "invalid") this.validate();
return el;
};
@@ -563,7 +594,7 @@ $(function() {
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));
@@ -709,6 +740,10 @@ $(function() {
);
});
});
+
+ _.each(this.fields, function(field) {
+ field.validateIfInvalid();
+ });
}
else _.each(data.data, function(value, name) {
@@ -747,7 +782,7 @@ $(function() {
meta["ui-member"] + " " + name,
!set,
!set
- );
+ ).validateIfInvalid();
};
Inline.widget = function(meta) { return widgets[meta.widget]; };
@@ -756,10 +791,20 @@ $(function() {
Inline.validate = function() {
_.bind(Link.validate, this)();
- if (this.fields)
- _.each(this.fields, function(field) {
- field.widget.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.validate();
+ });
+ });
};
@@ -936,6 +981,12 @@ $(function() {
var CheckBoxes = Object.create(HeaderInline);
+ CheckBoxes.setStatus = function(status) {
+ _.bind(Link.setStatus, this)(
+ status == "invalid" ? "invalid" : null
+ );
+ }
+
CheckBoxes.render = function(data, meta) {
_.bind(HeaderInline.render, this)(data, meta);
@@ -973,6 +1024,7 @@ $(function() {
data.add(choice.value) :
data.delete(choice.value)
).done(function(txnValid) {
+ self.setStatus(data.status());
setStatus();
statusBar.validationReady(txnValid);
});