주소검색 특수문자, sql 입력 방지 함수 추가
This commit is contained in:
@@ -87,3 +87,41 @@ export const findAddress = async (search: string) => {
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const searchFilter=(search:string)=>{
|
||||
|
||||
|
||||
if(search.length >0){
|
||||
//특수문자 제거
|
||||
const expText = /[%=><]/ ;
|
||||
if(expText.test(search) == true){
|
||||
alert("특수문자를 입력 할수 없습니다.") ;
|
||||
search = search.split(expText).join("");
|
||||
return false;
|
||||
}
|
||||
|
||||
//특정문자열(sql예약어의 앞뒤공백포함) 제거
|
||||
const sqlArray = [
|
||||
//sql 예약어
|
||||
"OR", "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE", "DROP", "EXEC",
|
||||
"UNION", "FETCH", "DECLARE", "TRUNCATE"
|
||||
]
|
||||
|
||||
let regex;
|
||||
for(let i=0; i<sqlArray.length; i++){
|
||||
regex = new RegExp( sqlArray[i] as string,"gi") ;
|
||||
|
||||
if (regex.test(search) ) {
|
||||
alert("\"" + sqlArray[i]+"\"와(과) 같은 특정문자로 검색할 수 없습니다.");
|
||||
search =search.replace(regex, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Input } from "@common/components/ui";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { findAddress, type addressType } from "./findAddress";
|
||||
import { findAddress, searchFilter, type addressType } from "./findAddress";
|
||||
|
||||
type thisProps = {
|
||||
initValue: string | undefined;
|
||||
@@ -9,52 +9,63 @@ type thisProps = {
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param initValue : 초기값 ?
|
||||
* @returns setRtnData => 선택된 주소 데이터 반환
|
||||
*/
|
||||
export default function SearchInputAddress({
|
||||
initValue ,
|
||||
initValue,
|
||||
setRtnData = () => {},
|
||||
readonly=false
|
||||
readonly = false,
|
||||
}: thisProps) {
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [textValue, setTextValue] = useState(initValue || "");
|
||||
const [searchList, setSearchList] = useState<addressType[]>([]);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
|
||||
if(initValue !== textValue && initValue !== undefined && initValue !== null && initValue !== ''){
|
||||
setTextValue(initValue)
|
||||
}
|
||||
|
||||
},[initValue])
|
||||
useEffect(() => {
|
||||
if (
|
||||
initValue !== textValue &&
|
||||
initValue !== undefined &&
|
||||
initValue !== null &&
|
||||
initValue !== ""
|
||||
) {
|
||||
setTextValue(initValue);
|
||||
}
|
||||
}, [initValue]);
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setTextValue(value);
|
||||
findAddress(value).then((data) => {
|
||||
setSearchList(data);
|
||||
})
|
||||
|
||||
if (searchFilter(value)) {
|
||||
setTextValue(value);
|
||||
findAddress(value).then((data) => {
|
||||
setSearchList(data);
|
||||
});
|
||||
}else{
|
||||
setTextValue("");
|
||||
setSearchList([]);
|
||||
}
|
||||
if (value) {
|
||||
setIsOpen(true);
|
||||
} else {
|
||||
setIsOpen(false);
|
||||
}
|
||||
},
|
||||
[setSearchList]
|
||||
[setSearchList],
|
||||
);
|
||||
|
||||
const handleSuggestionClick = useCallback(
|
||||
(roadAddrPart1: string) => {
|
||||
setTextValue(roadAddrPart1);
|
||||
setIsOpen(false);
|
||||
setRtnData(searchList?.find((item) => item.roadAddrPart1 === roadAddrPart1) || ({} as addressType));
|
||||
setRtnData(
|
||||
searchList?.find((item) => item.roadAddrPart1 === roadAddrPart1) ||
|
||||
({} as addressType),
|
||||
);
|
||||
},
|
||||
[searchList, setRtnData]
|
||||
[searchList, setRtnData],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -80,18 +91,18 @@ export default function SearchInputAddress({
|
||||
value={textValue}
|
||||
onChange={handleInputChange}
|
||||
/* onFocus={() => setIsOpen(true)} */
|
||||
className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
className="h-[3.2rem] w-full rounded-md border border-gray-300 pl-3 !text-xl text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder={`주소를 입력하세요`}
|
||||
readOnly={readonly}
|
||||
/>
|
||||
{isOpen && (
|
||||
<div className="absolute left-0 right-0 mt-2 bg-white border border-gray-300 rounded-md shadow-lg max-h-72 overflow-auto z-50">
|
||||
<div className="absolute left-0 right-0 z-50 mt-2 max-h-72 overflow-auto rounded-md border border-gray-300 bg-white shadow-lg">
|
||||
<div className="max-h-72">
|
||||
{searchList && searchList.length > 0 ? (
|
||||
searchList.map((item: addressType, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="!text-xl w-full text-left px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto"
|
||||
className="w-full cursor-pointer overflow-auto px-5 py-3 text-left !text-xl hover:bg-gray-100"
|
||||
onClick={() => handleSuggestionClick(item.roadAddrPart1)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
@@ -106,7 +117,7 @@ export default function SearchInputAddress({
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="!text-xl w-full px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto">
|
||||
<div className="w-full cursor-pointer overflow-auto px-5 py-3 !text-xl hover:bg-gray-100">
|
||||
검색 결과가 없습니다.
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user