• No results found

5.2 Systeeminrichting

6.1.1 Structuur

De webinterface heeft een modulaire opzet, waarbij het hoofdscherm een aantal tabbladen bevat die toegang geven tot de verschillende applicaties van het systeem. De tabbladen zijn ondergebracht in aparte HTML-pagina's die naar elkaar linken. Als er in een tabblad nog subtabs worden gebruikt, worden deze door middel van een PHP-script geïmporteerd in het

hoofdtabblad. De naam van het te openen subtabblad wordt dan via de URL doorgegeven (bijvoorbeeld: 'c2ip.php?t=operation').

Pagina's met actieve inhoud worden door middel van JAVA-requests ingevoegd vanuit de server. Hiervoor wordt per tabblad een JavaScriptbestand geïmporteerd dat deze requests afwikkelt.

Ten slotte zijn er pop-upschermen, zoals het detailscherm met camera-informatie. Deze schermen worden door jQuery aangeroepen (met de '$.dialog'-functie) en verder als normale HTML-pagina's uitgevoerd.

Figuur 6-1. Boomstructuur LDK Connect webinterface

XML Gateway index.php Install _c2ip_install.php Setup _c2ip_setup.php Floor view _floor_floorview.php C2IP c2ip.php Floor floor.php System system.php About about.php LDK Connect Main Operation _c2ip_operation.php Locations _floor_locations.php

Hoofdstuk 6 - Resultaten

6.1.2 Uitwerkingen

In dit hoofdstuk worden twee voorbeelden van interactieve componenten van de webinterface verder uitgewerkt:

• Operation-tab, die de operationele informatie van de camera’s weergeeft. Zie voor de functionele beschrijving van deze sectie paragraaf 7.3.3 op pagina 43.

• Floor view-tab, die de actuele cameralocaties op een plattegrond weergeeft. Zie voor de functionele beschrijving van deze sectie paragraaf 7.4.2 op pagina 45.

Opmerking

In de uitgewerkte voorbeelden zijn de niet-relevante stukken code weggelaten.

6.2 Uitwerking operation-tab

6.2.1 HTML-code

De HTML-code is het basis-sjabloon voor de opbouw van de webinterface. In de header van de pagina worden de CSS-files (voor de opmaak) en de JavaScriptfiles (voor de clientfuncties) geïmporteerd.

Broncode 6-2. HTML-code voor het afbeelden van de C2IP-tab (“c2ip.html”).

<!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>

<meta http-equiv="Content-type" content="text/html;charset=UTF-8;IE=7" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

<title>LDK Connect | C2IP Monitoring</title>

<link rel="stylesheet" href="styles/styles.css" type="text/css" /> <link rel="stylesheet" href="styles/tables.css" type="text/css" /> <script type="text/JavaScript" src="scripts/jquery.js"></script> <script type="text/JavaScript" src="scripts/jquery-ui.js"></script> <script type="text/JavaScript" src="scripts/c2ip.js"></script> </head>

<body>

<div class="content"> <div class="head">

<div class="tab_empty_body"><img src="img/LDK_logo.gif" class="logo"></div> <div class="tab_container"> <!-- Tab: XML Gateway--> <!-- Tab: C2IP --> <!-- Tab: Field --> <!-- Tab: System --> <!-- Tab: About --> </div> </div> <div class="main">

Hoofdstuk 6 - Resultaten

<!-- C2IP Network panel #1 --> <!-- C2IP Network panel #2 -->

<div class="box">

<div class="tab_container">

<!-- subtabs -->

</div>

<div class="box1_top topreset">&nbsp;</div> <div class="box1_body" id="c2ipListBox">

// Wacht tot het hele document ingeladen is en start dan het updaten van de tabel

<script type="text/JavaScript"> $(document).ready(function() {

refreshTableOperation(); });

</script>

<span class="section_titles">Camera systems:</span> <div class="table_large_heading">

<table cellspacing="0" cellpadding="0" class="large" id="dynaTableHead">

<tbody /> </table> </div>

<div class="table_large_body" style="height:330px" id="c2ipListTable">

<table cellspacing="0" cellpadding="0" class="large" id="dynaTableBody"> <tbody /> </table> </div> </div> <div class="box1_bottom">&nbsp;</div> </div> </div> </div> </body> </html>

6.2.2 JavaScript-code

Dit is een gedeelte van de JavaScriptcode dat de opbouw van de cameratabel voor zijn rekening neemt. Met behulp van jQuery wordt een AJAX-request gestuurd aan het PHP-script “getCameraData.php”, dat op de server staat.

Dit script levert een JavasScript-object (“data”) in JSON-opmaak terug dat een dataset met cameragegevens bevat. Vervolgens wordt het object als array uitgelezen en een HTML-tabel gecontstrueerd. Ten slotte wordt deze tabel met behulp van jQuery in de HTML-code gestopt. Broncode 6-3. JavaScript-code voor het aanmaken van de cameratabel (“c2ip.js”).

function refreshTableOperational() {

// Eerste keer tabel aanmaken

getTableOperational();

// Steeds herhalen na 1.5s tussentijd

setTimeout("refreshTableOperational()", 1500); }

