Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions public/demo-form-elements/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,47 @@
}
]
},
"Auto advance": {
"type": "questionnaire",
"response": [
{
"id": "math-buttons",
"type": "buttons",
"prompt": "Complex calculation that use buttons with auto-advance.",
"secondaryText": "What does 53 + 98 equal?",
"infoText": "Choose the option that is correct.",
"options": [
{
"label": "162",
"value": "162"
},
{
"label": "149",
"value": "149"
},
{
"label": "151",
"value": "151"
},
{
"label": "137",
"value": "137"
}
],
"autoAdvanceToNextStep": true,
"autoAdvanceDelay": 5000,
"allowResponseChange": false
}
],
"correctAnswer": [
{
"id": "math-buttons",
"answer": "151"
}
],
"provideFeedback": true,
"trainingAttempts": 1
},
"Default Values": {
"type": "questionnaire",
"response": [
Expand Down Expand Up @@ -1422,6 +1463,7 @@
"Text Validation",
"Default Values",
"Custom Response",
"Auto advance",
"Randomizing Options",
"Randomizing Questions",
"Ranking Widgets",
Expand Down
11 changes: 7 additions & 4 deletions public/demo-html-input/assets/bar-chart-interaction.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</head>

<body>
<svg></svg>
<svg role="img" aria-label="Interactive bar chart"></svg>
</body>

<script>
Expand Down Expand Up @@ -68,9 +68,12 @@

// Post answer from the html to reVISit platform
.on('click', (e, d) => {
Revisit.postAnswers({
[taskID]: d,
});
// Trial parameters decide whether a click also requests submission.
Revisit.postAnswers(
{ [taskID]: d },
data.autoAdvanceToNextStep === true,
data.autoAdvanceDelay ?? 0
);
});

svg
Expand Down
3 changes: 3 additions & 0 deletions public/demo-html-input/assets/introduction.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
This is an example study to show how to embed HTML elements into the study page.
In this example, the HTML stimulus communicates with the reVISit study framework to save the clicked bar as the answer, which is also stored in the study provenance.

The first two trials let you select a bar and continue with Next. In the final trial, clicking any bar records its value and automatically continues after 300 milliseconds using `Revisit.postAnswers(answers, true, 300)`.
The trial's `parameters` enable this behavior, and `nextButtonHidden` hides Next.

## Relevant files:
* [The Config](https://github.com/revisit-studies/study/blob/main/public/demo-html-input/config.json)
* [bar-chart-interaction.html](https://github.com/revisit-studies/study/blob/main/public/demo-html-input/assets/bar-chart-interaction.html)
Expand Down
14 changes: 13 additions & 1 deletion public/demo-html-input/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,26 @@
0.3
]
}
},
"bar-chart-auto-advance": {
"baseComponent": "bar-chart",
"description": "A trial that automatically advances when a bar is clicked.",
"instruction": "Click a bar to automatically continue.",
"nextButtonHidden": true,
"parameters": {
"barData": [0.4, 0.8, 1.2, 0.6],
"autoAdvanceToNextStep": true,
"autoAdvanceDelay": 300
}
}
},
"sequence": {
"order": "fixed",
"components": [
"introduction",
"bar-chart-1",
"bar-chart-2"
"bar-chart-2",
"bar-chart-auto-advance"
]
}
}
5 changes: 5 additions & 0 deletions public/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"library-vlat",
"test-keymapping",
"test-audio",
"test-auto-advance",
"test-device-restriction",
"test-library",
"test-likert-matrix",
Expand Down Expand Up @@ -353,6 +354,10 @@
"path": "test-audio/config.json",
"test": true
},
"test-auto-advance": {
"path": "test-auto-advance/config.json",
"test": true
},
"test-device-restriction": {
"tab": "Tests",
"path": "test-device-restriction/config.json"
Expand Down
168 changes: 86 additions & 82 deletions public/revisitUtilities/revisit-communicate.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
(function () {
const PREFIX = "@REVISIT_COMMS";

const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);

// Templated websites are rendered from their compiled contents rather than from their URL,
// so they have no query string; reVISit injects the same values on window.__REVISIT_PARAMS__.
const injectedParams =
window.__REVISIT_PARAMS__ && typeof window.__REVISIT_PARAMS__ === "object"
? window.__REVISIT_PARAMS__
: {};

const id = urlParams.get("id") || injectedParams.id || null;

const sendMessage = (tag, message) => {
window.parent.postMessage(
{
error: false,
type: `${PREFIX}/${tag}`,
iframeId: id,
message,
},
"*"
);
};

let onDataReceiveCallback = null;
let onProvenanceReceiveCallback = null;
let onAnswerReceiveCallback = null;
(function () {
const PREFIX = "@REVISIT_COMMS";

const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);

// Templated websites are rendered from their compiled contents rather than from their URL,
// so they have no query string; reVISit injects the same values on window.__REVISIT_PARAMS__.
const injectedParams =
window.__REVISIT_PARAMS__ && typeof window.__REVISIT_PARAMS__ === "object"
? window.__REVISIT_PARAMS__
: {};

const id = urlParams.get("id") || injectedParams.id || null;

const sendMessage = (tag, message, options) => {
window.parent.postMessage(
{
error: false,
type: `${PREFIX}/${tag}`,
iframeId: id,
message,
...(options === undefined ? {} : { options }),
},
"*"
);
};

let onDataReceiveCallback = null;
let onProvenanceReceiveCallback = null;
let onAnswerReceiveCallback = null;
const managedTrrackSubscriptions = new Set();

const appendTraversalEvent = (previousProvenance, incomingProvenance, observedAt) => {
Expand Down Expand Up @@ -70,32 +71,35 @@
managedTrrackSubscriptions.forEach((unsubscribe) => unsubscribe());
managedTrrackSubscriptions.clear();
};

window.addEventListener('message', function (e) {
const data = e.data;
if (typeof data === 'object' && id === data.iframeId) {
if (data.type === `${PREFIX}/STUDY_DATA` && onDataReceiveCallback) {
onDataReceiveCallback(data.message);
}
if (data.type === `${PREFIX}/PROVENANCE` && onProvenanceReceiveCallback) {
onProvenanceReceiveCallback(data.message);
}
if (data.type === `${PREFIX}/ANSWERS` && onAnswerReceiveCallback) {
onAnswerReceiveCallback(data.message);
}
}
});

window.Revisit = {
postAnswers: (answers) => {
sendMessage("ANSWERS", answers);
},

window.addEventListener('message', function (e) {
const data = e.data;
if (typeof data === 'object' && id === data.iframeId) {
if (data.type === `${PREFIX}/STUDY_DATA` && onDataReceiveCallback) {
onDataReceiveCallback(data.message);
}
if (data.type === `${PREFIX}/PROVENANCE` && onProvenanceReceiveCallback) {
onProvenanceReceiveCallback(data.message);
}
if (data.type === `${PREFIX}/ANSWERS` && onAnswerReceiveCallback) {
onAnswerReceiveCallback(data.message);
}
}
});

window.Revisit = {
postAnswers: (answers, autoAdvanceToNextStep = false, autoAdvanceDelay = 0) => {
const options = autoAdvanceToNextStep === true
? { autoAdvanceToNextStep, autoAdvanceDelay }
: undefined;
sendMessage("ANSWERS", answers, options);
},
/**
* @deprecated Use Revisit.createTrrack so every traversal is reported automatically.
*/
postProvenance: (provenance) => {
sendMessage("PROVENANCE", provenance);
},
postProvenance: (provenance) => {
sendMessage("PROVENANCE", provenance);
},
createTrrack: ({ initializeTrrack, ...options }) => {
if (typeof initializeTrrack !== 'function') {
throw new TypeError('Revisit.createTrrack requires the Trrack initializeTrrack function.');
Expand All @@ -119,37 +123,37 @@

return trrack;
},
postEvent: (eventName, objectId) => {
sendMessage("EVENT", { eventName, objectId });
},
// Inform Revisit that the stimuli is ready in the iframe.
postReady: () => {
sendMessage("READY", {
documentHeight: document.documentElement.scrollHeight,
documentWidth: document.documentElement.scrollWidth,
});
},
onDataReceive: (fn) => {
onDataReceiveCallback = fn;
},
onProvenanceReceive: (fn) => {
onProvenanceReceiveCallback = fn;
},
onAnswersReceive: (fn) => {
onAnswerReceiveCallback = fn;
},
};
window.addEventListener(
'load',
function () {
sendMessage('WINDOW_READY');
},
false
);
postEvent: (eventName, objectId) => {
sendMessage("EVENT", { eventName, objectId });
},
// Inform Revisit that the stimuli is ready in the iframe.
postReady: () => {
sendMessage("READY", {
documentHeight: document.documentElement.scrollHeight,
documentWidth: document.documentElement.scrollWidth,
});
},
onDataReceive: (fn) => {
onDataReceiveCallback = fn;
},
onProvenanceReceive: (fn) => {
onProvenanceReceiveCallback = fn;
},
onAnswersReceive: (fn) => {
onAnswerReceiveCallback = fn;
},
};

window.addEventListener(
'load',
function () {
sendMessage('WINDOW_READY');
},
false
);
window.addEventListener('pagehide', (event) => {
if (!event.persisted) {
disposeManagedTrracks();
}
});
})();
})();
Loading
Loading