diff --git a/public/js/src/module/controller-webform-oc.js b/public/js/src/module/controller-webform-oc.js
index 47c66f72..0aca15d3 100644
--- a/public/js/src/module/controller-webform-oc.js
+++ b/public/js/src/module/controller-webform-oc.js
@@ -170,62 +170,6 @@ function init(formEl, data, loadErrors = []) {
// set form eventhandlers before initializing form
_setFormEventHandlers();
- const handleGoToIrrelevant = (e) => {
- let err;
- // In OC hidden go_to fields should show loadError
- // regular questions:
- if (!e.target.classList.contains('or-appearance-dn')) {
- err = t('alert.goto.irrelevant');
- }
- // Discrepancy notes
- else {
- err = `${t('alert.goto.irrelevant')} `;
- const goToErrorLink = settings.goToErrorUrl
- ? `${settings.goToErrorUrl}`
- : '';
- if (settings.interface === 'queries') {
- err += goToErrorLink
- ? t('alert.goto.msg2', {
- miniform: goToErrorLink,
- // switch off escaping
- interpolation: {
- escapeValue: false,
- },
- })
- : t('alert.goto.msg1');
- }
- }
- // For goto targets that are discrepancy notes and are relevant but their linked question is not,
- // the goto-irrelevant event will be fired twice. We can safely remove the eventlistener after the first
- // event is caught (for all cases).
- form.view.html.removeEventListener(
- events.GoToIrrelevant().type,
- handleGoToIrrelevant
- );
- goToHiddenErrors = [err];
- loadErrors.push(err);
- };
-
- const handleGoToInvisible = () => {
- form.view.html.removeEventListener(
- events.GoToInvisible().type,
- handleGoToInvisible
- );
- if (settings.interface === 'sdv') {
- loadErrors.push(`${t('alert.goto.invisible')} `);
- }
- };
-
- // listen for "goto-irrelevant" event and add error
- form.view.html.addEventListener(
- events.GoToIrrelevant().type,
- handleGoToIrrelevant
- );
- form.view.html.addEventListener(
- events.GoToInvisible().type,
- handleGoToInvisible
- );
-
loadErrors = loadErrors.concat(form.init());
// Determine whether UI language should be attempted to be switched.
@@ -293,6 +237,61 @@ function init(formEl, data, loadErrors = []) {
// this is placed in between form.init() and form.goTo().
$('.main-loader').remove();
if (settings.goTo && location.hash) {
+ const handleGoToIrrelevant = (e) => {
+ let err;
+ // In OC hidden go_to fields should show loadError
+ // regular questions:
+ if (!e.target.classList.contains('or-appearance-dn')) {
+ err = t('alert.goto.irrelevant');
+ }
+ // Discrepancy notes
+ else {
+ err = `${t('alert.goto.irrelevant')} `;
+ const goToErrorLink = settings.goToErrorUrl
+ ? `${settings.goToErrorUrl}`
+ : '';
+ if (settings.interface === 'queries') {
+ err += goToErrorLink
+ ? t('alert.goto.msg2', {
+ miniform: goToErrorLink,
+ // switch off escaping
+ interpolation: {
+ escapeValue: false,
+ },
+ })
+ : t('alert.goto.msg1');
+ }
+ }
+ // For goto targets that are discrepancy notes and are relevant but their linked question is not,
+ // the goto-irrelevant event will be fired twice. We can safely remove the eventlistener after the first
+ // event is caught (for all cases).
+ form.view.html.removeEventListener(
+ events.GoToIrrelevant().type,
+ handleGoToIrrelevant
+ );
+ goToHiddenErrors = [err];
+ loadErrors.push(err);
+ };
+
+ const handleGoToInvisible = () => {
+ form.view.html.removeEventListener(
+ events.GoToInvisible().type,
+ handleGoToInvisible
+ );
+ if (settings.interface === 'sdv') {
+ loadErrors.push(`${t('alert.goto.invisible')} `);
+ }
+ };
+
+ form.view.html.addEventListener(
+ events.GoToIrrelevant().type,
+ handleGoToIrrelevant
+ );
+ form.view.html.addEventListener(
+ events.GoToInvisible().type,
+ handleGoToInvisible
+ );
+
// form.goTo returns an array of 1 error if it has error. We're using our special
// knowledge of Enketo Core to replace this error
goToErrors = form.goTo(
diff --git a/public/js/src/module/page.js b/public/js/src/module/page.js
index 59ea69bf..46a2ceeb 100644
--- a/public/js/src/module/page.js
+++ b/public/js/src/module/page.js
@@ -6,6 +6,31 @@ import reasons from './reasons';
import settings from './settings';
import gui from './gui';
+// Contains fix for https://github.com/OpenClinica/enketo-express-oc/issues/720
+// This function should be removed once PR https://github.com/enketo/enketo/pull/1286 is merged
+// and published
+pageModule.flipToPageContaining = function ($e) {
+ const e = $e[0];
+ const closestPage = e.closest('[role="page"]');
+
+ if (closestPage) {
+ this._flipTo(closestPage);
+ } else if (e.closest('.question')) {
+ // If $e is a comment question, and it is not inside a group, there will be no closestPage.
+ const referer = e.querySelector('[data-for]');
+ const ancestor = e.closest('.or-repeat, form.or');
+ if (referer && ancestor) {
+ const linkedQuestion = ancestor.querySelector(
+ `[name="${referer.dataset.for}"]`
+ );
+ if (linkedQuestion) {
+ this._flipTo(linkedQuestion.closest('[role="page"]'));
+ }
+ }
+ }
+ this.$toc.parent().find('.pages-toc__overlay').click();
+};
+
/*
* The only thing we want to change in this function for OC,
* is to NOT flip to the next page when a repeat is the same as a page and
diff --git a/widget/discrepancy-note/dn-widget.js b/widget/discrepancy-note/dn-widget.js
index 9854020a..fd9d2d31 100644
--- a/widget/discrepancy-note/dn-widget.js
+++ b/widget/discrepancy-note/dn-widget.js
@@ -1585,6 +1585,20 @@ class Comment extends Widget {
}
}
+ _encodeHtml(str) {
+ return str.replace(
+ /[&<>'"]/g,
+ (tag) =>
+ ({
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ "'": ''',
+ '"': '"',
+ }[tag])
+ );
+ }
+
_getHistoryRow(item, options = {}) {
const types = {
comment: '',
@@ -1638,7 +1652,9 @@ class Comment extends Widget {
types[item.type]
}
- ${msg}
+ ${this._encodeHtml(
+ msg
+ )}
${
assignee