annotate test_create/test_create.html @ 168:f95a30a25a87 Dev_main

create_test: File API to handle dragged in XML file.
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Wed, 03 Jun 2015 12:54:08 +0100
parents fa33bf58d863
children 5aff374de11c
rev   line source
n@156 1 <!DOCTYPE html>
n@156 2 <html lang="en">
n@156 3 <head>
n@156 4 <meta charset="utf-8">
n@156 5
n@156 6 <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
n@156 7 Remove this if you use the .htaccess -->
n@156 8 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
n@156 9
n@156 10 <title>WAET Create Test</title>
n@156 11 <meta name="description" content="">
n@156 12 <meta name="author" content="">
n@156 13
n@156 14 <meta name="viewport" content="width=device-width; initial-scale=1.0">
n@157 15
n@157 16 <script type="text/javascript">
n@157 17 // To aid 'one-page set-up' all scripts and CSS must be included directly in this file!
n@157 18 var topLevel;
n@157 19 window.onload = function() {
n@157 20 // Initialise page
n@157 21 topLevel = document.getElementById('topLevelBody');
n@157 22 var setup = document.createElement('div');
n@157 23 setup.id = 'setupTagDiv';
n@157 24
n@168 25 // Setup drag/drop handles
n@168 26 var dropBody = document.getElementById('dragFile');
n@168 27 dropBody.addEventListener('dragover', handleDragOver, false);
n@168 28 dropBody.addEventListener('dragenter',handleDragEnter,false);
n@168 29 dropBody.addEventListener('dragleave',handleDragLeave,false);
n@168 30 dropBody.addEventListener('drop', handleDrop,false);
n@157 31 };
n@157 32
n@162 33 function attributePair(string, type, mandatory){
n@157 34 var id = document.createElement("span");
n@157 35 id.textContent = string;
n@157 36 var input = document.createElement("input");
n@157 37 input.type = type;
n@162 38 if (type == 'text') {
n@162 39 if (mandatory == true) {
n@162 40 input.setAttribute('mandatory','true');
n@162 41 }
n@162 42 else {
n@162 43 input.setAttribute('mandatory','false');
n@162 44 }
n@162 45 }
n@157 46 return [id, input];
n@157 47 }
n@157 48
n@159 49 function removeNode(event) {
n@159 50 event.srcElement.parentElement.parentElement.removeChild(event.srcElement.parentElement);
n@159 51 }
n@159 52
n@162 53 function buttonClickedValidate() {
n@162 54 var ready = validate();
n@162 55 if (ready == false) {
n@162 56 var errMsg = document.getElementById('errorMessage');
n@163 57 errMsg.textContent = "There were some errors with your XML. Any input boxes highlighted in red are invalid because they are empty or because its ID matches another elements ID. Please fill these in correctly. Any boxes which are yellow are not-invalid but will use the default value.";
n@162 58 errMsg.style.visibility = 'visible';
n@162 59 document.getElementById('createXML').disabled = true;
n@162 60
n@162 61 } else {
n@162 62 var errMsg = document.getElementById('errorMessage');
n@162 63 errMsg.textContent = "";
n@162 64 errMsg.style.visiblity = 'hidden';
n@162 65 document.getElementById('createXML').disabled = false;
n@162 66 }
n@162 67 }
n@162 68
n@163 69 function buttonClickedSubmit() {
n@163 70 var ready = validate();
n@163 71 if (ready == true) {
n@167 72 var xmlDoc = buildXML();
n@167 73 var inject = document.getElementById('errorMessage');
n@167 74 createProjectSave(xmlDoc, inject);
n@167 75 }
n@167 76 }
n@167 77
n@167 78 function createProjectSave(xmlDoc, injectPoint) {
n@167 79 var parent = document.createElement("div");
n@167 80 parent.appendChild(xmlDoc);
n@167 81 var file = [parent.innerHTML];
n@167 82 var bb = new Blob(file,{type : 'application/xml'});
n@167 83 var dnlk = window.URL.createObjectURL(bb);
n@167 84 var a = document.createElement("a");
n@167 85 a.hidden = '';
n@167 86 a.href = dnlk;
n@167 87 a.download = "save.xml";
n@167 88 a.textContent = "Save File";
n@167 89 injectPoint.appendChild(a);
n@167 90 }
n@167 91
n@167 92 function buildXML() {
n@167 93 var xmlDoc = document.createElement('BrowserEvalProjectDocument');
n@167 94 var setup = document.createElement('setup');
n@167 95 setup.setAttribute('interface',document.getElementById('interface').value);
n@167 96 if (document.getElementById('projectReturn').value == "") {
n@167 97 setup.setAttribute('projectReturn',"null");
n@167 98 } else {
n@167 99 setup.setAttribute('projectReturn',document.getElementById('projectReturn').value);
n@167 100 }
n@167 101 setup.setAttribute('randomiseOrder',document.getElementById('randomisePageOrder').checked);
n@167 102 setup.setAttribute('collectMetrics',document.getElementById('collectMetrics').checked);
n@167 103
n@167 104 var globalPreTest = document.createElement('preTest');
n@167 105 var options = document.getElementById('globalPreTest').getElementsByClassName('head');
n@167 106 constructPrePost(globalPreTest, options);
n@167 107
n@167 108 var globalPostTest = document.createElement('postTest');
n@167 109 options = document.getElementById('globalPostTest').getElementsByClassName('head');
n@167 110 constructPrePost(globalPostTest, options);
n@167 111
n@167 112 var globalMetrics = document.createElement('metric');
n@167 113 options = document.getElementById('globalMetric').getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@167 114 for (var i=0; i<options.length; i++) {
n@167 115 if (options[i].checked) {
n@167 116 var metric = document.createElement('metricEnable');
n@167 117 metric.textContent = options[i].id;
n@167 118 globalMetrics.appendChild(metric);
n@163 119 }
n@167 120 }
n@167 121 setup.appendChild(globalPreTest);
n@167 122 setup.appendChild(globalPostTest);
n@167 123 setup.appendChild(globalMetrics);
n@167 124 xmlDoc.appendChild(setup);
n@167 125
n@167 126 var audioHolders = document.getElementsByName('audio-holder');
n@167 127 for (var i=0; i<audioHolders.length; i++) {
n@167 128 var audioHolder = document.createElement('audioHolder');
n@167 129 var audioHolderDOM = audioHolders[i];
n@167 130 var attribs = audioHolderDOM.getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@167 131 audioHolder.id = attribs[0].value;
n@167 132 if (attribs[1].value != "") {audioHolder.setAttribute('sampleRate',attribs[1].value);}
n@167 133 if (attribs[2].value != "") {audioHolder.setAttribute('hostURL',attribs[2].value);}
n@167 134 audioHolder.setAttribute('randomiseOrder',attribs[3].checked);
n@167 135 audioHolder.setAttribute('repeatCount',attribs[4].checked);
n@167 136 audioHolder.setAttribute('loop',attribs[5].checked);
n@167 137 audioHolder.setAttribute('elementComments',attribs[6].checked);
n@163 138
n@167 139 // Audio-Holder PreTests
n@167 140 var audioHolderPreTest = document.createElement('preTest');
n@167 141 var audioHolderPostTest = document.createElement('postTest');
n@167 142 options = audioHolderDOM.childNodes[2].getElementsByClassName('head');
n@167 143 constructPrePost(audioHolderPreTest, options);
n@167 144 options = audioHolderDOM.childNodes[3].getElementsByClassName('head');
n@167 145 constructPrePost(audioHolderPostTest, options);
n@163 146
n@167 147 audioHolder.appendChild(audioHolderPreTest);
n@167 148 audioHolder.appendChild(audioHolderPostTest);
n@163 149
n@167 150 // audio-Elements
n@167 151 var audioElementsDOM = [];
n@167 152 var commentQuestionDOM = [];
n@167 153 for (var j=0; j<audioHolderDOM.childElementCount; j++) {
n@167 154 var child = audioHolderDOM.childNodes[j];
n@167 155 var name = child.getAttribute('name');
n@167 156 if (name == 'audio-element') {audioElementsDOM.push(child);}
n@167 157 else if (name == 'comment-question') {commentQuestionDOM.push(child);}
n@163 158 }
n@163 159
n@167 160 for (var j=0; j<audioElementsDOM.length; j++) {
n@167 161 var audioElement = document.createElement('audioElement');
n@167 162 attribs = audioElementsDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@167 163 audioElement.id = attribs[0].value;
n@167 164 audioElement.setAttribute('url',attribs[1].value);
n@167 165 audioHolder.appendChild(audioElement);
n@166 166 }
n@167 167
n@167 168 for (var j=0; j<commentQuestionDOM.length; j++) {
n@167 169 var commentQuestion = document.createElement('commentQuestion');
n@167 170 attribs = commentQuestionDOM[j].getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@167 171 commentQuestion.id = attribs[0].value;
n@167 172 commentQuestion.textContent = attribs[1].value;
n@167 173 audioHolder.appendChild(commentQuestion);
n@167 174 }
n@167 175 xmlDoc.appendChild(audioHolder);
n@163 176 }
n@167 177 return xmlDoc;
n@163 178 }
n@163 179
n@163 180 function constructPrePost(parent, options) {
n@163 181 for (var i=0; i<options.length; i++) {
n@163 182 var elem = options[i];
n@163 183 var attributes = elem.getElementsByClassName('attrib')[0].getElementsByTagName('input');
n@163 184 if (elem.getAttribute('name') == 'question-node') {
n@163 185 var node = document.createElement('question');
n@163 186 node.setAttribute('id',attributes[0].value);
n@163 187 node.textContent = attributes[1].value;
n@163 188 } else if (elem.getAttribute('name') == 'statement-node') {
n@163 189 var node = document.createElement('statment');
n@163 190 node.textContent = attributes[0].value;
n@163 191 }
n@163 192 parent.appendChild(node);
n@163 193 }
n@163 194 }
n@163 195
n@162 196 function validate() {
n@162 197 var canExport = true;
n@162 198 // Checks if the XML can be created from the given entries
n@162 199 var inputs = document.getElementsByTagName('input');
n@162 200 for (var i=0; i<inputs.length; i++) {
n@162 201 if (inputs[i].type == 'text') {
n@162 202 if (inputs[i].value == "") {
n@162 203 var mandatory = inputs[i].getAttribute('mandatory');
n@162 204 if (mandatory == "true") {
n@162 205 errorInput(inputs[i]);
n@162 206 canExport = false;
n@162 207 } else {
n@162 208 warningInput(inputs[i]);
n@162 209 }
n@162 210 } else {
n@162 211 goodInput(inputs[i]);
n@162 212 }
n@162 213 }
n@162 214 }
n@163 215
n@163 216 var audioHolders = document.getElementsByName('audio-holder');
n@163 217 for (var i=0; i<audioHolders.length; i++) {
n@163 218 var divs = audioHolders[i].getElementsByClassName('head');
n@163 219 var IDs = [];
n@163 220 for (var j=0; j<divs.length; j++) {
n@163 221 if (divs[j].getAttribute('name') == 'audio-element') {
n@163 222 var obj = divs[j].getElementsByClassName('attrib')[0].children[1];
n@163 223 var aeID = obj.value;
n@163 224 if (aeID != "") {
n@163 225 var unique = true;
n@163 226 for (var k=0; k<IDs.length; k++) {
n@163 227 if (aeID == IDs[k]) {
n@163 228 unique = false;
n@163 229 break;
n@163 230 }
n@163 231 }
n@163 232 if (unique == true) {
n@163 233 IDs.push(aeID);
n@163 234 } else {
n@163 235 errorInput(obj);
n@163 236 canExport = false;
n@163 237 }
n@163 238 }
n@163 239 }
n@163 240 }
n@163 241 }
n@162 242 return canExport;
n@162 243 };
n@162 244
n@162 245 function errorInput(node) {
n@162 246 node.style.backgroundColor = "#FF0000";
n@162 247 }
n@162 248
n@162 249 function warningInput(node) {
n@162 250 node.style.backgroundColor = "#FFFF00";
n@162 251 }
n@162 252
n@162 253 function goodInput(node) {
n@162 254 node.style.backgroundColor = "#FFFFFF";
n@162 255 }
n@162 256
n@157 257 function questionNode() {
n@157 258 var node = document.createElement("div");
n@157 259 node.setAttribute('class','head');
n@157 260 node.setAttribute('name','question-node');
n@157 261 var nodeTitle = document.createElement("span");
n@157 262 nodeTitle.textContent = "Question";
n@157 263 var attributes = document.createElement("div");
n@157 264 attributes.setAttribute('class','attrib');
n@162 265 var id = attributePair("ID:","text", true);
n@162 266 var question = attributePair("Question:","text", false);
n@157 267 node.appendChild(nodeTitle);
n@157 268 id.forEach(function(item){attributes.appendChild(item);},false);
n@157 269 question.forEach(function(item){attributes.appendChild(item);},false);
n@157 270 node.appendChild(attributes);
n@159 271
n@159 272 var removeButton = document.createElement("button");
n@159 273 removeButton.textContent = "Remove";
n@159 274 removeButton.onclick = removeNode;
n@159 275 node.appendChild(removeButton);
n@157 276 return node;
n@157 277 }
n@157 278
n@157 279 function statementNode() {
n@157 280 var node = document.createElement("div");
n@157 281 node.setAttribute('class','head');
n@162 282 node.setAttribute('name','statement-node');
n@157 283 var nodeTitle = document.createElement("span");
n@157 284 nodeTitle.textContent = "Statement";
n@157 285 var attributes = document.createElement("div");
n@157 286 attributes.setAttribute('class','attrib');
n@162 287 var statement = attributePair("Statement:","text",false);
n@157 288 node.appendChild(nodeTitle);
n@157 289 statement.forEach(function(item){attributes.appendChild(item);},false);
n@157 290 node.appendChild(attributes);
n@159 291
n@159 292 var removeButton = document.createElement("button");
n@159 293 removeButton.textContent = "Remove";
n@159 294 removeButton.onclick = removeNode;
n@159 295 node.appendChild(removeButton);
n@157 296 return node;
n@157 297 }
n@157 298
n@157 299 function audioHolderNode() {
n@157 300 var audioHolderCounts = document.getElementsByName("audio-holder").length;
n@157 301 var node = document.createElement("div");
n@157 302 node.setAttribute("class","head");
n@157 303 node.setAttribute("name","audio-holder");
n@159 304 node.setAttribute("id","audio-holder-"+audioHolderCounts);
n@157 305 var nodeTitle = document.createElement("span");
n@159 306 nodeTitle.textContent = "Audio Holder "+(audioHolderCounts+1);
n@157 307
n@157 308 var attributes = document.createElement("div");
n@157 309 attributes.setAttribute('class','attrib');
n@162 310 var id = attributePair("ID:","text",true);
n@159 311 id[1].value=audioHolderCounts;
n@162 312 var hostURL = attributePair("Host URL:", "text",false);
n@162 313 var sampleRate = attributePair("Sample Rate:","text",false);
n@159 314 var randomiseOrder = attributePair("Randomise Element Order:","checkbox");
n@159 315 var repeatCount = attributePair("Repeat Page Count:","number");
n@159 316 repeatCount[1].value = 0;
n@159 317 var loop = attributePair("Loop Element Playback","checkbox");
n@159 318 var elementComments = attributePair("Enable Comment Boxes","checkbox");
n@159 319 id.forEach(function(item){attributes.appendChild(item);},false);
n@159 320 hostURL.forEach(function(item){attributes.appendChild(item);},false);
n@159 321 sampleRate.forEach(function(item){attributes.appendChild(item);},false);
n@159 322 hostURL.forEach(function(item){attributes.appendChild(item);},false);
n@159 323 randomiseOrder.forEach(function(item){attributes.appendChild(item);},false);
n@159 324 repeatCount.forEach(function(item){attributes.appendChild(item);},false);
n@159 325 loop.forEach(function(item){attributes.appendChild(item);},false);
n@159 326 elementComments.forEach(function(item){attributes.appendChild(item);},false);
n@159 327
n@159 328 node.appendChild(nodeTitle);
n@159 329 node.appendChild(attributes);
n@159 330
n@159 331 var pretest = document.createElement("div");
n@159 332 pretest.setAttribute('class','head');
n@159 333 pretest.setAttribute('name','pre-test');
n@159 334 var pretestTitle = document.createElement("h4");
n@159 335 pretestTitle.textContent = "Pre Test";
n@159 336 var buttonAddQ = document.createElement("button");
n@159 337 buttonAddQ.textContent = "Add Pre Test Question";
n@159 338 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
n@159 339 var buttonAddS = document.createElement("button");
n@159 340 buttonAddS.textContent = "Add Pre Test Statement";
n@159 341 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
n@159 342 pretest.appendChild(pretestTitle);
n@159 343 pretest.appendChild(buttonAddQ);
n@159 344 pretest.appendChild(buttonAddS);
n@159 345
n@159 346 var posttest = document.createElement("div");
n@159 347 posttest.setAttribute('class','head');
n@159 348 posttest.setAttribute('name','post-test');
n@159 349 var posttestTitle = document.createElement("h4");
n@159 350 posttestTitle.textContent = "Post Test";
n@159 351 var buttonAddQ = document.createElement("button");
n@159 352 buttonAddQ.textContent = "Add Post Test Question";
n@159 353 buttonAddQ.onclick = function(){event.srcElement.parentElement.appendChild(questionNode());};
n@159 354 var buttonAddS = document.createElement("button");
n@159 355 buttonAddS.textContent = "Add Post Test Statement";
n@159 356 buttonAddS.onclick = function(){event.srcElement.parentElement.appendChild(statementNode());};
n@159 357 posttest.appendChild(posttestTitle);
n@159 358 posttest.appendChild(buttonAddQ);
n@159 359 posttest.appendChild(buttonAddS);
n@159 360
n@159 361 node.appendChild(pretest);
n@159 362 node.appendChild(posttest);
n@159 363
n@159 364 var newAudioElementButton = document.createElement("button");
n@159 365 newAudioElementButton.textContent = "Add audio element";
n@159 366 newAudioElementButton.onclick = function(){
n@159 367 event.srcElement.parentElement.appendChild(audioElementNode());
n@159 368 };
n@159 369 node.appendChild(newAudioElementButton);
n@159 370
n@159 371 var newCommentButton = document.createElement("button");
n@159 372 newCommentButton.textContent = "Add Comment Box";
n@159 373 newCommentButton.onclick = function() {
n@159 374 event.srcElement.parentElement.appendChild(commentBox());
n@159 375 };
n@159 376 node.appendChild(newCommentButton);
n@159 377
n@159 378 var removeButton = document.createElement("button");
n@159 379 removeButton.textContent = "Remove Audio Holder";
n@159 380 removeButton.onclick = removeNode;
n@159 381 node.appendChild(removeButton);
n@159 382 return node;
n@159 383 }
n@159 384
n@159 385 function audioElementNode() {
n@159 386 var parentStructure = event.srcElement.parentElement.childNodes;
n@159 387 var audioElemCounts = 0;
n@159 388 for (var i=0; i<parentStructure.length; i++) {
n@159 389 if (parentStructure[i].getAttribute('name') == "audio-element")
n@159 390 {audioElemCounts++;}
n@159 391 }
n@159 392 var node = document.createElement('div');
n@159 393 node.setAttribute('class','head');
n@159 394 node.setAttribute('name','audio-element');
n@159 395 var nodeTitle = document.createElement('span');
n@159 396 nodeTitle.textContent = 'Audio Element '+(audioElemCounts+1);
n@159 397
n@159 398 var attributes = document.createElement("div");
n@159 399 attributes.setAttribute('class','attrib');
n@162 400 var id = attributePair("ID:","text",true);
n@159 401 id[1].value = audioElemCounts;
n@162 402 var url = attributePair("URL:","text",true);
n@159 403 id.forEach(function(item){attributes.appendChild(item);},false);
n@159 404 url.forEach(function(item){attributes.appendChild(item);},false);
n@159 405
n@159 406 node.appendChild(nodeTitle);
n@159 407 node.appendChild(attributes);
n@159 408
n@159 409 var removeButton = document.createElement("button");
n@159 410 removeButton.textContent = "Remove Audio Element";
n@159 411 removeButton.onclick = removeNode;
n@159 412 node.appendChild(removeButton);
n@159 413 return node;
n@159 414 }
n@159 415
n@159 416 function commentBox() {
n@159 417 var node = document.createElement('div');
n@159 418 node.setAttribute('class','head');
n@159 419 node.setAttribute('name','comment-question');
n@159 420 var nodeTitle = document.createElement('h4');
n@159 421 nodeTitle.textContent = "Comment Box";
n@159 422
n@159 423 var attributes = document.createElement('div');
n@159 424 attributes.setAttribute('class','attrib');
n@162 425 var id = attributePair("ID:",'text',true);
n@162 426 var question = attributePair("Question:",'text',true);
n@159 427 id.forEach(function(item){attributes.appendChild(item);},false);
n@159 428 question.forEach(function(item){attributes.appendChild(item);},false);
n@159 429
n@159 430 var removeButton = document.createElement("button");
n@159 431 removeButton.textContent = "Remove Comment Box";
n@159 432 removeButton.onclick = removeNode;
n@159 433
n@159 434 node.appendChild(nodeTitle);
n@159 435 node.appendChild(attributes);
n@159 436 node.appendChild(removeButton);
n@159 437 return node;
n@157 438 }
n@168 439
n@168 440
n@168 441 function handleDragOver(e) {
n@168 442 e.stopPropagation();
n@168 443 e.preventDefault();
n@168 444 }
n@168 445 function handleDragEnter(e) {
n@168 446 e.stopPropagation();
n@168 447 e.preventDefault();
n@168 448 this.style.backgroundColor = '#AAFFAA';
n@168 449 }
n@168 450 function handleDragLeave(e) {
n@168 451 e.stopPropagation();
n@168 452 e.preventDefault();
n@168 453 this.style.backgroundColor = "#FFFFFF";
n@168 454 }
n@168 455 function handleDrop(e) {
n@168 456 e.stopPropagation();
n@168 457 e.preventDefault();
n@168 458
n@168 459 var file = e.dataTransfer.files[0];
n@168 460
n@168 461 // Uses HTML5 FileAPI - https://w3c.github.io/FileAPI/#filereader-interface
n@168 462 var reader = new FileReader();
n@168 463 reader.readAsText(file);
n@168 464 var parse = new DOMParser();
n@168 465 var xml = parse.parseFromString(reader.result,'text/xml');
n@168 466 importXML(xml);
n@168 467 }
n@168 468
n@168 469 function importXML(xml) {
n@168 470 console.log(xml);
n@168 471 }
n@157 472 </script>
n@157 473 <style>
n@157 474 div {
n@157 475 padding: 2px;
n@157 476 margin-top: 2px;
n@157 477 margin-bottom: 2px;
n@157 478 }
n@157 479 div.head{
n@157 480 margin-left: 10px;
n@157 481 border: black;
n@157 482 border-width: 2px;
n@157 483 border-style: solid;
n@157 484 }
n@157 485 div.attrib{
n@157 486 margin-left:25px;
n@157 487 border: black;
n@157 488 border-width: 2px;
n@157 489 border-style: dashed;
n@157 490 margin-bottom: 10px;
n@157 491 }
n@168 492 div#dragFile{
n@168 493 height:100px;
n@168 494 border-width: 2px;
n@168 495 border-style: dashed;
n@168 496 margin-bottom: 10px;
n@168 497 }
n@157 498 </style>
n@157 499
n@156 500 </head>
n@156 501
n@156 502 <body>
n@157 503 <h1>Create Test Setup XML</h1>
n@168 504 <div id="dragFile">
n@168 505 <span>Drag and Drop an XML specification file here to auto-load.</span>
n@168 506 </div>
n@162 507 <button id="validateXML" onclick="buttonClickedValidate();">Validate</button>
n@167 508 <button id="createXML" onclick="buttonClickedSubmit();" disabled>Submit</button>
n@162 509 <span id="errorMessage" visibility="hidden"></span>
n@157 510 <div id="topLevelBody" align="left">
n@156 511 <!-- Interface goes here -->
n@157 512 <div name='test-setup'>
n@157 513 <div id="setup" class="head">
n@157 514 <h2>Setup Tag</h2>
n@157 515 <div id="setup-attribs" class="attrib">
n@157 516 <span>Interface</span>
n@157 517 <select id="interface">
n@157 518 <option value='APE'>APE</option>
n@157 519 </select>
n@157 520 <span>Project Return</span>
n@162 521 <input type="text" id="projectReturn" mandatory="false">
n@157 522 <span>Randomise Test Page Order</span>
n@157 523 <input id="randomisePageOrder" type="checkbox" value="false">
n@157 524 <span>Collect Session Metrics</span>
n@157 525 <input id="collectMetrics" type="checkbox">
n@157 526 </div>
n@157 527 <div id="globalPreTest" class="head">
n@157 528 <h3>Pre Test</h3>
n@157 529 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Pre Test Question</button>
n@157 530 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Pre Test Statement</button>
n@157 531 </div>
n@157 532 <div id="globalPostTest" class="head">
n@157 533 <h3>Post Test</h3>
n@157 534 <button id="addPreTestQ" onclick="event.srcElement.parentElement.appendChild(questionNode());">Add Post Test Question</button>
n@157 535 <button id="addPreTestS" onclick="event.srcElement.parentElement.appendChild(statementNode());">Add Post Test Statement</button>
n@157 536 </div>
n@157 537 <div id="globalMetric" class="head">
n@157 538 <h3>Global Metrics</h3>
n@157 539 <div id="globalMetric-attrib" class="attrib">
n@157 540 <span>Test Timer</span>
n@157 541 <input type="checkbox" id="testTimer" />
n@157 542 <span>Element Playback Timer</span>
n@157 543 <input type="checkbox" id="elementTimer" />
n@157 544 <span>Element Initial Position</span>
n@157 545 <input type="checkbox" id="elementInitialPosition" />
n@157 546 <span>Element Tracker</span>
n@157 547 <input type="checkbox" id="elementTracker" />
n@157 548 <span>Element Flag Listened To</span>
n@163 549 <input type="checkbox" id="elementFlagListenedTo" />
n@157 550 <span>Element Flag Moved</span>
n@157 551 <input type="checkbox" id="elementFlagMoved" />
n@157 552 </div>
n@157 553 </div>
n@159 554 <button id="addAudioHolder" onclick="event.srcElement.parentElement.appendChild(audioHolderNode());">Add AudioHolder / Test Page</button>
n@157 555 </div>
n@157 556 </div>
n@156 557 </div>
n@156 558 </body>
n@156 559 </html>