mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-26 01:22:31 +02:00
feat: implement input box validation functionality
This commit is contained in:
@@ -84,6 +84,7 @@ function PdfRequestFiles() {
|
||||
const [isExpired, setIsExpired] = useState(false);
|
||||
const [alreadySign, setAlreadySign] = useState(false);
|
||||
const [containerWH, setContainerWH] = useState({});
|
||||
const [validateAlert, setValidateAlert] = useState(false);
|
||||
const divRef = useRef(null);
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const rowLevel =
|
||||
@@ -482,7 +483,6 @@ function PdfRequestFiles() {
|
||||
});
|
||||
};
|
||||
|
||||
console.log("signerpos", signerPos);
|
||||
//function for save button to save signature or image url
|
||||
const saveSign = (isDefaultSign, width, height) => {
|
||||
const isTypeText = width && height ? true : false;
|
||||
@@ -891,6 +891,7 @@ function PdfRequestFiles() {
|
||||
setSignerPos={setSignerPos}
|
||||
containerWH={containerWH}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -1048,6 +1049,36 @@ function PdfRequestFiles() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ModalUi
|
||||
headerColor={"#dc3545"}
|
||||
isOpen={validateAlert}
|
||||
title={"Validation alert"}
|
||||
handleClose={() => {
|
||||
setValidateAlert(false);
|
||||
}}
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<p>Please input a properly validated input value.</p>
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
onClick={() => setValidateAlert(false)}
|
||||
type="button"
|
||||
className="finishBtn cancelBtn"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
</DndProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ function Placeholder(props) {
|
||||
const [saveDateFormat, setSaveDateFormat] = useState("");
|
||||
const dateFormatArr = [
|
||||
"L",
|
||||
"DD/MM/YYYY",
|
||||
// "DD/MM/YYYY",
|
||||
"YYYY-MM-DD",
|
||||
"MM.DD.YYYY",
|
||||
"MM-DD-YYYY",
|
||||
@@ -34,7 +34,7 @@ function Placeholder(props) {
|
||||
case "LL":
|
||||
return "MMMM dd, yyyy";
|
||||
case "DD MMM, YYYY":
|
||||
return "DD MMM, YYYY";
|
||||
return "dd MMM, YYYY";
|
||||
case "YYYY-MM-DD":
|
||||
return "YYYY-MM-dd";
|
||||
case "MM-DD-YYYY":
|
||||
@@ -63,18 +63,20 @@ function Placeholder(props) {
|
||||
setDateFormat(updateDate);
|
||||
};
|
||||
useEffect(() => {
|
||||
const date = new Date();
|
||||
const milliseconds = date.getTime();
|
||||
const newDate = moment(milliseconds).format("MM/DD/YYYY");
|
||||
const dateObj = {
|
||||
date: newDate,
|
||||
format: "MM/dd/YYYY"
|
||||
};
|
||||
setSelectDate(dateObj);
|
||||
if (props.isPlaceholder || props.isSignYourself) {
|
||||
const date = new Date();
|
||||
const milliseconds = date.getTime();
|
||||
const newDate = moment(milliseconds).format("MM/DD/YYYY");
|
||||
const dateObj = {
|
||||
date: newDate,
|
||||
format: "MM/dd/YYYY"
|
||||
};
|
||||
setSelectDate(dateObj);
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (selectDate) {
|
||||
changeDateFormat();
|
||||
if (props.isPlaceholder || props.isSignYourself) {
|
||||
selectDate && changeDateFormat();
|
||||
}
|
||||
}, [selectDate]);
|
||||
//handle to close drop down menu onclick screen
|
||||
@@ -163,25 +165,54 @@ function Placeholder(props) {
|
||||
<>
|
||||
{props.isPlaceholder && (
|
||||
<>
|
||||
{props.pos.type === "checkbox" && (
|
||||
{(props.pos.type === "checkbox" ||
|
||||
props.pos.type === "text" ||
|
||||
props.pos.type === "email" ||
|
||||
props.pos.type === "name" ||
|
||||
props.pos.type === "company" ||
|
||||
props.pos.type === "job title") && (
|
||||
<i
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
props.setIsCheckboxRequired(true);
|
||||
if (props.pos.type === "checkbox") {
|
||||
props.setIsCheckboxRequired(true);
|
||||
} else {
|
||||
props.setIsValidate(true);
|
||||
}
|
||||
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
onTouchEnd={(e) => {
|
||||
e.stopPropagation();
|
||||
props.setIsCheckboxRequired(true);
|
||||
if (props.pos.type === "checkbox") {
|
||||
props.setIsCheckboxRequired(true);
|
||||
} else {
|
||||
props.setIsValidate(true);
|
||||
}
|
||||
|
||||
props.setSignKey(props.pos.key);
|
||||
props.setUniqueId(props.data.Id);
|
||||
}}
|
||||
class="fa-solid fa-gear settingIcon"
|
||||
style={{
|
||||
color: "#188ae2",
|
||||
right: "23px",
|
||||
top: "-35px"
|
||||
right:
|
||||
props.pos.type === "text" ||
|
||||
props.pos.type === "email" ||
|
||||
props.pos.type === "name" ||
|
||||
props.pos.type === "company" ||
|
||||
props.pos.type === "job title"
|
||||
? "49px"
|
||||
: "17px",
|
||||
top:
|
||||
props.pos.type === "text" ||
|
||||
props.pos.type === "email" ||
|
||||
props.pos.type === "name" ||
|
||||
props.pos.type === "company" ||
|
||||
props.pos.type === "job title"
|
||||
? "-20px"
|
||||
: "-35px"
|
||||
}}
|
||||
></i>
|
||||
)}
|
||||
@@ -500,6 +531,7 @@ function Placeholder(props) {
|
||||
selectDate={selectDate}
|
||||
setSaveDateFormat={setSaveDateFormat}
|
||||
saveDateFormat={saveDateFormat}
|
||||
setValidateAlert={props.setValidateAlert}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@@ -525,6 +557,7 @@ function Placeholder(props) {
|
||||
selectDate={selectDate}
|
||||
setSaveDateFormat={setSaveDateFormat}
|
||||
saveDateFormat={saveDateFormat}
|
||||
setValidateAlert={props.setValidateAlert}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, forwardRef, useMemo } from "react";
|
||||
import React, { useEffect, useState, forwardRef, useMemo, useRef } from "react";
|
||||
|
||||
import { onChangeInput } from "../../utils/Utils";
|
||||
import DatePicker from "react-datepicker";
|
||||
@@ -6,17 +6,71 @@ import "react-datepicker/dist/react-datepicker.css";
|
||||
import "../../css/signature.css";
|
||||
|
||||
function PlaceholderType(props) {
|
||||
const type = props.pos.type;
|
||||
const [selectOption, setSelectOption] = useState("");
|
||||
const [startDate, setStartDate] = useState(new Date());
|
||||
const [validatePlaceholder, setValidatePlaceholder] = useState("");
|
||||
const inputRef = useRef(null);
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const memoizedCount = useMemo(
|
||||
() => props.saveDateFormat,
|
||||
[props.saveDateFormat]
|
||||
);
|
||||
const type = props.pos.type;
|
||||
|
||||
const validateExpression = (regexValidation) => {
|
||||
let isValidate = regexValidation.test(inputValue);
|
||||
if (!isValidate) {
|
||||
props.setValidateAlert(true);
|
||||
inputRef.current.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputBlur = () => {
|
||||
props.setDraggingEnabled(true);
|
||||
const validateType = props.pos?.validation;
|
||||
let regexValidation;
|
||||
if (props.pos?.validation) {
|
||||
switch (validateType) {
|
||||
case "email":
|
||||
regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
case "number":
|
||||
regexValidation = /^\d+$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
case "text":
|
||||
regexValidation = /^[a-zA-Z\s]+$/;
|
||||
validateExpression(regexValidation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function checkRegularExpress(validateType) {
|
||||
switch (validateType) {
|
||||
case "email":
|
||||
setValidatePlaceholder("demo@gmail.com");
|
||||
break;
|
||||
case "number":
|
||||
setValidatePlaceholder("12345");
|
||||
break;
|
||||
case "text":
|
||||
setValidatePlaceholder("enter text");
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (props.pos.validation) {
|
||||
checkRegularExpress(props.pos.validation);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.selectDate) {
|
||||
const updateDate = new Date(props.selectDate?.date);
|
||||
setStartDate(updateDate);
|
||||
}
|
||||
|
||||
onChangeInput(
|
||||
props.saveDateFormat,
|
||||
props.pos.key,
|
||||
@@ -25,7 +79,11 @@ function PlaceholderType(props) {
|
||||
props.setXyPostion,
|
||||
props.data && props.data.signerObjId,
|
||||
false,
|
||||
props.selectDate?.format ? props.selectDate.format : "MM/dd/YYYY"
|
||||
props.selectDate?.format
|
||||
? props.selectDate.format
|
||||
: props.pos?.dateFormat
|
||||
? props.pos?.dateFormat
|
||||
: "MM/dd/YYYY"
|
||||
);
|
||||
}, [memoizedCount]);
|
||||
|
||||
@@ -148,6 +206,8 @@ function PlaceholderType(props) {
|
||||
return (
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
ref={inputRef}
|
||||
placeholder={validatePlaceholder}
|
||||
type="text"
|
||||
tabIndex="0"
|
||||
disabled={
|
||||
@@ -156,7 +216,8 @@ function PlaceholderType(props) {
|
||||
: props.isPlaceholder
|
||||
}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) =>
|
||||
onChange={(e) => {
|
||||
setInputValue(e.target.value);
|
||||
onChangeInput(
|
||||
e.target.value,
|
||||
props.pos.key,
|
||||
@@ -165,8 +226,8 @@ function PlaceholderType(props) {
|
||||
props.setXyPostion,
|
||||
props.data && props.data.signerObjId,
|
||||
false
|
||||
)
|
||||
}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
case "dropdown":
|
||||
@@ -233,7 +294,8 @@ function PlaceholderType(props) {
|
||||
(props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? (
|
||||
<input
|
||||
tabIndex="0"
|
||||
placeholder="name"
|
||||
ref={inputRef}
|
||||
placeholder={"name"}
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
value={props.pos.widgetValue}
|
||||
@@ -267,7 +329,8 @@ function PlaceholderType(props) {
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
placeholder="company"
|
||||
ref={inputRef}
|
||||
placeholder={"company"}
|
||||
value={props.pos.widgetValue && props.pos.widgetValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) =>
|
||||
@@ -299,7 +362,8 @@ function PlaceholderType(props) {
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
placeholder="job title"
|
||||
ref={inputRef}
|
||||
placeholder={"job title"}
|
||||
value={props.pos.widgetValue && props.pos.widgetValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) =>
|
||||
@@ -390,10 +454,10 @@ function PlaceholderType(props) {
|
||||
popperPlacement="top-end"
|
||||
customInput={<ExampleCustomInput />}
|
||||
dateFormat={
|
||||
props.pos?.dateFormat
|
||||
? props.pos?.dateFormat
|
||||
: props.selectDate
|
||||
? props.selectDate?.format
|
||||
props.selectDate
|
||||
? props.selectDate?.format
|
||||
: props.pos?.dateFormat
|
||||
? props.pos?.dateFormat
|
||||
: "dd MMMM, YYYY"
|
||||
}
|
||||
/>
|
||||
@@ -432,7 +496,8 @@ function PlaceholderType(props) {
|
||||
<input
|
||||
className="inputPlaceholder"
|
||||
type="text"
|
||||
placeholder="email"
|
||||
ref={inputRef}
|
||||
placeholder={"email"}
|
||||
value={props.pos.widgetValue && props.pos.widgetValue}
|
||||
onBlur={handleInputBlur}
|
||||
onChange={(e) =>
|
||||
|
||||
@@ -35,7 +35,6 @@ function RenderPdf({
|
||||
pdfUrl,
|
||||
numPages,
|
||||
pageDetails,
|
||||
|
||||
pdfRequest,
|
||||
setCurrentSigner,
|
||||
signerObjectId,
|
||||
@@ -56,7 +55,10 @@ function RenderPdf({
|
||||
setSignerObjId,
|
||||
setShowDropdown,
|
||||
setIsInitial,
|
||||
setIsCheckboxRequired
|
||||
setIsCheckboxRequired,
|
||||
setIsValidate,
|
||||
setWidgetType,
|
||||
setValidateAlert
|
||||
}) {
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const newWidth = containerWH.width;
|
||||
@@ -363,6 +365,7 @@ function RenderPdf({
|
||||
isDragging={false}
|
||||
pdfDetails={pdfDetails}
|
||||
setIsInitial={setIsInitial}
|
||||
setValidateAlert={setValidateAlert}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
@@ -773,6 +776,8 @@ function RenderPdf({
|
||||
setIsCheckboxRequired={
|
||||
setIsCheckboxRequired
|
||||
}
|
||||
setIsValidate={setIsValidate}
|
||||
setWidgetType={setWidgetType}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
@@ -1231,6 +1236,8 @@ function RenderPdf({
|
||||
setIsCheckboxRequired={
|
||||
setIsCheckboxRequired
|
||||
}
|
||||
setIsValidate={setIsValidate}
|
||||
setWidgetType={setWidgetType}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -88,6 +88,10 @@ function PlaceHolderSign() {
|
||||
const [isCheckboxRequired, setIsCheckboxRequired] = useState(false);
|
||||
const [selectRequiredType, setSelectRequiredType] = useState("Optional");
|
||||
const [isdraggingEnable, setIsDraggingEnable] = useState(false);
|
||||
const [isValidate, setIsValidate] = useState(false);
|
||||
const [textValidate, setTextValidate] = useState("");
|
||||
const [validateError, setValidateError] = useState("");
|
||||
const [widgetType, setWidgetType] = useState("");
|
||||
const color = [
|
||||
"#93a3db",
|
||||
"#e6c3db",
|
||||
@@ -983,6 +987,7 @@ function PlaceHolderSign() {
|
||||
navigate(`${hostUrl}recipientSignPdf/${documentId}/${currentId}`);
|
||||
};
|
||||
|
||||
console.log("signerpos", signerPos);
|
||||
const handleLinkUser = (id) => {
|
||||
setIsAddUser({ [id]: true });
|
||||
};
|
||||
@@ -1027,9 +1032,10 @@ function PlaceHolderSign() {
|
||||
const closePopup = () => {
|
||||
setIsAddUser({});
|
||||
};
|
||||
//function for add checkbox widget status in signerPos array
|
||||
|
||||
const handleApplycheckbox = () => {
|
||||
//function for base on condition to add checkbox widget status and input text validation in signerPos array
|
||||
const handleApplyWidgetsStatus = (textValidate) => {
|
||||
let regularExpression = textValidate;
|
||||
const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId);
|
||||
if (filterSignerPos.length > 0) {
|
||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
||||
@@ -1044,16 +1050,23 @@ function PlaceHolderSign() {
|
||||
const getPosData = getXYdata;
|
||||
const addSignPos = getPosData.map((position, ind) => {
|
||||
if (position.key === signKey) {
|
||||
if (selectRequiredType === "Read only") {
|
||||
return {
|
||||
...position,
|
||||
widgetStatus: selectRequiredType,
|
||||
widgetValue: true
|
||||
};
|
||||
if (widgetType === "checkbox") {
|
||||
if (selectRequiredType === "Read only") {
|
||||
return {
|
||||
...position,
|
||||
widgetStatus: selectRequiredType,
|
||||
widgetValue: true
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
widgetStatus: selectRequiredType
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
widgetStatus: selectRequiredType
|
||||
validation: regularExpression
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1080,6 +1093,21 @@ function PlaceHolderSign() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleValidateInput = (e) => {
|
||||
if (
|
||||
textValidate === "email" ||
|
||||
textValidate === "number" ||
|
||||
textValidate === "text"
|
||||
) {
|
||||
handleApplyWidgetsStatus(textValidate);
|
||||
setIsValidate(false);
|
||||
} else {
|
||||
setValidateError("please enter accurate validation.");
|
||||
setTimeout(() => {
|
||||
setValidateError("");
|
||||
}, 1500);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Title title={state?.title ? state.title : "New Document"} />
|
||||
@@ -1316,7 +1344,63 @@ function PlaceHolderSign() {
|
||||
></div>
|
||||
<button
|
||||
onClick={() => {
|
||||
handleApplycheckbox();
|
||||
handleApplyWidgetsStatus();
|
||||
}}
|
||||
style={{
|
||||
background: themeColor()
|
||||
}}
|
||||
type="button"
|
||||
// disabled={!selectCopyType}
|
||||
className="finishBtn"
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
<ModalUi
|
||||
//isValidate
|
||||
isOpen={isValidate}
|
||||
handleClose={() => {
|
||||
setIsValidate(false);
|
||||
}}
|
||||
title={"Validation"}
|
||||
>
|
||||
<div style={{ height: "100%", padding: 20 }}>
|
||||
<div className="validateText">
|
||||
<label
|
||||
style={{
|
||||
marginRight: "5px",
|
||||
fontSize: "14px",
|
||||
fontWeight: "500"
|
||||
}}
|
||||
>
|
||||
Regular expression:
|
||||
</label>
|
||||
|
||||
<input
|
||||
placeholder="email, number, text"
|
||||
className="drodown-input validateInputText"
|
||||
onChange={(e) => setTextValidate(e.target.value)}
|
||||
/>
|
||||
{validateError && (
|
||||
<p style={{ color: "red", fontSize: "12px" }}>
|
||||
{validateError}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: "1px",
|
||||
backgroundColor: "#9f9f9f",
|
||||
width: "100%",
|
||||
marginTop: "15px",
|
||||
marginBottom: "15px"
|
||||
}}
|
||||
></div>
|
||||
<button
|
||||
onClick={() => {
|
||||
handleValidateInput();
|
||||
}}
|
||||
style={{
|
||||
background: themeColor()
|
||||
@@ -1391,6 +1475,8 @@ function PlaceHolderSign() {
|
||||
isDragging={isDragging}
|
||||
setShowDropdown={setShowDropdown}
|
||||
setIsCheckboxRequired={setIsCheckboxRequired}
|
||||
setIsValidate={setIsValidate}
|
||||
setWidgetType={setWidgetType}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -1509,6 +1595,7 @@ function PlaceHolderSign() {
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
|
||||
<LinkUserModal
|
||||
handleAddUser={handleAddUser}
|
||||
isAddUser={isAddUser}
|
||||
|
||||
@@ -615,7 +615,6 @@
|
||||
.uploadImgLogo {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.DropdownMenuContent,
|
||||
.DropdownMenuSubContent {
|
||||
min-width: 130px;
|
||||
@@ -824,8 +823,23 @@ option {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.validateInputText {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media screen and (max-width:766px) {
|
||||
|
||||
.validateInputText {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.validateText {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.showPages {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ export const defaultWidthHeight = (type) => {
|
||||
return obj;
|
||||
case "name":
|
||||
obj = {
|
||||
width: 50,
|
||||
width: 60,
|
||||
height: 25
|
||||
};
|
||||
return obj;
|
||||
|
||||
Reference in New Issue
Block a user