From 997523c3381ea6eac17e034cbe46b9414e6073f4 Mon Sep 17 00:00:00 2001 From: "EP\\qang2" Date: Tue, 17 Oct 2023 16:16:59 +0700 Subject: [PATCH] Add NumberElementBlock Fixes: AFORM-3557 --- .../src/components/RenderElement.tsx | 7 ++- .../elements/NumberElementBlock.tsx | 56 +++++++++++++++++++ .../src/components/elements/index.ts | 3 +- .../forms-sdk/src/helpers/index.ts | 2 + .../forms-sdk/src/helpers/urlHelper.ts | 34 +++++++++++ src/@optimizely/forms-sdk/src/index.ts | 3 +- .../forms-sdk/src/models/elements/Number.ts | 8 +-- 7 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 src/@optimizely/forms-react/src/components/elements/NumberElementBlock.tsx create mode 100644 src/@optimizely/forms-sdk/src/helpers/index.ts create mode 100644 src/@optimizely/forms-sdk/src/helpers/urlHelper.ts diff --git a/src/@optimizely/forms-react/src/components/RenderElement.tsx b/src/@optimizely/forms-react/src/components/RenderElement.tsx index 547f9ac..aa474a1 100644 --- a/src/@optimizely/forms-react/src/components/RenderElement.tsx +++ b/src/@optimizely/forms-react/src/components/RenderElement.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import { TextareaElementBlock, TextboxElementBlock } from './elements'; +import { TextareaElementBlock, TextboxElementBlock, NumberElementBlock } from './elements'; import { FormElementBase } from '@optimizely/forms-sdk'; const components: Record = { - TextboxElementBlock, - TextareaElementBlock + TextboxElementBlock, + TextareaElementBlock, + NumberElementBlock }; export interface ElementProps { diff --git a/src/@optimizely/forms-react/src/components/elements/NumberElementBlock.tsx b/src/@optimizely/forms-react/src/components/elements/NumberElementBlock.tsx new file mode 100644 index 0000000..fc448c4 --- /dev/null +++ b/src/@optimizely/forms-react/src/components/elements/NumberElementBlock.tsx @@ -0,0 +1,56 @@ +import { Number, extractParams } from "@optimizely/forms-sdk" +import { ValidatorType } from "../../models"; +import React, { useRef } from "react"; +import ElementWrapper from "../ElementWrapper"; +import { useElement } from "../../hooks/useElement"; + +export interface NumberElementBlockProps { + element: Number +} + +export const NumberElementBlock = (props: NumberElementBlockProps) => { + const { element } = props; + const { elementContext, handleChange, handleBlur, checkVisible } = useElement(element); + const { relativePath, language } = extractParams(window.location.pathname) + + const isRequire = element.properties.validators?.some(v => v.type === ValidatorType.RequiredValidator); + const validatorClasses = element.properties.validators?.reduce((acc, obj) => `${acc} ${obj.model.validationCssClass}`, ""); + + const extraAttr = useRef({}); + if (isRequire) { + extraAttr.current = { ...extraAttr.current, required: isRequire, "aria-required": isRequire }; + } + + return ( + +
+ + + {element.properties.validators?.map((v) => { + let validationResult = elementContext.validationResults; + let valid = !validationResult || validationResult?.length == 0 || validationResult[0].valid; + return ( + + {v.model.message} + + ); + })} +
+
+ ); +} \ No newline at end of file diff --git a/src/@optimizely/forms-react/src/components/elements/index.ts b/src/@optimizely/forms-react/src/components/elements/index.ts index f926c68..466e528 100644 --- a/src/@optimizely/forms-react/src/components/elements/index.ts +++ b/src/@optimizely/forms-react/src/components/elements/index.ts @@ -1,2 +1,3 @@ export * from "./TextboxElementBlock"; -export * from "./TextareaElementBlock"; \ No newline at end of file +export * from "./TextareaElementBlock"; +export * from "./NumberElementBlock"; \ No newline at end of file diff --git a/src/@optimizely/forms-sdk/src/helpers/index.ts b/src/@optimizely/forms-sdk/src/helpers/index.ts new file mode 100644 index 0000000..801c5d5 --- /dev/null +++ b/src/@optimizely/forms-sdk/src/helpers/index.ts @@ -0,0 +1,2 @@ +export * from "./generateId" +export * from "./urlHelper" \ No newline at end of file diff --git a/src/@optimizely/forms-sdk/src/helpers/urlHelper.ts b/src/@optimizely/forms-sdk/src/helpers/urlHelper.ts new file mode 100644 index 0000000..da58047 --- /dev/null +++ b/src/@optimizely/forms-sdk/src/helpers/urlHelper.ts @@ -0,0 +1,34 @@ +export const extractParams = (urlPath: string) => { + let relativePath = (urlPath.length > 1 && urlPath !== "/search") ? urlPath : '/en' + let contentId + let workId = undefined + + const epiContentPrefix = "/EPiServer/CMS/Content/"; + if (relativePath.startsWith(epiContentPrefix)) { + relativePath = relativePath.substring(epiContentPrefix.length - 1); + } + + if (relativePath.endsWith('/')) { + relativePath = relativePath.slice(0, -1) + } + + if (relativePath.includes(",")) { + const [, , idString] = relativePath.split(",") + if (idString.includes("_")) { + [contentId, workId] = idString.split("_").map(x => parseInt(x)); + + } else { + contentId = parseInt(idString) + } + relativePath = relativePath.substring(0, relativePath.indexOf(',')); + } + + if (relativePath.endsWith('/')) { + relativePath = relativePath.slice(0, -1) + } + + const urlSegments = relativePath.split('/') + const language = urlSegments.length ? urlSegments.find(s => s.length === 2) : "en" + + return { relativePath, locales: language, language, contentId, workId } +} \ No newline at end of file diff --git a/src/@optimizely/forms-sdk/src/index.ts b/src/@optimizely/forms-sdk/src/index.ts index 3623b35..75372c8 100644 --- a/src/@optimizely/forms-sdk/src/index.ts +++ b/src/@optimizely/forms-sdk/src/index.ts @@ -1,3 +1,4 @@ export * from "./form-loader"; export * from "./models"; -export * from "./form-step"; \ No newline at end of file +export * from "./form-step"; +export * from "./helpers" \ No newline at end of file diff --git a/src/@optimizely/forms-sdk/src/models/elements/Number.ts b/src/@optimizely/forms-sdk/src/models/elements/Number.ts index 430552a..e0a54df 100644 --- a/src/@optimizely/forms-sdk/src/models/elements/Number.ts +++ b/src/@optimizely/forms-sdk/src/models/elements/Number.ts @@ -1,11 +1,11 @@ -import { InputElementBaseProperties, FormElementBase } from "./base"; +import { InputElementBaseProperties, InputElementBase } from "./base"; /** * Only allows users to input numeric values */ -export interface Number extends FormElementBase { - +export interface Number extends InputElementBase { + properties: NumberProperties } export interface NumberProperties extends InputElementBaseProperties { - + autoComplete: string; } \ No newline at end of file