function getTableOperational() {

// Haal met een AJAX-request data op van de server als JSON-bericht

Hoofdstuk 6 - Resultaten

// Maak HTML-tabel leeg

$("#dynaTable").empty();

// Bouw tableHead op in string

$("#dynaTable").append('<thead>'); var strTableHead = "";

strTableHead += "<tr>";

strTableHead += "<th width=\"83px\" class=\"large\">Number</td>"; strTableHead += "<th width=\"83px\" class=\"large\">Type</td>"; strTableHead += "<th width=\"83px\" class=\"large\">System</td>"; strTableHead += "<th width=\"83px\" class=\"large\">On Air</td>"; strTableHead += "<th width=\"83px\" class=\"large\">Quality</td>"; strTableHead += "<th width=\"43px\" class=\"large\">Ref.</td>"; strTableHead += "<th width=\"43px\" class=\"large\">Gen.</td>"; strTableHead += "<th class=\"large\">Message</td>";

strTableHead += "</tr>";

// hang de gebouwde table header aan het DOM-element THEAD

$("#dynaTable").find('thead').append(strTableHead);

// Bouw tableBody op in string

$("#dynaTable").append('<tbody>'); var strTableBody = "";

var YesNo = new Array("No","Yes"); var OnAirBulb = new Array("grey","red"); var IsoBulb = new Array("grey","yellow"); var CallBulb = new Array("grey","green");

var OddEven = new Array("alternatingColor_2","alternatingColor_1");

// loop door alle elementen met de Query-iterator ‘each’

$.each(data, function(key){ strTableBody+= "<tr class='"+OddEven[key%2]+"' onMouseOver=\"this.className='alternatingColor_3';this.style.cursor='pointer'\" onMouseOut=\"this.className='"+OddEven[key%2]+"'\" onclick = \"openDialog('details_camera.php?camnum="+this["Camnum"]+"', 'details', 425, 525);\">"; strTableBody+= "<td class=’cell80px’>"+this["Camnum"]; if (this["Message"] != "") {

strTableBody += "<img src='warning_icon.gif' class='inline'>"; }

strTableBody+= "</td>";

strTableBody+= "<td class=’cell80px’>"+this["Type"]+"</td>"; strTableBody+= "<td class=’cell80px’>"+this["System"]+"</td>"; strTableBody+= "<td class=’cell80px’>";

strTableBody+= "<img src=’bulb_"+OnAirBulb[this["OnAir"]]+".gif’>"; strTableBody+= "<img src=’bulb_"+IsoBulb[this["Iso"]]+".gif>";

strTableBody+= "<img src=’bulb_"+CallBulb[this["Calsignal"]]+".gif’>"; strTableBody+= "</td>";

strTableBody+= "<td class=’cell80px’><img src=’/blue.gif’ height=’10\" width=’"+this["Quality"]+"’></td>"; strTableBody+= "<td class=’cell40px’>"+YesNo[this["Reference"]]+"</ td>"; strTableBody+= "<td class=’cell40px’>"+YesNo[this["Genlock"]]+"</td>"; strTableBody+= "<td class=’cell’>"+this["Message"]+"</td>"; strTableBody+= "</tr>"; });

// hang de gebouwde table body aan het DOM-element TBODY

$("#dynaTable").find('tbody').append(strTableBody); });

Hoofdstuk 6 - Resultaten

6.2.3 PHP-script

Het PHP-script staat op de server en wordt aangeroepen door een AJAX-request. Het script maakt een connectie naar een MySQL-database (die ook op de server staat) en haalt met een query een recordset op. Deze wordt vervolgens als JSON-bericht naar de client teruggestuurd. Broncode 6-4. PHP-script voor het ophalen van de cameradata (“getCameraData.php”).

<?php

// Genereer een text-type header voor het JSON-bericht

header('Content-Type: text/JavaScript'); header('Cache-Control: no-cache'); header('Pragma: no-cache');

// Haal de camera-informatie op uit de database

$connection = mysql_connect("localhost","root"); if (!$connection) {

die("Could not connect to database: ".mysql_error()); }

mysql_select_db("cambase", $connection);

$query = "SELECT * FROM cameras WHERE Enabled = '1' ORDER BY Camnum ASC"; $result = mysql_query($query);

// Zet om naar een array en voer uit als JSON-gecodeerd bericht

$rs = array(); while($row = mysql_fetch_assoc($result)){ array_push($rs,$row); } echo json_encode($rs); // Sluit de database-verbinding mysql_close($connection); ?>

6.3 Uitwerking floorview-tab

6.3.1 HTML/PHP-code

Dze pagina vraagt met behulp van PHP-script alle locatiegegevens uit de database. Met deze gegevens worden vervolgens JavaScriptfuncties gebouwd die er op hun beurt voor zorgen dat de camera-ikoontje worden toegevoegd aan de ‘floor’.

Broncode 6-5. HTML-code voor het aanmaken van de floorview.

<...>

<script type="text/javascript" src="scripts/floor.js"></script>

<...>

<!--- Laadt de default ‘floor’ -->

