next generation frontend ;)

This commit is contained in:
Steffen Vogel 2010-12-10 22:13:19 +01:00
parent da751bda13
commit 1725e2199a
9 changed files with 162 additions and 106 deletions

BIN
frontend/images/link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

BIN
frontend/images/save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

View file

@ -17,10 +17,8 @@
<!--[if IE]><script language="javascript" type="text/javascript" src="javascripts/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="javascripts/flot/jquery.flot.js"></script>
<script type="text/javascript" src="javascripts/flot/jquery.flot.selection.js"></script>
<script type="text/javascript" src="javascripts/flot/jquery.flot.navigate.js"></script>
<script type="text/javascript" src="javascripts/flot/jquery.flot.crosshair.js"></script>
<script type="text/javascript" src="javascripts/flot/jquery.flot.symbol.js"></script>
<script type="text/javascript" src="javascripts/flot/jquery.flot.selection.js"></script>
<!-- volkszaehler.org code -->
<script type="text/javascript" src="javascripts/init.js"></script>
@ -37,7 +35,13 @@
<body>
<div id="header"></div>
<div id="content">
<div id="headline">
<h2 id="title"></h2>
<button id="permalink"><img src="images/link.png" alt="permalink" /> Permalink</button>
<br style="clear: both" />
</div>
<div id="plot">
<div id="flot"></div>
<div id="overlay"></div>
@ -92,7 +96,10 @@
</tr>
<tr>
<td><img src="images/eye.png" alt="" /> Darstellung</td>
<td><label for="render-points"><input type="radio" id="render-points" name="render" value="points" /> Punkte</label> <label for="render-lines"><input type="radio" id="render-lines" name="render" value="lines" /> Linien</label></td>
<td>
<label for="render-points"><input type="radio" id="render-points" name="render" value="points" /> Punkte</label>&nbsp;
<label for="render-lines"><input type="radio" id="render-lines" name="render" value="lines" /> Linien</label>
</td>
</tr>
<tr>
<td><label for="backend-url"><img src="images/server.png" alt="" /> Backend-Adresse</label></td>
@ -104,6 +111,7 @@
</tr>
</tbody>
</table>
<div><button name="options-save"><img src="images/save.png" alt="save" /> Einstellungen speichern</button></div>
</div>
</div>
</div>
@ -122,15 +130,17 @@
<div id="entity-subscribe">
<p>Hier k&ouml;nnen Sie einen existierenden Kanal über seine UUID hinzuf&uuml;gen</p>
<p><label for="uuid">UUID: </label><input id="uuid" type="text" size="36" maxlength="36" /></p>
<input type="button" value="hinzufügen" />
<input type="button" value="abonnieren" />
</div>
<div id="entity-create">
<p>Hier können Sie einen neuen Kanal erstellen</p>
<p><label for="type">Typ: </label><select id="type" size="1"><option>Strom (das funktioniert noch nicht)</option></select></p>
<input type="button" value="erstellen" />
</div>
<div id="public-entities">
<p>Hier k&ouml;nnen Sie demn&auml;chst &ouml;ffentliche Kan&auml;le abonnieren.</p>
<p><label for="uuid">Kanal: </label><select id="public-uuids" size="1"><option>Demo (das funktioniert noch nicht)</option></select></p>
<input type="button" value="abonnieren" />
</div>
</div>
</div>

View file

