Permalink
Browse files

improved dynamic creation/modification of channel properties

  • Loading branch information...
1 parent 700c515 commit 0b10eadb6aa2c252f3423d7b9de0dbd6df66d132 @stv0g committed Feb 21, 2012
@@ -27,6 +27,7 @@
<script type="text/javascript" src="javascripts/entities.js"></script>
<script type="text/javascript" src="javascripts/wui.js"></script>
<script type="text/javascript" src="javascripts/entity.js"></script>
+ <script type="text/javascript" src="javascripts/property.js"></script>
<link rel="stylesheet" type="text/css" href="stylesheets/jquery-ui-vz/jquery-ui-1.8.17.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/jquery-treeTable.css">
@@ -156,7 +157,7 @@ <h2 id="title"></h2>
<p><input type="button" value="Abonnieren" /> <label for="entity-public-cookie">Cookie:</label> <input id="entity-public-cookie" type="checkbox" /></p>
</div>
<div id="entity-create">
- <form method="get" target="_blank">
+ <form>
<table>
<tr class="property"><th>Eigenschaft</th><th>Wert</th></tr>
<tr class="property"><td>Middleware:</td><td><input type="text" id="entity-create-middleware" /></td></tr>
@@ -127,114 +127,93 @@ Entity.prototype.loadData = function() {
*/
Entity.prototype.showDetails = function() {
var entity = this;
- var dialog = $('<div>');
-
- dialog.addClass('details')
- .append(this.getDOMDetails())
- .dialog({
- title: 'Details f&uuml;r ' + this.title,
- width: 480,
- resizable: false,
- buttons : {
- 'Schließen': function() {
- $(this).dialog('close');
- },
- 'Löschen' : function() {
- $('#entity-delete').dialog({ // confirm prompt
- resizable: false,
- modal: true,
- title: 'Löschen',
- width: 400,
- buttons: {
- 'Löschen': function() {
- entity.delete().done(function() {
- entity.cookie = false;
- vz.entities.saveCookie();
+ var dialog = $('<div>')
+ .addClass('details')
+ .append(this.getDOMDetails())
+ .dialog({
+ title: 'Details f&uuml;r ' + this.title,
+ width: 480,
+ resizable: false,
+ buttons : {
+ 'Bearbeiten' : function() {
+ $('table', this).remove();
+ $(this).append(entity.getDOMDetails(true));
+ },
+ 'Löschen' : function() {
+ $('#entity-delete').dialog({ // confirm prompt
+ resizable: false,
+ modal: true,
+ title: 'Löschen',
+ width: 400,
+ buttons: {
+ 'Löschen': function() {
+ entity.delete().done(function() {
+ entity.cookie = false;
+ vz.entities.saveCookie();
- vz.entities.each(function(it, parent) { // remove from tree
- if (entity.uuid == it.uuid) {
- var array = (parent) ? parent.children : vz.entities;
- array.remove(it);
- }
- }, true);
+ vz.entities.each(function(it, parent) { // remove from tree
+ if (entity.uuid == it.uuid) {
+ var array = (parent) ? parent.children : vz.entities;
+ array.remove(it);
+ }
+ }, true);
- vz.entities.showTable();
- vz.wui.drawPlot();
- dialog.dialog('close');
- });
+ vz.entities.showTable();
+ vz.wui.drawPlot();
+ dialog.dialog('close');
+ });
- $(this).dialog('close');
- },
- 'Abbrechen': function() {
- $(this).dialog('close');
+ $(this).dialog('close');
+ },
+ 'Abbrechen': function() {
+ $(this).dialog('close');
+ }
}
- }
- });
+ });
+ }
}
- }
- });
+ });
};
/**
* Show from for new Channel
* used to create info dialog
*/
-Entity.prototype.getDOMDetails = function(edit) {
+Entity.prototype.getDOMDetails = function(editable) {
var table = $('<table><thead><tr><th>Eigenschaft</th><th>Wert</th></tr></thead></table>');
var data = $('<tbody>');
- // general properties
- var general = ['title', 'type', 'uuid', 'middleware', 'color', 'style', 'active', 'cookie'];
- var sections = ['required', 'optional'];
-
+ // frontend properties
+ var general = ['type', 'uuid', 'middleware', 'cookie'];
general.each(function(index, property) {
- var definition = vz.capabilities.definitions.get('properties', property);
- var title = (definition) ? definition.translation[vz.options.language] : property;
var value = this[property];
+ var title;
switch(property) {
case 'type':
- var title = 'Typ';
+ title = 'Typ';
var icon = $('<img>').
attr('src', 'images/types/' + this.definition.icon)
.css('margin-right', 4);
var value = $('<span>')
.text(this.definition.translation[vz.options.language])
.prepend(icon);
break;
-
+
case 'middleware':
- var title = 'Middleware';
- var value = '<a href="' + this.middleware + '/capabilities.json">' + this.middleware + '</a>';
+ title = 'Middleware';
+ value = '<a href="' + this.middleware + '/capabilities.json">' + this.middleware + '</a>';
break;
-
+
case 'uuid':
- var title = 'UUID';
- var value = '<a href="' + this.middleware + '/entity/' + this.uuid + '.json">' + this.uuid + '</a>';
+ title = 'UUID';
+ value = '<a href="' + this.middleware + '/entity/' + this.uuid + '.json">' + this.uuid + '</a>';
break;
-
- case 'color':
- var value = $('<span>')
- .text(this.color)
- .css('background-color', this.color)
- .css('padding-left', 5)
- .css('padding-right', 5);
- break;
-
+
case 'cookie':
- var title = 'Cookie';
+ title = 'Cookie';
value = '<img src="images/' + ((this.cookie) ? 'tick' : 'cross') + '.png" alt="' + ((value) ? 'ja' : 'nein') + '" />';
break;
- case 'active':
- var value = '<img src="images/' + ((this.active) ? 'tick' : 'cross') + '.png" alt="' + ((this.active) ? 'ja' : 'nein') + '" />';
- break;
- case 'style':
- switch (this.style) {
- case 'lines': var value = 'Linien'; break;
- case 'steps': var value = 'Stufen'; break;
- case 'points': var value = 'Punkte'; break;
- }
- break;
}
data.append($('<tr>')
@@ -251,21 +230,46 @@ Entity.prototype.getDOMDetails = function(edit) {
);
}, this);
+ // middleware properties
+ var sections = ['required', 'optional'];
sections.each(function(index, section) {
this.definition[section].each(function(index, property) {
- if (this.hasOwnProperty(property) && !general.contains(property)) {
- var definition = vz.capabilities.definitions.get('properties', property);
- var title = definition.translation[vz.options.language];
+ if (editable || this.hasOwnProperty(property)) {
+ var propDef = vz.capabilities.definitions.get('properties', property);
+
+ var title = (propDef) ? propDef.translation[vz.options.language] : property;
var value = this[property];
- if (definition.type == 'boolean') {
+ if (propDef && propDef.type == 'boolean') {
value = '<img src="images/' + ((value) ? 'tick' : 'cross') + '.png" alt="' + ((value) ? 'ja' : 'nein') + '" />';
}
- if (property == 'cost') {
- value = (value * 1000 * 100) + ' ct/k' + this.definition.unit + 'h'; // ct per kWh
+ switch (property) {
+ case 'cost':
+ value = (value * 1000 * 100) + ' ct/k' + this.definition.unit + 'h'; // ct per kWh
+ break;
+
+ case 'color':
+ value = $('<span>')
+ .text(this.color)
+ .css('background-color', this.color)
+ .css('padding-left', 5)
+ .css('padding-right', 5);
+ break;
+
+ case 'style':
+ switch (this.style) {
+ case 'lines': value = 'Linien'; break;
+ case 'steps': value = 'Stufen'; break;
+ case 'points': value = 'Punkte'; break;
+ }
+ break;
}
-
+
+ if (editable && propDef) {
+ value = propDef.getInput(this[property]);
+ }
+
data.append($('<tr>')
.addClass('property')
.addClass(section)
@@ -281,6 +285,7 @@ Entity.prototype.getDOMDetails = function(edit) {
}
}, this);
}, this);
+
return table.append(data);
};
@@ -200,6 +200,10 @@ vz.capabilities.load = function() {
controller: 'capabilities',
success: function(json) {
$.extend(true, vz.capabilities, json.capabilities);
+
+ vz.capabilities.definitions.properties.each(function(index, propdef) {
+ vz.capabilities.definitions.properties[index] = new Property(propdef);
+ });
}
});
};
@@ -39,7 +39,7 @@ var vz = {
timeout: null
},
capabilities: { // debugging and runtime information from middleware
- definitions: {} // definitions of entities & properties
+ definitions: { }
},
plot: { }, // flot instance
options: { } // options loaded from cookies in options.js
@@ -38,69 +38,94 @@ var Property = function(json) {
* @todo implement/test
*/
Property.prototype.validate = function(value) {
+ var invalid = false;
+
switch (this.type) {
case 'string':
case 'text':
- // TODO check pattern
- // TODO check string length
- return true;
+ invalid |= (this.pattern != undefined) && value.match(this.pattern);
+ invalid |= (this.min != undefined) && value.length < this.min;
+ invalid |= (this.max != undefined) && value.length > this.max;
+ break;
+
+ case 'integer':
+ invalid |= !value.match(/^[+-]?\d*$/);
case 'float':
- // TODO check format
- // TODO check min/max
- return true;
-
- case 'integer':
- // TODO check format
- // TODO check min/max
- return true;
+ invalid |= !value.match(/^[+-]?\d*(\.\d*)?$/);
+ invalid |= (this.min != undefined) && value < this.min;
+ invalid |= (this.max != undefined) && value > this.max;
+ break;
case 'boolean':
- return value == '1' || value == '';
+ invalid |= value != '1' && value != '';
+ break;
case 'multiple':
- return this.options.contains(value);
+ invalid |= !this.options.contains(value);
+ break;
default:
throw new Exception('EntityException', 'Unknown property');
}
+
+ return !invalid;
};
/**
- *
- * @todo implement/test
+ * Get form element for property
*/
Property.prototype.getInput = function(value) {
+ var elm;
+
switch (this.type) {
- case 'string':
case 'float':
case 'integer':
- return $('<input>')
- .attr('type', 'text')
- .attr('name=', this.name)
- .attr('maxlength', (property.type == 'string') ? this.max : 0);
+ case 'string':
+ elm = $('<input>').attr('type', 'text');
+ if (this.type == 'string' && this.max) {
+ elm.attr('maxlength', this.max);
+ }
+ break;
+
case 'text':
- return $('<textarea>')
- .attr('name', this.name);
-
+ elm = $('<textarea>');
+ break;
+
case 'boolean':
- return $('<input>')
- .attr('type', 'checkbox')
- .attr('name', this.name)
- .attr('checked', true);
-
+ elm = $('<input>').attr('type', 'checkbox');
+ break;
+
case 'multiple':
- var dom = $('<select>').attr('name', property.name)
- property.options.each(function(index, option) {
- dom.append($('<option>')
- .value(option)
- .text(option)
+ elm = $('<select>').attr('size', 1);
+ this.options.each(function(index, option) {
+ elm.append(
+ $('<option>')
+ .val(option)
+ .text(option)
);
});
- return dom;
-
+ break;
+
default:
throw new Exception('PropertyException', 'Unknown property');
}
+
+ elm
+ .attr('name', this.name)
+ .val(value)
+ .bind('keyup keydown change', this, function(event) { // live validation
+ var propdef = event.data;
+ var elm = $(this);
+
+ if (propdef.validate(elm.val()) == false && elm.val() != '') {
+ elm.addClass('invalid');
+ }
+ else {
+ elm.removeClass('invalid');
+ }
+ });
+
+ return elm;
};
Oops, something went wrong.

0 comments on commit 0b10ead

Please sign in to comment.