<div id="floorcontainer" style="background: url('/floors/floor_soccer.gif'); clear:right; width:832px; height:420px; overflow:hidden; position:relative;"></ div>

<script language="javascript">; <?php

// ophalen informatie uit database en daarna JavaScript genereren

$connection = mysql_connect("localhost","root");

Hoofdstuk 6 - Resultaten

mysql_select_db("cambase", $connection);

$query = "SELECT * FROM Locations ORDER BY Label ASC"; $result = mysql_query($query);

$rows = mysql_num_rows($result);

while ($row = mysql_fetch_array($result)){

echo "addLocation('".$row[Label]."','".$row[Camnum]."', '".$row[Name]."','".$row[MapX]."','".$row[MapY]."');\n"; }

mysql_close($connection); ?>

// Voorbeeld van gegenereerde JavaScriptcode (run time): //

// addLocation('16HiL','21', '16m High Left','562px','345px'); // addLocation('16HiR','30', '16m High Right','44px','202px'); // addLocation('Cb','80', 'Centre Back','595px','5px');

// addLocation('FGL','22', 'Low Goal Left','20px','284px'); // addLocation('FGR','23', 'Low Goal Right ','710px','200px'); // addLocation('GLL','31', 'Goal Line Left','721px','285px'); // addLocation('GLR','21', 'Goal Line Right','279px','247px'); // addLocation('LL','80', 'Left Luggage','719px','65px'); // addLocation('MC1','', 'Main Camera','125px','345px');

// wacht tot hele pagina ingeladen is en start dan de AJAX-refresh

$(document).ready(function() { refreshCameraStatus(); }); </script> <...>

6.3.2 JavaScript-code

De JavaScript-functie ‘AddLocation’ maakt het camera-ikoon aan. Het maakt gebruik van de jQueryUI-functie ‘draggable’. De afbeeldingen worden gestapeld (via z-indexing) en er wordt een dialoogscherm toegevoegd (om het pop-upscherm met detailgegevens te tonen). Ook wordt de event-trigger ‘stop’ toegekend aan de draggable-status. Dit betekent dat als het ikoontje wordt losgelaten, het script ‘postLocation.php’ wordt uitgevoerd.

Broncode 6-6. JavaScript-code voor de functie “addLocation()”.

function addLocation(label,camnum,name,posx,posy) {

// opbouwen string voor het toevoegen van de versleepbare DIV

var camStr = "";

camStr += "<div id='" + label + "' "; camStr += "class='draggable_layout' ";

camStr += "style='text-align: center; position: absolute; left: "+posx+"; top: "+posy+";'>";

camStr += "<div style='width:70px;height:60px;position:relative;'>"; camStr += "<img src='img/fieldcam_grey.gif' id='cam_" + label + "' alt='' title='' style='position:absolute;left:0px;top:5px;z-index:1'"; if (camnum != ""){ camStr += " onDblclick=\"openDialog(\'details_camera.php?camnum="+camnum+"\',\'details\',42 5,525);\""; } camStr += ">";

camStr += "<img src='img/warning_empty.gif' id='war_" + label + "' style='position:absolute;left:40px;top:0px;z-index:2;'>";

camStr += "<img src='img/bulb_small_grey.gif' id='air_" + label + "' style='position:absolute;left:16px;top:43px;z-index:3;'>";

Hoofdstuk 6 - Resultaten

camStr += "<img src='img/bulb_small_grey.gif' id='iso_" + label + "' style='position:absolute;left:30px;top:43px;z-index:4;'>";

camStr += "<img src='img/bulb_small_grey.gif' id='cal_" + label + "' style='position:absolute;left:44px;top:43px;z-index:5;'>"; camStr += "</div>"; camStr += name; if (camnum != ""){ camStr += " ("+camnum+")"; } camStr += "</div>";

// met jQuery de div toevoegen en versleepbaar maken

$("#floorcontainer").append(camStr); $(".draggable_layout").draggable();

// Voeg een event-trigger toe voor het stoppen met slepen

// bij droppen van het icoon eindpositie opslaan met AJAX in database

$(".draggable_layout").draggable({ containment: "#floorcontainer", stop: function(event,ui){ strlabel=this.id; strx=this.style.left; stry=this.style.top;

$.post("postLocation.php", { label: strlabel, x: strx, y: stry } ); }

}); }

6.3.3 PHP-script

Dit is het PHP-script dat zorgt voor het wegschrijven van de eindlocatie van het camera-ikoon naar de database. Het script wordt aangeroepen door een AJAX-request van de webpagina. Broncode 6-7. PHP-script voor opslaan eindposite camera-ikoon in database.

<?php

// haal gegevens op van AJAX-post request

$label= $_POST['label']; $X = $_POST['x'];

$Y= $_POST['y'];

// Maak connectie met database

$connection = mysql_connect("localhost","root");

if (!$connection) { die("Could not connect to database: ".mysql_error()); } mysql_select_db("cambase", $connection);

// Sla positie van draggable icoon op in database

$query = "UPDATE Locations SET MapX = '".$X."', MapY = '".$Y."' WHERE Label = '".$label."'";

mysql_query($query);

// Sluit de database-verbinding

mysql_close($connection); ?>