@ -24,65 +24,82 @@
* volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Frontend related functions
*/
/**
* Initialize the WUI (Web User Interface)
*/
vz.wui.init = function() {
// start auto refresh timer
window.setInterval(this.refresh, 3000);
// initialize dropdown accordion
$('#accordion h3').click(function() {
$(this).next().toggle('fast');
return false;
}).next().hide();
// make buttons fancy
// buttons
$('button, input[type=button],[type=image]').button();
$('button[name=options-save]').click(function() { vz.options.save(); });
$('#permalink').click(function() { // TODO add uuids
var u = window.location.protocol + '//' +
window.location.host +
window.location.pathname +
'?from=' + vz.options.plot.xaxis.min +
'&to=' + vz.options.plot.xaxis.max;
window.location = u;
});
$('button[name=entity-add]').click(function() { $('#entity-add').dialog('open'); });
$('#entity-subscribe input[type=button]').click(function() {
try {
vz.uuids.add($('#entity-subscribe input[type=text]').val());
$('#entity-subscribe input[type=text]').val('');
$('#entity-add').dialog('close');
vz.entities.loadDetails();
}
catch (exception) {
vz.wui.dialogs.exception(exception);
}
});
// bind plot actions
$('#controls button').click(this.handleControls);
$('#controls').buttonset();
// tuple resolution
vz.options.tuples = Math.round($('#flot').width() / 3);
vz.options.tuples = Math.round($('#flot').width() / 4);
$('#tuples').val(vz.options.tuples).change(function() {
vz.options.tuples = $(this).val();
vz.entities.loadData();
});
// backend address
$('#backend-url')
.val(vz.options.backendUrl)
.change(function() {
vz.options.backendUrl = $(this).val();
});
// auto refresh
$('#refresh')
.attr('checked', vz.options.refresh)
.change(function() {
vz.options.refresh = $(this).val();
if ($(this).attr('checked')) {
vz.options.refresh = true;
vz.wui.refreshTimeout = window.setTimeout(vz.wui.refresh, vz.options.refreshInterval);
}
else {
vz.options.refresh = false;
window.clearTimeout(vz.wui.refreshTimeout);
}
});
// plot rendering
$('#render-lines')
.attr('checked', vz.options.plot.series.lines.show)
.change(function() {
vz.options.plot.series.lines.show = $(this).attr('checked');
vz.options.plot.series.points.show = !$(this).attr('checked');
$('#render-lines').attr('checked', (vz.options.render == 'lines'));
$('#render-points').attr('checked', (vz.options.render == 'points'));
$('input[name=render][type=radio]').change(function() {
if ($(this).attr('checked')) {
vz.options.render = $(this).val();
vz.drawPlot();
});
$('#render-points')
.attr('checked', vz.options.plot.series.points.show)
.change(function() {
vz.options.plot.series.lines.show = !$(this).attr('checked');
vz.options.plot.series.points.show = $(this).attr('checked');
vz.drawPlot();
});
}
});
};
/**
@ -93,28 +110,10 @@ vz.wui.dialogs.init = function() {
$('#entity-add.dialog').dialog({
autoOpen: false,
title: 'Kanal hinzuf&uuml;gen',
width: 600,
width: 530,
resizable: false
});
$('#entity-add.dialog > div').tabs();
// open entity dialogs
$('button[name=entity-add]').click(function() {
$('#entity-add').dialog('open');
});
// subscribe UUID
$('#entity-subscribe input[type=button]').click(function() {
try {
vz.uuids.add($('#entity-subscribe input[type=text]').val());
$('#entity-subscribe input[type=text]').val('');
$('#entity-add').dialog('close');
vz.entities.loadDetails();
}
catch (exception) {
vz.exceptionDialog(exception);
}
});
};
/**
@ -153,12 +152,13 @@ vz.wui.initEvents = function() {
* Refresh plot with new data
*/
vz.wui.refresh = function() {
if (vz.options.refresh) {
var delta = vz.options.plot.xaxis.max - vz.options.plot.xaxis.min;
vz.options.plot.xaxis.max = new Date().getTime(); // move plot
vz.options.plot.xaxis.min = vz.options.plot.xaxis.max - delta; // move plot
vz.entities.loadData();
}
var delta = vz.options.plot.xaxis.max - vz.options.plot.xaxis.min;
vz.options.plot.xaxis.max = new Date().getTime(); // move plot
vz.options.plot.xaxis.min = vz.options.plot.xaxis.max - delta; // move plot
vz.entities.loadData();
// schedule next refresh
this.refreshTimeout = window.setTimeout(vz.wui.refresh, vz.options.refreshInterval);
};
/**
@ -251,7 +251,6 @@ vz.entities.loadDetails = function() {
/**
* Create nested entity list
* @param data
*/
vz.entities.show = function() {
var i = 0;
@ -373,10 +372,18 @@ vz.entities.loadData = function() {
});
};
vz.wui.updateHeadline = function() {
var from = $.plot.formatDate(new Date(vz.options.plot.xaxis.min + vz.options.timezoneOffset), vz.options.plot.xaxis.timeformat, vz.options.plot.xaxis.monthNames);
var to = $.plot.formatDate(new Date(vz.options.plot.xaxis.max + vz.options.timezoneOffset), vz.options.plot.xaxis.timeformat, vz.options.plot.xaxis.monthNames);
$('#title').text(from + ' - ' + to);
}
/**
* Draws plot to container
*/
vz.drawPlot = function () {
vz.wui.updateHeadline();
var data = new Array;
vz.entities.each(function(entity, parent) {
if (entity.active && entity.data && entity.data.count > 0) {
@ -395,6 +402,9 @@ vz.drawPlot = function () {
$('#overlay').empty();
}
vz.options.plot.series.lines.show = (vz.options.render == 'lines');
vz.options.plot.series.points.show = (vz.options.render == 'points');
vz.plot = $.plot($('#flot'), data, vz.options.plot);
};
@ -402,22 +412,47 @@ vz.drawPlot = function () {
* Universal helper for backend ajax requests with error handling
*/
vz.load = function(context, identifier, data, success) {
$.getUrlVars().each(function (key, value) { // TODO parse only once
data[key] = value;
});
$.ajax({
success: success,
url: vz.options.backendUrl + '/' + context + '/' + identifier + '.json',
url: this.options.backendUrl + '/' + context + '/' + identifier + '.json',
dataType: 'json',
data: data,
error: function(xhr) {
json = JSON.parse(xhr.responseText);
vz.wui.dialogs.error(xhr.statusText, json.exception.message, xhr.status); // TODO throw exception?
vz.wui.dialogs.error(xhr.statusText, json.exception.message, xhr.status); // TODO or throw exception?
}
});
};
/**
* Parse URL GET parameters
*/
vz.parseUrlVars = function() {
var vars = $.getUrlVars();
for (var key in vars) {
if (vars.hasOwnProperty(key)) {
switch (key) {
case 'uuid': // add optional uuid from url
try {
vz.uuids.add(vars[key]);
} catch (exception) {
vz.wui.dialogs.exception(exception);
}
break;
case 'from':
vz.options.plot.xaxis.min = parseInt(vars[key]);
break;
case 'to':
vz.options.plot.xaxis.max = parseInt(vars[key]);
break;
case 'debug':
$.getScript('javascripts/firebug-lite.js');
break;
}
}
}
};
/**
* Load definitions from backend
*/

View file

@ -50,43 +50,29 @@ var vz = {
options: { }
};
// check for debugging & load firebug
if ($.getUrlVar('debug')) {
$.getScript('javascripts/firebug-lite.js');
}
// executed on document loaded complete
// this is where it all starts...
$(document).ready(function() {
$(window).unload(function() {
vz.uuids.save();
vz.options.save();
});
$(window).resize(function() {
vz.options.tuples = Math.round($('#flot').width() / 3);
$('#tuples').val(vz.options.tuples);
vz.drawPlot();
});
// parse uuids & options from cookie
vz.uuids.load();
vz.options.load();
// initialize user interface
vz.wui.init();
vz.wui.initEvents();
vz.wui.dialogs.init();
// add optional uuid from url
if($.getUrlVar('uuid')) {
vz.uuids.add($.getUrlVar('uuid'));
}
if (vz.uuids.length == 0) {
$('#addUUID').dialog('open');
}
// parse uuids & options from cookie
vz.definitions.load();
vz.uuids.load();
vz.options.load();
vz.parseUrlVars();
if (vz.uuids.length == 0) {
$('#entity-add').dialog('open');
}
vz.entities.loadDetails();
});

View file

@ -26,10 +26,13 @@
// default time interval to show
vz.options = {
language: 'de',
backendUrl: '../backend/index.php',
tuples: 300,
render: 'lines',
refresh: false,
defaultInterval: 1*24*60*60*1000, // 1 day
refreshInterval: 5*1000, // 5 secs
defaultInterval: 24*60*60*1000, // 1 day
timezoneOffset: -(new Date().getTimezoneOffset() * 60*1000) // TODO add option with timezone dropdown
};
@ -69,20 +72,12 @@ vz.options.plot = {
grid: {
hoverable: true,
autoHighlight: false
},
zoom: {
interactive: true,
frameRate: null
},
pan: {
interactive: false,
frameRate: 20
}
}
vz.options.save = function() {
for (var key in this) {
if (typeof this[key] == 'string' || typeof this[key] == 'number') {
if (this.hasOwnProperty(key) && typeof this[key] != 'function' && typeof this[key] != 'object' && typeof this[key] != 'undefined') {
$.setCookie('vz_' + key, this[key]);
}
}
@ -90,10 +85,18 @@ vz.options.save = function() {
vz.options.load = function() {
for (var key in this) {
if (typeof this[key] == 'string' || typeof this[key] == 'number') {
var value = $.getCookie('vz_' + key);
if (typeof value != undefined) {
this[key] = (typeof this[key] == 'number') ? parseFloat(value) : value;
var value = $.getCookie('vz_' + key);
if (typeof value != 'undefined') {
switch(typeof this[key]) {
case 'string':
this[key] = value;
break;
case 'number':
this[key] = Number(value);
break;
case 'boolean':
this[key] = (value == 'true');
break;
}
}
}

View file

@ -31,9 +31,10 @@ vz.uuids.add = function(uuid) {
if (this.validate(uuid)) {
if (!this.contains(uuid)) {
this.push(uuid);
this.save();
}
else {
throw new Exception('UUIDException', 'UUID already added');
throw new Exception('UUIDException', 'UUID already added: ' + uuid);
}
}
else {
@ -47,6 +48,7 @@ vz.uuids.add = function(uuid) {
vz.uuids.remove = function(uuid) {
if (this.contains(uuid)) {
this.splice(this.indexOf(uuid), 1); // remove uuid from array
this.save();
}
else {
throw new Exception('UUIDException', 'UUID unkown: ' + uuid);

View file

@ -1,9 +1,21 @@
/* jQuery UI */
/* jQuery UI customizations */
input.ui-button {
padding: 0.1em 0.5em;
}
.ui-button-text-only .ui-button-text {
padding:0.1em 0.5em;
padding: 0.1em 0.5em;
}
.ui-error .ui-widget-header {
background-image: url("../images/ui-bg_gloss-wave_35_red_500x100.png");
}
#entity-add.ui-dialog-content {
padding: 0.3em 0 0;
}
.ui-tabs .ui-tabs-nav li a {
padding: 0.1em 0.7em;
}

View file

@ -137,7 +137,15 @@ tbody tr td {
width: 20px;
}
/* additional theming for user interface */
.ui-error .ui-widget-header {
background-image: url("../images/ui-bg_gloss-wave_35_red_500x100.png");
#headline {
margin-bottom: 15px;
}
#title {
margin: 0.2em;
float: left;
}
#permalink {
float: right;
}