changeset 2853:f75db4482006

More test-creator work. Finished global surveys
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 26 Apr 2017 16:38:34 +0100
parents 8372c220db7a
children aed359997687
files test_create.html test_create/style.css test_create/test_core.js xml/test-schema.xsd
diffstat 4 files changed, 288 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/test_create.html	Wed Apr 26 15:17:48 2017 +0100
+++ b/test_create.html	Wed Apr 26 16:38:34 2017 +0100
@@ -71,6 +71,225 @@
                     <input type="checkbox" ng-model="specification.playOne" />
                 </div>
             </div>
+            <div class="node">
+                <h2>Test Completed Message</h2>
+                <textarea ng-model="specification.exitText"></textarea>
+            </div>
+            <div id="metricsNode" class="node">
+                <h3>Session Metrics</h3>
+                <div class="attributes">
+                    <div class="attribute">
+                        <span>Collect Total Test Time: </span>
+                        <input type="checkbox" value="testTimer" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Listen Time: </span>
+                        <input type="checkbox" value="elementTimer" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Initial Position: </span>
+                        <input type="checkbox" value="elementInitialPosition" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Position over Time: </span>
+                        <input type="checkbox" value="elementTracker" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Listened To Flag: </span>
+                        <input type="checkbox" value="elementFlagListenedTo" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Moved Flag: </span>
+                        <input type="checkbox" value="elementFlagMoved" ng-click="enableMetric($event)" />
+                    </div>
+                    <div class="attribute">
+                        <span>Collect Fragment Listened Flag: </span>
+                        <input type="checkbox" value="elementListenTracker" ng-click="enableMetric($event)" />
+                    </div>
+                </div>
+            </div>
+            <div id="globalpresurvey" class="node">
+                <h2>Pre Test Survey</h2>
+                <div class="node" ng-repeat="opt in specification.preTest.options" ng-controller="surveyOption">
+                    <h3>Survey Entry</h3>
+                    <div class="attributes">
+                        <div class="attribute">
+                            <span>Survey Type: </span>
+                            <select ng-model="opt.type">
+                                <option value="question">Question</option>
+                                <option value="radio">Radio</option>
+                                <option value="checkbox">Checkbox</option>
+                                <option value="statement">Statement</option>
+                                <option value="number">Number</option>
+                                <option value="slider">Slider</option>
+                                <option value="video">Video</option>
+                                <option value="youtube">YouTube</option>
+                            </select>
+                        </div>
+                        <div class="attribute">
+                            <span>Unique Survey Entry ID:</span>
+                            <input type="text" ng-model="opt.id" />
+                        </div>
+                        <div class="attribute">
+                            <span>Entry Name:</span>
+                            <input type="text" ng-model="opt.name" />
+                        </div>
+                        <div class="attribute" ng-show="['question', 'checkbox', 'radio', 'number'].indexOf(opt.type) >= 0">
+                            <span>Mandatory:</span>
+                            <input type="checkbox" ng-model="opt.mandatory" />
+                        </div>
+                        <div class="attribute">
+                            <span>Minimum Wait Time (s):</span>
+                            <input type="number" ng-model="opt.minWait" min="0" />
+                        </div>
+                        <div class="attribute" ng-show="opt.type == 'question'">
+                            <span>Box Size:</span>
+                            <select ng-model="opt.boxsize">
+                                <option value="small">Small</option>
+                                <option value="normal">Normal</option>
+                                <option value="large">Large</option>
+                                <option value="huge">Huge</option>
+                            </select>
+                        </div>
+                        <div class="attribute" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                            <span>Minimum Selected:</span>
+                            <input type="number" ng-model="opt.min" min="0" />
+                        </div>
+                        <div class="attribute" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                            <span>Maximum Selected:</span>
+                            <input type="number" ng-model="opt.max" max="{{opt.options.length}}" />
+                        </div>
+                        <div class="attribute" ng-show="['slider', 'number'].indexOf(opt.type) >= 0">
+                            <span>Minimum Value:</span>
+                            <input type="number" ng-model="opt.min" />
+                        </div>
+                        <div class="attribute" ng-show="['slider', 'number'].indexOf(opt.type) >= 0">
+                            <span>Maximum Value:</span>
+                            <input type="number" ng-model="opt.max" />
+                        </div>
+                        <div class="attribute" ng-show="['video', 'youtube'].indexOf(opt.type) >= 0">
+                            <span>Video URL:</span>
+                            <input type="text" ng-model="opt.url" />
+                        </div>
+                    </div>
+                    <div class="node">
+                        <h4>Statement</h4>
+                        <textarea ng-model="opt.statement"></textarea>
+                    </div>
+                    <div class="node" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                        <h4>Options</h4>
+                        <div>
+                            <button type="button" class="btn btn-default" ng-click="addOption();">Add Option</button>
+                        </div>
+                        <div class="node" ng-repeat="option in opt.options">
+                            <div class="attributes">
+                                <div class="attribute">
+                                    <button type="button" class="btn btn-default" ng-click="removeOption(option);">Remove</button>
+                                </div>
+                                <div class="attribute">
+                                    <span>Name: </span>
+                                    <input type="text" ng-model="option.name" />
+                                </div>
+                                <div class="attribute">
+                                    <span>Displayed Text: </span>
+                                    <input type="text" ng-model="option.text" />
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div id="globalpostsurvey" class="node">
+                <h2>Post Test Survey</h2>
+                <div class="node" ng-repeat="opt in specification.postTest.options" ng-controller="surveyOption">
+                    <h3>Survey Entry</h3>
+                    <div class="attributes">
+                        <div class="attribute">
+                            <span>Survey Type: </span>
+                            <select ng-model="opt.type">
+                                <option value="question">Question</option>
+                                <option value="radio">Radio</option>
+                                <option value="checkbox">Checkbox</option>
+                                <option value="statement">Statement</option>
+                                <option value="number">Number</option>
+                                <option value="slider">Slider</option>
+                                <option value="video">Video</option>
+                                <option value="youtube">YouTube</option>
+                            </select>
+                        </div>
+                        <div class="attribute">
+                            <span>Unique Survey Entry ID:</span>
+                            <input type="text" ng-model="opt.id" />
+                        </div>
+                        <div class="attribute">
+                            <span>Entry Name:</span>
+                            <input type="text" ng-model="opt.name" />
+                        </div>
+                        <div class="attribute" ng-show="['question', 'checkbox', 'radio', 'number'].indexOf(opt.type) >= 0">
+                            <span>Mandatory:</span>
+                            <input type="checkbox" ng-model="opt.mandatory" />
+                        </div>
+                        <div class="attribute">
+                            <span>Minimum Wait Time (s):</span>
+                            <input type="number" ng-model="opt.minWait" min="0" />
+                        </div>
+                        <div class="attribute" ng-show="opt.type == 'question'">
+                            <span>Box Size:</span>
+                            <select ng-model="opt.boxsize">
+                                <option value="small">Small</option>
+                                <option value="normal">Normal</option>
+                                <option value="large">Large</option>
+                                <option value="huge">Huge</option>
+                            </select>
+                        </div>
+                        <div class="attribute" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                            <span>Minimum Selected:</span>
+                            <input type="number" ng-model="opt.min" min="0" />
+                        </div>
+                        <div class="attribute" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                            <span>Maximum Selected:</span>
+                            <input type="number" ng-model="opt.max" max="{{opt.options.length}}" />
+                        </div>
+                        <div class="attribute" ng-show="['slider', 'number'].indexOf(opt.type) >= 0">
+                            <span>Minimum Value:</span>
+                            <input type="number" ng-model="opt.min" />
+                        </div>
+                        <div class="attribute" ng-show="['slider', 'number'].indexOf(opt.type) >= 0">
+                            <span>Maximum Value:</span>
+                            <input type="number" ng-model="opt.max" />
+                        </div>
+                        <div class="attribute" ng-show="['video', 'youtube'].indexOf(opt.type) >= 0">
+                            <span>Video URL:</span>
+                            <input type="text" ng-model="opt.url" />
+                        </div>
+                    </div>
+                    <div class="node">
+                        <h4>Statement</h4>
+                        <textarea ng-model="opt.statement"></textarea>
+                    </div>
+                    <div class="node" ng-show="['checkbox', 'radio'].indexOf(opt.type) >= 0">
+                        <h4>Options</h4>
+                        <div>
+                            <button type="button" class="btn btn-default" ng-click="addOption();">Add Option</button>
+                        </div>
+                        <div class="node" ng-repeat="option in opt.options">
+                            <div class="attributes">
+                                <div class="attribute">
+                                    <button type="button" class="btn btn-default" ng-click="removeOption(option);">Remove</button>
+                                </div>
+                                <div class="attribute">
+                                    <span>Name: </span>
+                                    <input type="text" ng-model="option.name" />
+                                </div>
+                                <div class="attribute">
+                                    <span>Displayed Text: </span>
+                                    <input type="text" ng-model="option.text" />
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
         <div id="popupHolder" ng-show="popupVisible">
             <div ng-controller="introduction" class="popup" ng-show="popupVisible">
