annotate test_create/test_create.html @ 1017:e103d40537b5

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