initial dynamic forms

This commit is contained in:
2021-07-08 16:22:12 +01:00
parent b335c11e6b
commit 878940a6d5
25 changed files with 709 additions and 60 deletions
+14 -11
View File
@@ -2,6 +2,7 @@ import Link from "next/link";
import jsonpath from "jsonpath";
import _ from "lodash";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
const Breadcrumbs = (props) => {
const {
@@ -14,11 +15,13 @@ const Breadcrumbs = (props) => {
applicant_ref,
} = props;
const router = useRouter();
const { course, section } = router.query;
const { appealType, section } = router.query;
let { t } = useTranslation();
function Breadcrumb() {
if (slug) {
var coursePageURL = course + "/" + slug;
var coursePageURL = appealType + "/" + slug;
if (_.isEmpty(courseContent)) {
return null;
} else {
@@ -43,37 +46,37 @@ const Breadcrumbs = (props) => {
return (
<nav
aria-label={"Breadcrumb for " + _.startCase(_.toLower(course))}
aria-label={"Breadcrumb for " + _.startCase(_.toLower(appealType))}
role="navigation"
data-module="track-click"
>
<div className="govuk-breadcrumbs ">
<ol className="govuk-breadcrumbs__list">
<li className="govuk-breadcrumbs__list-item">
<Link href="http://www.gov.uk">
<a className="govuk-breadcrumbs__link">GOV.UK</a>
<Link href="http://www.gov.wales">
<a className="govuk-breadcrumbs__link">GOV.WALES</a>
</Link>
</li>
<li className="govuk-breadcrumbs__list-item">
<Link href="/">
<a className="govuk-breadcrumbs__link">
Appeals Casework Portal
{t("common:service-name")}
</a>
</Link>
</li>
<li className="govuk-breadcrumbs__list-item">
<Link href="/portal">
<Link href="/myportal">
<a className="govuk-breadcrumbs__link">
Find the right training
{t("myportal:page-title")}
</a>
</Link>
</li>
{!_.isEmpty(course) ? (
{!_.isEmpty(appealType) ? (
<li className="govuk-breadcrumbs__list-item">
<Link
href={
"/" +
course +
appealType +
"?id=" +
applicant_id +
"&refno=" +
@@ -83,7 +86,7 @@ const Breadcrumbs = (props) => {
}
>
<a className="govuk-breadcrumbs__link">
{_.startCase(_.toLower(course))}
{_.startCase(_.toLower(appealType))}
</a>
</Link>
</li>
+252
View File
@@ -0,0 +1,252 @@
export function Textfield(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<label className="govuk-label govuk-label--m " htmlFor="event-name">
{props.label}
</label>
<input
className="govuk-input govuk-input--width-20"
id="event-name"
name={props.name}
type="text"
/>
</div>
);
}
export function MultiLinefield(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<h1 className="govuk-label-wrapper">
<label
className="govuk-label govuk-label--l"
htmlFor="more-detail"
>
{props.label}
</label>
</h1>
<div id="more-detail-hint" className="govuk-hint">
Do not include personal or financial information, like your
National Insurance number or credit card details.
</div>
<textarea
className="govuk-textarea"
id="more-detail"
name="more-detail"
rows="5"
aria-describedby="more-detail-hint"
></textarea>
</div>
);
}
export function DateField(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<fieldset
className="govuk-fieldset"
role="group"
aria-describedby="dob-hint"
>
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s">
<label className="govuk-fieldset__heading">
{props.label}
</label>
</legend>
<div id="dob-hint" className="govuk-hint">
For example, 31 3 1980
</div>
<div className="govuk-date-input" id="dob">
<div className="govuk-date-input__item">
<div className="govuk-form-group">
<label
className="govuk-label govuk-date-input__label"
htmlFor="dob-day"
>
Day
</label>
<input
className="govuk-input govuk-date-input__input govuk-input--width-2"
id="dob-day"
name="dob-day"
type="text"
autoComplete="bday-day"
pattern="[0-9]*"
inputMode="numeric"
/>
</div>
</div>
<div className="govuk-date-input__item">
<div className="govuk-form-group">
<label
className="govuk-label govuk-date-input__label"
htmlFor="dob-month"
>
Month
</label>
<input
className="govuk-input govuk-date-input__input govuk-input--width-2"
id="dob-month"
name="dob-month"
type="text"
autoComplete="bday-month"
pattern="[0-9]*"
inputMode="numeric"
/>
</div>
</div>
<div className="govuk-date-input__item">
<div className="govuk-form-group">
<label
className="govuk-label govuk-date-input__label"
htmlFor="dob-year"
>
Year
</label>
<input
className="govuk-input govuk-date-input__input govuk-input--width-4"
id="dob-year"
name="dob-year"
type="text"
autoComplete="bday-year"
pattern="[0-9]*"
inputMode="numeric"
/>
</div>
</div>
</div>
</fieldset>
</div>
);
}
export function YesNofield(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<fieldset
className="govuk-fieldset"
aria-describedby="changed-name-hint"
>
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s">
<label className="govuk-fieldset__heading">
{props.label}
</label>
</legend>
<div id="changed-name-hint" className="govuk-hint">
This includes changing your last name or spelling your name
differently.
</div>
<div className="govuk-radios govuk-radios--inline">
<div className="govuk-radios__item">
<input
className="govuk-radios__input"
id="changed-name"
name="changed-name"
type="radio"
value="yes"
/>
<label
className="govuk-label govuk-radios__label"
htmlFor="changed-name"
>
Yes
</label>
</div>
<div className="govuk-radios__item">
<input
className="govuk-radios__input"
id="changed-name-2"
name="changed-name"
type="radio"
value="no"
/>
<label
className="govuk-label govuk-radios__label"
htmlFor="changed-name-2"
>
No
</label>
</div>
</div>
</fieldset>
</div>
);
}
export function PickList(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<label className="govuk-label govuk-body-m" htmlFor="sort">
{props.label}
</label>
<select className="govuk-select" id="sort" name="sort">
<option value="published">Recently published</option>
<option value="updated" defaultValue>
Recently updated
</option>
<option value="views">Most views</option>
<option value="comments">Most comments</option>
</select>
</div>
);
}
export function NumericField(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<label
className="govuk-label govuk-label--m"
htmlFor="account-number"
>
{props.label}
</label>
<div id="account-number-hint" className="govuk-hint">
Must be between 6 and 8 digits long
</div>
<input
className="govuk-input govuk-input--width-10"
id="account-number"
name="account-number"
type="text"
spellCheck="false"
aria-describedby="account-number-hint"
pattern="[0-9]*"
inputMode="numeric"
/>
</div>
);
}
export function ReadOnlyfield(props) {
const { name, label } = props;
return (
<div className="govuk-form-group">
<label className="govuk-label govuk-label--m " htmlFor="event-name">
{props.label}
</label>
<input
className="govuk-input govuk-input--width-20"
id="event-name"
name={props.name}
type="text"
disabled
/>
</div>
);
}
+1 -1
View File
@@ -15,7 +15,7 @@ export default function MakeAdvertApplication() {
discontinuance notice.
</p>
<div className="appealCTA">
<Link href="/newappeal">
<Link href="/newappeal/selectappeal">
<a className="govuk-button">
An advert application/Discontinuance Notice (DN)
</a>
+95
View File
@@ -0,0 +1,95 @@
import Link from "next/link";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import xpath from "xpath";
import {
Textfield,
DateField,
YesNofield,
PickList,
MultiLinefield,
NumericField,
ReadOnlyfield,
} from "../elements";
export default function BuildField(props) {
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
const { fieldType, label, datafieldname } = props;
const parser = new DOMParser();
const whichFieldType = (classid) => {
switch (classid) {
case "{270BD3DB-D9AF-4782-9025-509E298DEC0A}":
return (
<ReadOnlyfield
name={props.datafieldname}
label={props.label}
/>
);
break;
case "{3EF39988-22BB-4f0b-BBBE-64B5A3748AEE}":
return (
<PickList
name={props.datafieldname}
label={props.label}
datafieldname={props.datafieldname}
/>
);
break;
case "{67FAC785-CD58-4f9f-ABB3-4B7DDC6ED5ED}":
return (
<YesNofield
name={props.datafieldname}
label={props.label}
/>
);
break;
case "{ 4273EDBD-AC1D-40d3-9FB2-095C621B552D}":
return (
<Textfield name={props.datafieldname} label={props.label} />
);
break;
case "{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}":
return (
<DateField name={props.datafieldname} label={props.label} />
);
break;
case "{E0DECE4B-6FC8-4a8f-A065-082708572369}":
return (
<MultiLinefield
name={props.datafieldname}
label={props.label}
/>
);
break;
case "{C6D124CA-7EDA-4a60-AEA9-7FB8D318B68F}":
return (
<NumericField
name={props.datafieldname}
label={props.label}
/>
);
break;
case "{C3EFE0C3-0EC6-42be-8349-CBD9079DFD8E}":
return " decimal";
break;
default:
return (
<Textfield name={props.datafieldname} label={props.label} />
);
}
};
return (
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
{whichFieldType(props.fieldType)}
</div>
</div>
);
}
+39
View File
@@ -0,0 +1,39 @@
import Link from "next/link";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import xpath from "xpath";
import BuildField from "./buildfield";
export default function BuildRow(props) {
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
const { rowXML, whichSection, sectionCount } = props;
const parser = new DOMParser();
return (
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
{Object.keys(rowXML).map((key, index) => {
var doc = parser.parseFromString(
rowXML[key].outerHTML,
"text/xml"
);
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
return (
<BuildField
fieldType={fieldtype[0].value}
label={rows[0].value}
datafieldname={datafieldname[0].value}
/>
);
})}
</div>
</div>
);
}
+52
View File
@@ -0,0 +1,52 @@
import Link from "next/link";
import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation";
import xpath from "xpath";
import BuildRow from "./buildrow";
export default function BuildSection(props) {
let { t } = useTranslation();
const router = useRouter();
const { locale } = router;
const { formXML, whichSection, sectionCount } = props;
const parser = new DOMParser();
var doc = parser.parseFromString(props.formXML, "text/xml");
var titles = xpath.select(
"//form/tabs/tab[" +
(parseInt(whichSection) + 1) +
" ]/labels/label/@description",
doc
);
var rowXML = xpath.select(
"/form/tabs/tab[" +
(parseInt(whichSection) + 1) +
"]/columns//sections/section/rows/row",
doc
);
return (
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<h2>
{props.whichSection} - {titles[0].value}{" "}
</h2>
<BuildRow
rowXML={rowXML}
whichSection={props.whichSection}
sectionCount={props.sectionCount}
/>
<button
type="submit"
role="button"
draggable="false"
class="govuk-button"
data-module="govuk-button"
>
Continue
</button>
</div>
</div>
);
}
+1 -1
View File
@@ -14,7 +14,7 @@ export default function MakeEnforcementNotice() {
Including an enforcement listed building notice.
</p>
<div className="appealCTA">
<Link href="/newappeal">
<Link href="/newappeal/selectappeal">
<a className="govuk-button">A enforcement notice</a>
</Link>
</div>
+1 -1
View File
@@ -15,7 +15,7 @@ export default function MakeLDC() {
lawful use or development.
</p>
<div className="appealCTA">
<Link href="/newappeal">
<Link href="/newappeal/selectappeal">
<a className="govuk-button">
A Lawful Development Certificate (LDC)
</a>
+1 -1
View File
@@ -16,7 +16,7 @@ export default function MakeNewAppeal() {
building (LB) applications.
</p>
<div className="appealCTA">
<Link href="./newappeal/appealtypes/planningappeals78">
<Link href="./newappeal/selectappeal">
<a className="govuk-button">A planning application</a>
</Link>
</div>