--- a/test_create/style.css	Wed Apr 26 15:17:48 2017 +0100
+++ b/test_create/style.css	Wed Apr 26 16:38:34 2017 +0100
@@ -64,10 +64,21 @@
     font-style: italic;
 }
 .node {
-    padding: 0px 20px;
+    padding: 10px 20px;
     border: 2px solid black;
     margin: 20px;
     border-radius: 20px;
+    background-color: inherit;
+}
+.node > textarea {
+    width: 80%;
+}
+.node > h1,
+h2,
+h3,
+h4,
+h5 {
+    text-align: center;
 }
 .attribute {
     display: inline-block;
@@ -76,3 +87,9 @@
     border-right: 1px solid grey;
     padding: 5px 5px;
 }
+#setupNode {
+    background-color: rgba(255, 10, 10, 0.25);
+}
+#pageNode {
+    background-color: rgba(10, 255, 10, 0.25);
+}
--- a/test_create/test_core.js	Wed Apr 26 15:17:48 2017 +0100
+++ b/test_create/test_core.js	Wed Apr 26 16:38:34 2017 +0100
@@ -111,7 +111,56 @@
     }
     $s.schema = undefined;
     $s.attributes = [];
-    $s.model = specification;
 
     $s.$watch("globalSchema", initialise);
