Validation Fields

This commit is contained in:
Naitik
2023-10-02 19:27:37 +05:30
parent bcaf2337c4
commit cf75b4850d
3 changed files with 78 additions and 13 deletions

View File

@@ -1,7 +1,15 @@
import React, { useState, useEffect } from "react";
import { TSurveyOpenTextQuestion, TSurveyWithAnalytics } from "@formbricks/types/v1/surveys";
import { Button, Input, Label } from "@formbricks/ui";
import { Button, Input, Label, Select } from "@formbricks/ui";
import { TrashIcon, PlusIcon } from "@heroicons/react/24/solid";
import { useState } from "react";
const questionTypes = [
{ value: "text", label: "Text" },
{ value: "email", label: "Email" },
{ value: "url", label: "URL" },
{ value: "number", label: "Number" },
{ value: "phone", label: "Phone Number" },
];
interface OpenQuestionFormProps {
localSurvey: TSurveyWithAnalytics;
@@ -13,6 +21,7 @@ interface OpenQuestionFormProps {
}
export default function OpenQuestionForm({
localSurvey,
question,
questionIdx,
updateQuestion,
@@ -20,6 +29,15 @@ export default function OpenQuestionForm({
}: OpenQuestionFormProps): JSX.Element {
const [showSubheader, setShowSubheader] = useState(!!question.subheader);
// Function to handle question type change
const handleQuestionTypeChange = (value: string) => {
updateQuestion(questionIdx, { inputType: value });
};
useEffect(() => {
handleQuestionTypeChange("text");
}, []);
return (
<form>
<div className="mt-3">
@@ -76,6 +94,23 @@ export default function OpenQuestionForm({
/>
</div>
</div>
{/* Add a dropdown to select the question type */}
<div className="mt-3">
<Label htmlFor="questionType">Question Type</Label>
<div className="flex items-center">
{questionTypes.map((type) => (
<div
key={type.value}
onClick={() => handleQuestionTypeChange(type.value)}
className={`mr-2 cursor-pointer rounded-md border p-2 ${
question.inputType === type.value ? "bg-slate-50" : "bg-white"
}`}>
{type.label}
</div>
))}
</div>
</div>
</form>
);
}

View File

@@ -4,6 +4,25 @@ import { BackButton } from "./BackButton";
import Headline from "./Headline";
import Subheader from "./Subheader";
import SubmitButton from "./SubmitButton";
import { useState } from "preact/hooks";
function validateInput(value: string, questionType: string): boolean {
switch (questionType) {
case "email":
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(value);
case "url":
const urlPattern = /^(ftp|http|https):\/\/[^ "]+$/;
return urlPattern.test(value);
case "number":
return !isNaN(parseFloat(value));
case "phone":
const phonePattern = /^\+?[0-9]+$/;
return phonePattern.test(value);
default:
return true;
}
}
interface OpenTextQuestionProps {
question: TSurveyOpenTextQuestion;
@@ -28,11 +47,21 @@ export default function OpenTextQuestion({
brandColor,
autoFocus = true,
}: OpenTextQuestionProps) {
const [isValid, setIsValid] = useState(true);
const handleInputChange = (inputValue: string) => {
const isValidInput = validateInput(inputValue, question.inputType);
setIsValid(isValidInput);
onChange({ [question.id]: inputValue });
};
return (
<form
onSubmit={(e) => {
e.preventDefault();
onSubmit({ [question.id]: value });
if (isValid) {
onSubmit({ [question.id]: value, inputType: question.inputType });
}
}}
className="w-full">
<Headline headline={question.headline} questionId={question.id} required={question.required} />
@@ -44,12 +73,12 @@ export default function OpenTextQuestion({
id={question.id}
placeholder={question.placeholder}
required={question.required}
value={value}
onInput={(e) => {
onChange({ [question.id]: e.currentTarget.value });
}}
value={value as string}
onInput={(e) => handleInputChange(e.currentTarget.value)}
autoFocus={autoFocus}
className="block w-full rounded-md border border-slate-100 bg-slate-50 p-2 shadow-sm focus:border-slate-500 focus:outline-none focus:ring-0 sm:text-sm"
className={`block w-full rounded-md border ${
isValid ? "border-slate-100" : "border-red-500"
} bg-slate-50 p-2 shadow-sm focus:border-slate-500 focus:outline-none focus:ring-0 sm:text-sm`}
/>
) : (
<textarea
@@ -58,12 +87,12 @@ export default function OpenTextQuestion({
id={question.id}
placeholder={question.placeholder}
required={question.required}
value={value}
onInput={(e) => {
onChange({ [question.id]: e.currentTarget.value });
}}
value={value as string}
onInput={(e) => handleInputChange(e.currentTarget.value)}
autoFocus={autoFocus}
className="block w-full rounded-md border border-slate-100 bg-slate-50 p-2 shadow-sm focus:border-slate-500 focus:ring-0 sm:text-sm"></textarea>
className={`block w-full rounded-md border ${
isValid ? "border-slate-100" : "border-red-500" // Apply red border for invalid input
} bg-slate-50 p-2 shadow-sm focus:border-slate-500 focus:outline-none focus:ring-0 sm:text-sm`}></textarea>
)}
</div>
<div className="mt-4 flex w-full justify-between">

View File

@@ -145,6 +145,7 @@ export const ZSurveyOpenTextQuestion = ZSurveyQuestionBase.extend({
placeholder: z.string().optional(),
longAnswer: z.boolean().optional(),
logic: z.array(ZSurveyOpenTextLogic).optional(),
inputType: z.enum(["text", "email", "url", "number", "phone"]).optional().default("text"),
});
export type TSurveyOpenTextQuestion = z.infer<typeof ZSurveyOpenTextQuestion>;