Skip to content

Commit

Permalink
Merge pull request #211 from ukhsa-collaboration/feat/OOC-4405
Browse files Browse the repository at this point in the history
OOC-4405: Update landing page (part 2) content (CQC checkbox)
  • Loading branch information
masuk-kazi98 authored Jul 15, 2024
2 parents c8d2618 + 4339735 commit 5d0ba6b
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 27 deletions.
9 changes: 9 additions & 0 deletions model/src/components/component-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ export const ComponentTypes: ComponentDef[] = [
options: {},
schema: {},
},
{
name: "TextFieldCustom",
type: "TextFieldCustom",
title: "Text field",
subType: "field",
hint: "",
options: {},
schema: {},
},
{
name: "MultilineTextField",
type: "MultilineTextField",
Expand Down
14 changes: 14 additions & 0 deletions model/src/components/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum ComponentTypeEnum {
TextField = "TextField",
TextFieldCustom = "TextFieldCustom",
MultilineTextField = "MultilineTextField",
YesNoField = "YesNoField",
DateField = "DateField",
Expand Down Expand Up @@ -28,6 +29,7 @@ export enum ComponentTypeEnum {

export type ComponentType =
| "TextField"
| "TextFieldCustom"
| "MultilineTextField"
| "YesNoField"
| "DateField"
Expand Down Expand Up @@ -178,6 +180,17 @@ export interface TextFieldComponent extends TextFieldBase {
};
}

export interface TextFieldCustomComponent extends TextFieldBase {
type: "TextFieldCustom";
options: TextFieldBase["options"] & {
customValidationMessage?: string;
conditionalTextField?: {
dependsOn: string;
};
fieldName?: string;
};
}

export interface EmailAddressFieldComponent extends TextFieldBase {
type: "EmailAddressField";
}
Expand Down Expand Up @@ -345,6 +358,7 @@ export type ComponentDef =
| SelectFieldComponent
| TelephoneNumberFieldComponent
| TextFieldComponent
| TextFieldCustomComponent
| TimeFieldComponent
| UkAddressFieldComponent
| YesNoFieldComponent
Expand Down
87 changes: 62 additions & 25 deletions runner/src/server/forms/ReportAnOutbreak.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,61 +33,87 @@
"title": "Acute Respiratory Infections (ARI) - COVID-19, Flu or unknown infection in Adult Social Care settings",
"components": [
{
"name": "S0Q4",
"name": "S0Q1",
"options": {
"customValidationMessages": {
"string.regex.base": "Enter a full UK postcode",
"string.pattern.base": "Enter a full UK postcode"
}
},
"type": "TextField",
"title": "Please enter your setting Postcode",
"title": "Your setting postcode",
"schema": {
"regex": "^([a-zA-Z]{1,2}[0-9][a-zA-Z0-9]? *[0-9][a-zA-Z]{2}|[a-zA-Z]{1,2}[0-9][a-zA-Z0-9]?)$"
},
"nameHasError": false,
"hint": "Please provide the postcode of the specific setting affected (i.e. not the overarching management company if applicable). If there is no one specific setting affected e.g. Domiciliary or Home Care, then please provide the postcode of the care provider company"
"hint": "Give the postcode of your care setting, not the management company. If you provide domiciliary or home care, enter the postcode of the care provider company."
},
{
"name": "S0Q2",
"options": {
"required":false,
"customValidationMessages": {
"string.regex.base": "Enter a valid CQC Location ID",
"string.pattern.base": "Enter a valid CQC Location ID"
}
},
"type": "TextField",
"title": "Please enter your CQC Location ID",
"options": { "required": true },
"type": "SelectField",
"title": "Your local UKHSA health protection team",
"list": "sjgMDe",
"nameHasError": false,
"schema": { "regex": "^(1-\\d{1,9}|[a-zA-Z0-9]{3,7})$" }
"schema": {},
"values": {
"type": "listRef"
}
},
{
"name": "VMOkqi",
"name": "cstZQG",
"options": {},
"type": "Para",
"content": "If you don’t know your CQC Location ID then please visit <a id=\"cqc number\" target=\"_blank\" href=\"https://www.cqc.org.uk/about-us/transparency/using-cqc-data\">Using CQC data - Care Quality Commission</a> and scroll about half way down the page to <b style=\"color:#1d70b8\">CQC care directory - csv</b>. You will find your CQC Location ID in this look up table.\n</br></br>",
"content": "<a target=\"_blank\" id=\"local-health-protection-team\" href=\"https://www.gov.uk/health-protection-team\">Use your postcode to find your local health protection team (opens in a new tab)</a>",
"schema": {}
},
{
"name": "S0Q3",
"options": { "required": true },
"type": "SelectField",
"title": "Please enter your local HPT here",
"list": "sjgMDe",
"options": {
"required": false,
"optionalText": false,
"conditionalTextField": {
"dependsOn": "S0Q4"
},
"fieldName": "cqc"
},
"type": "TextFieldCustom",
"title": "Your Care Quality Commission (CQC) location ID",
"nameHasError": false,
"schema": {},
"values": {
"type": "listRef"
"schema": {
"regex": "^(1-\\d{1,9}|[a-zA-Z0-9]{3,7})$"
}
},
{
"name": "rIpMWq",
"options": {},
"type": "Para",
"content": "<div class='govuk-checkboxes__divider'>or</div>"
},
{
"name": "S0Q4",
"options": {
"hideTitle": true,
"required": false
},
"hint": "Please make sure you've selected the correct local health protection team (HPT) to guarantee you receive the appropriate support"
"type": "CheckboxesField",
"title": "My setting is not registered with the CQC",
"nameHasError": false,
"list": "OZDejp",
"schema": {}
},
{
"name": "cstZQG",
"name": "VMOkqi",
"options": {},
"type": "Para",
"content": "Click on the link to <a target=\"_blank\" id=\"local-health-protection-team\" href=\"https://www.gov.uk/health-protection-team\">Find your local health protection team in England - GOV.UK</a> (www.gov.uk) [Enter the postcode of your care setting]",
"content": "<a id=\"cqc number\" target=\"_blank\" href=\"https://www.cqc.org.uk/about-us/transparency/using-cqc-data\">Find your CQC location ID in the care directory on the CQC website (opens in a new tab).</a>",
"schema": {}
},
{
"name": "rIpMWr",
"options": {},
"type": "Html",
"content": "<script>\ndocument.addEventListener('DOMContentLoaded', function() {\nconst cqcIdText = document.getElementById('S0Q3');\nconst cqcIdCheckbox = document.getElementById('S0Q4');\nfunction updateTextFieldRequiredState() {\nconst isChecked = cqcIdCheckbox.checked;\ncqcIdText.required = !isChecked;\n}\nfunction clearCheckbox() {\ncqcIdCheckbox.checked = false;\n}\ncqcIdCheckbox.addEventListener('change', function() {\nif (cqcIdCheckbox.checked) {\ncqcIdText.value = '';\n}\nupdateTextFieldRequiredState();\n});\ncqcIdText.addEventListener('input', function() {\nif (cqcIdText.value !== '') {\nclearCheckbox();\n}\nupdateTextFieldRequiredState()\n});\n});\n</script>"
}
],
"next": [
Expand Down Expand Up @@ -1661,6 +1687,17 @@
}
],
"lists": [
{
"title": "care-setting-not-registered",
"name": "OZDejp",
"type": "string",
"items": [
{
"text": "My setting is not registered with the CQC",
"value": "My setting is not registered with the CQC"
}
]
},
{
"title": "social-care-provider-type",
"name": "MpSRIP",
Expand Down
11 changes: 10 additions & 1 deletion runner/src/server/plugins/engine/components/CheckboxesField.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { FormData, FormSubmissionErrors, FormSubmissionState } from "../types";
import {
FormData,
FormPayload,
FormSubmissionErrors,
FormSubmissionState,
} from "../types";
import { ListComponentsDef } from "@xgovformbuilder/model";
import { FormModel } from "../models";
import joi from "joi";
Expand Down Expand Up @@ -31,6 +36,10 @@ export class CheckboxesField extends SelectionControlField {
this.stateSchema = schema;
}

getStateValueFromValidForm(payload: FormPayload) {
return payload[this.name];
}

getDisplayStringFromState(state: FormSubmissionState) {
return state?.[this.name]
?.map(
Expand Down
65 changes: 65 additions & 0 deletions runner/src/server/plugins/engine/components/TextFieldCustom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { TextFieldCustomComponent } from "@xgovformbuilder/model";
import { FormModel } from "../models";
import joi from "joi";
import * as helpers from "./helpers";
import { FormPayload } from "../types";
import { FormComponent } from "./FormComponent";

// Currently only used on the ReportAnOutbreak/uon-and-cqc page to handle textfield and checkbox comparisons
export class TextFieldCustom extends FormComponent {
formSchema;
stateSchema;
pattern;
dependentField;
fieldName;

constructor(def: TextFieldCustomComponent, model: FormModel) {
super(def, model);

const { options, schema = {} } = def;
this.options = options;
this.schema = schema;

if (schema.regex) {
this.pattern = new RegExp(schema.regex);
}

if (options.conditionalTextField) {
this.dependentField = options.conditionalTextField.dependsOn;
}

if (options.fieldName) {
this.fieldName = options.fieldName;
}

let componentSchema = joi.optional().allow(null).allow("");

this.formSchema = componentSchema;
}

getStateSchemaKeys() {
let schema: any = this.formSchema;

if (this.fieldName) {
schema = schema.custom(
helpers.customTextCheckboxValidator(this.fieldName)
);
}

this.schema = schema;
return { [this.name]: schema };
}

getStateValueFromValidForm(payload: FormPayload) {
const currentFieldValue = payload[this.name].trim();
const dependentFieldValue = payload[this.dependentField];

if (currentFieldValue === "" && !dependentFieldValue) {
return false;
}
if (currentFieldValue && !this.pattern.test(currentFieldValue)) {
return "regex";
}
return currentFieldValue;
}
}
16 changes: 16 additions & 0 deletions runner/src/server/plugins/engine/components/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,22 @@ export function getCustomDateValidator(
};
}

export function customTextCheckboxValidator(fieldName: string) {
return (value: string, helpers: joi.CustomHelpers) => {
if (!value) {
return helpers.error(`string.${fieldName}`, {
label: helpers.state.key,
});
}
if (value == "regex") {
return helpers.error(`string.${fieldName}.regex`, {
label: helpers.state.key,
});
}
return value;
};
}

export function internationalPhoneValidator(
value: string,
_helpers: joi.CustomHelpers
Expand Down
1 change: 1 addition & 0 deletions runner/src/server/plugins/engine/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export { RadiosField } from "./RadiosField";
export { SelectField } from "./SelectField";
export { TelephoneNumberField } from "./TelephoneNumberField";
export { TextField } from "./TextField";
export { TextFieldCustom } from "./TextFieldCustom";
export { TimeField } from "./TimeField";
export { UkAddressField } from "./UkAddressField";
export { WebsiteField } from "./WebsiteField";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const messageTemplate = {
dateDayYear: "{{#label}} must include a day and a year",
dateDayMonth: "{{#label}} must include a day and a month",
dateYear4digits: "The year must include 4 numbers",
cqc:
"Enter your CQC location ID or select 'My setting is not registered with the CQC'",
cqcRegex: "Enter a valid CQC Location ID",
};

export const messages: ValidationOptions["messages"] = {
Expand All @@ -39,6 +42,8 @@ export const messages: ValidationOptions["messages"] = {
"string.email": messageTemplate.email,
"string.regex.base": messageTemplate.format,
"string.maxWords": messageTemplate.maxWords,
"string.cqc": messageTemplate.cqc,
"string.cqc.regex": messageTemplate.cqcRegex,

"date.base": messageTemplate.date,
"date.empty": messageTemplate.required,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% from "input/macro.njk" import govukInput %}

{% macro TextFieldCustom(component) %}
{{ govukInput(component.model) }}
{% endmacro %}
2 changes: 1 addition & 1 deletion runner/src/server/plugins/engine/views/partials/form.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% from "button/macro.njk" import govukButton %}
{% from "summary-list/macro.njk" import govukSummaryList -%}

<form method="post" enctype="multipart/form-data" autocomplete="on">
<form method="post" enctype="multipart/form-data" autocomplete="on" novalidate>
<input type="hidden" name="crumb" value="{{crumb}}"/>
{{ componentList(components) }}

Expand Down

0 comments on commit 5d0ba6b

Please sign in to comment.