-
Remco Tukker authoredRemco Tukker authored
SurveyComponent.tsx 4.15 KiB
import React, { useCallback } from "react";
import { Question, FunctionFactory } from "survey-core";
import { Survey } from "survey-react-ui";
import { VerificationStatus } from './Schema';
function customDescriptionCallback(_, options) {
// get the customDescription for matrix rows and set it in the title
// attribute so that it shows up as a hover popup
if (options.column['indexValue'] == 0 && 'item' in options.row) {
const item = options.row['item'] as object;
if (item['customDescription'] !== undefined) {
options.htmlElement.parentElement?.children[0].setAttribute("title", item['customDescription']);
}
}
}
function validateWebsiteUrl(params) {
const value = params[0];
if (value === undefined || value == null || value == '') {
return true;
}
try {
const url = new URL(value);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (err) {
return false;
}
}
function hideCheckboxLabels(_, options) {
if (options.question.hideCheckboxLabels) {
const classes = options.cssClasses;
classes.root += " hidden-checkbox-labels";
}
}
function setVerifyButton(question: Question, state: VerificationStatus, surveyModel) {
surveyModel.verificationStatus.set(question.name, state);
const btn = document.createElement("button");
btn.type = "button";
btn.className = "sv-action-bar-item verification";
btn.innerHTML = state;
if (state == VerificationStatus.Unverified) {
btn.innerHTML = "No change from previous year";
btn.className += " verification-required";
btn.onclick = function () {
if (surveyModel.mode == "display") {
return;
}
question.validate();
setVerifyButton(question, VerificationStatus.Verified, surveyModel);
}
} else {
btn.innerHTML = "Answer updated"
btn.className += " verification-ok";
}
const selector = '[data-name="' + question.name + '"]';
const header = document.querySelector(selector)?.querySelector('h5');
const old = header?.querySelector(".verification");
if (old) {
old.replaceWith(btn);
} else {
header?.appendChild(btn);
}
}
function SurveyComponent({ surveyModel }) {
const alwaysSetVerify = useCallback((_, options) => {
const status = surveyModel.verificationStatus.get(options.question.name);
if (status) {
setVerifyButton(options.question, status, surveyModel);
}
}, [surveyModel])
const updateFromUnverified = useCallback((_, options) => {
const currentStatus = surveyModel.verificationStatus.get(options.question.name);
if (currentStatus == VerificationStatus.Unverified) {
setVerifyButton(options.question, VerificationStatus.Edited, surveyModel);
}
}, [surveyModel])
if (!FunctionFactory.Instance.hasFunction("validateWebsiteUrl")) {
FunctionFactory.Instance.register("validateWebsiteUrl", validateWebsiteUrl);
}
if (!surveyModel.css.question.title.includes("sv-header-flex")) {
surveyModel.css.question.title = "sv-title sv-question__title sv-header-flex";
surveyModel.css.question.titleOnError = "sv-question__title--error sv-error-color-fix";
}
if (!surveyModel.onAfterRenderQuestion.hasFunc(alwaysSetVerify)) {
surveyModel.onAfterRenderQuestion.add(alwaysSetVerify);
}
if (!surveyModel.onValueChanged.hasFunc(updateFromUnverified)) {
surveyModel.onValueChanged.add(updateFromUnverified);
}
if (!surveyModel.onUpdateQuestionCssClasses.hasFunc(hideCheckboxLabels)) {
surveyModel.onUpdateQuestionCssClasses.add(hideCheckboxLabels);
}
if (!surveyModel.onMatrixAfterCellRender.hasFunc(customDescriptionCallback)) {
// NB I would have preferred using onAfterRenderQuestion, but unfortunately that is
// not always triggered on re-renders (specifically when extra column become visble or invisible)
surveyModel.onMatrixAfterCellRender.add(customDescriptionCallback);
}
return <Survey model={surveyModel} />
}
export default SurveyComponent;