recorder/docroot/table/index.html

352 lines
10 KiB
HTML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>OwnTracks Recorder Table</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" sizes="192x192" href="../static/recorder.png" />
<link rel="apple-touch-icon" href="../static/recorder.png" />
<script src="../static/js/jquery-1.12.0.min.js" type="text/javascript"></script>
<script src="../static/js/mustache.js"></script>
<script src="../static/js/moment.min.js"></script>
<script src="defaultface.js"></script>
<script src="config.js"></script>
<link rel="stylesheet" type="text/css" href="js/jquery.dataTables.min.css">
<script type="text/javascript" charset="utf8" src="js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="otable.css">
<script type="text/javascript">
var tab;
/*
* Insert data object into table or update existing row. `data' must
* have 'topic', as that is the key into column 0 of the datatable.
*/
function upsert(data) {
var found = false;
var idx;
tab.rows().indexes().each( function(idx) {
var d = tab.row(idx).data();
if (d && (d.topic == data.topic)) {
found = true;
/* idx is index of updated row (0--n) */
idx = tab.row(idx).data(data);
/* Highlight */
var row = tab.rows(idx, {order:'index'}).nodes().to$();
$(row).animate({ 'backgroundColor': '#FF9900' }, 650, function(){
$(row).animate({'backgroundColor': 'white'}, 650);
});
}
});
if (!found) {
idx = tab.row.add(data);
}
tab.draw();
}
function listusers(data) {
for (i in data) {
var d = data[i];
if (d.username == 'ping' && d.device == 'ping') {
continue;
}
if (!d.topic) {
console.log("SKIP " + JSON.stringify(d));
continue;
}
var dt = moment.utc(d.tst * 1000).local();
d['fulldate'] = dt.format("DD MMM YYYY HH:mm:ss");
d['addr'] = d['addr'] || '(' + d['lat'] + ',' + d['lon'] + ')';
d['cc'] = d['cc'] || '__';
d['tid'] = d['tid'] || d.topic.substr(d.topic.length - 2, d.topic.length);
upsert(d);
}
}
function getuserlist() {
var dataURI = location.protocol + "//" + location.host;
var parts = location.pathname.split('/');
for (var i = 1; i < parts.length - 2; i++) {
dataURI = dataURI + "/" + parts[i];
}
dataURI = dataURI + "/api/0/last" + location.search;
console.log("dataURI = " + dataURI);
$.ajax({
url: dataURI,
type: "GET",
dataType: 'json',
success: function(data) {
// console.log(JSON.stringify(data));
listusers(data);
},
error: function(jqXHR, textstatus, errorthrown) {
console.log(textstatus, errorthrown);
console.log(jqXHR.status + " " + jqXHR.responseText);
},
});
}
$(document).ready(function() {
getuserlist();
console.log(JSON.stringify(location));
var counter = 0;
tab = $('#livetable').DataTable({
paging: false,
searching: true,
ordering: true,
autoWidth: false,
order: [[ 2, "desc" ]],
columnDefs: [
{ orderable : true, targets: [0, 1, 3, 4, 5] },
{
className: 'topic',
name: 'topic',
title: config.column_titles.topic,
visible: false,
data: null,
render: 'topic',
"targets" : [0],
},
{
className: 'face',
name: 'face',
title: config.column_titles.face,
visible: true,
data: null,
"targets" : [1],
render : function(data, type, row) {
data['face'] = data['face'] || defaultface;
var t = "<img class='img-circle' src='data:image/png;base64,{{ face }}' height='20' width='20' />";
return Mustache.render(t, data);
}
},
{
className: 'fulldate',
name: 'fulldate',
title: config.column_titles.fulldate,
visible: true,
data: null,
render: 'fulldate',
"targets" : [2],
},
{
className: 'name',
name: 'name',
title: config.column_titles.name,
visible: true,
data: null,
render: function(data, type, row) {
var t = data['name'] || data['topic'];
return t;
},
"targets" : [3],
},
{
className: 'user',
name: 'user',
title: config.column_titles.user,
visible: true,
data: null,
createdCell: function(td, cellData, rowData, row, col) {
if (rowData._http) {
$(td).css('color', 'gray');
}
},
render: function(data, type, row) {
var t = "{{username}}/{{device}}";
return Mustache.render(t, data);
},
"targets" : [4],
},
{
className: 'tid',
name: 'tid',
title: config.column_titles.tid,
visible: true,
data: null,
render: 'tid',
"targets" : [5],
},
{
className: 'batt',
name: 'batt',
title: config.column_titles.batt,
visible: true,
data: null,
render: function(data, type, row) {
if (typeof data.batt === 'undefined' || data.batt === null) {
return '-';
}
if (typeof data.batt === 'object') {
// console.log(JSON.stringify(data.batt));
return data.batt[data.batt.length - 1]['batt'] + "v";
}
var t = "{{batt}}%";
if (data.batt < 25) {
t = '<span class="warning">' + t + '</span>';
}
return Mustache.render(t, data);
},
"targets" : [6],
},
{
className: 'vel',
name: 'vel',
title: config.column_titles.vel,
visible: true,
data: null,
render: function(data, type, row) {
if (typeof data.vel === 'undefined' || data.vel === null) {
return '';
}
try {
var v = parseInt(data.vel, 10);
if (v < 0) {
return '';
}
} catch(err) {
return '';
}
var t = "{{vel}}";
return Mustache.render(t, data);
},
"targets" : [7],
},
{
className: 'cog',
name: 'cog',
title: config.column_titles.cog,
visible: true,
data: null,
render: function(data, type, row) {
if (typeof data.cog === 'undefined' || data.cog === null) {
return '';
}
try {
var c = parseInt(data.cog, 10);
if (c < 0) {
return '';
}
} catch(err) {
return '';
}
var t = "{{cog}}";
return Mustache.render(t, data);
},
"targets" : [8],
},
{
className: 'cc',
name: 'cc',
title: config.column_titles.cc,
visible: true,
data: null,
render: function(data, type, row) {
var t = "<img src='flags/{{cc}}.png' title='{{cc}}'/>";
return Mustache.render(t, data);
},
"targets" : [9],
},
{
className: 'addr',
name: 'addr',
title: config.column_titles.addr,
visible: true,
data: null,
render : function(data, type, row) {
var t = "<a target='_new' href='http://maps.google.com/?q={{lat}},{{lon}}'>{{addr}}</a>";
return Mustache.render(t, data);
},
"targets" : [10],
},
],
});
$('button.toggle-vis').on('click', function (e) {
e.preventDefault();
// Get column API object
var column = tab.column( $(this).attr('data-column') );
column.visible( ! column.visible() );
});
$('#dataload').on('click', function(e) {
e.preventDefault();
getuserlist();
});
/* Click on a row should show object; remove `face' */
// $('#livetable tbody').on("click", "tr", function(ev){
$('#livetable tbody').on("click", "td", function(ev){
// alert( "Index: " + tab.row(this).index() );
var aPos = $('#livetable').dataTable().fnGetPosition(this);
var aData = $('#livetable').dataTable().fnGetData(aPos[0]);
var column = aPos[1];
if (column == 1) {
// var o = tab.row(this).data();
var o = aData;
delete o.face;
alert(JSON.stringify(o));
}
});
});
</script>
</head>
<body>
<ul>
<li><button id='dataload'>Reload data</button></li>
</ul>
<div id='header'>
<table id="livetable" class="display compact hover" cellspacing="0" width="100%">
</table>
</div>
<div id='togglers'>
<ul>
<li>Toggle</li>
<li><button class='toggle-vis' data-column='0'>topic</button></li>
<li><button class='toggle-vis' data-column='4'>user</button></li>
<li><button class='toggle-vis' data-column='6'>battery</button></li>
</ul>
</body>
</html>