+    $s.$watch("specification.metrics.enabled.length", function () {
+        var metricsNode = document.getElementById("metricsNode");
+        if (!$s.specification.metrics) {
+            return;
+        }
+        metricsNode.querySelectorAll("input").forEach(function (DOM) {
+            DOM.checked = false;
+        });
+        $s.specification.metrics.enabled.forEach(function (metric) {
+            var DOM = metricsNode.querySelector("[value=" + metric + "]");
+            if (DOM) {
+                DOM.checked = true;
+            }
+        });
+    })
+
+    $s.enableMetric = function ($event) {
+        var metric = $event.currentTarget.value;
+        var index = specification.metrics.enabled.findIndex(function (a) {
+            return a == metric;
+        });
+        if ($event.currentTarget.checked) {
+            if (index == -1) {
+                specification.metrics.enabled.push(metric);
+            }
+        } else {
+            if (index >= 0) {
+                specification.metrics.enabled.splice(index, 1);
+            }
+        }
+    }
 }]);
+
+AngularInterface.controller("surveyOption", ['$scope', '$element', '$window', function ($s, $e, $w) {
+
+    $s.removeOption = function (option) {
+        var index = $s.opt.options.findIndex(function (a) {
+            return a == option;
+        });
+        if (index === -1) {
+            throw ("Invalid option");
+        }
+        $s.opt.options.splice(index, 1);
+    };
+    $s.addOption = function () {
+        $s.opt.options.push({
+            name: "",
+            text: ""
+        });
+    }
+}]);
--- a/xml/test-schema.xsd	Wed Apr 26 15:17:48 2017 +0100
+++ b/xml/test-schema.xsd	Wed Apr 26 16:38:34 2017 +0100
@@ -410,6 +410,7 @@
                 <xs:sequence>
                     <xs:element ref="statement" minOccurs="1" maxOccurs="1" />
                 </xs:sequence>
+                <xs:attribute ref="minWait" />
                 <xs:attribute ref="id" use="required" />
             </xs:complexType>
         </xs:element>