관리 메뉴

공부 기록장 💻

[Javascript] input value 값 없을 때 form submit 막기 (서버에 데이터 전송 전 alert 창, onsubmit false 값으로 해결) 본문

# Develop/Project

[Javascript] input value 값 없을 때 form submit 막기 (서버에 데이터 전송 전 alert 창, onsubmit false 값으로 해결)

dream_for 2023. 2. 16. 15:46

 

문제 발생 원인

 

우선 발생한 문제는 아래와 같다.

Template View의 <form> 부분에서 input 값이 없는 경우 Bad Request (HTTP Status Code 400) 에러가 발생한다.

특히 아래의 경우, 나이 (age) 는 int형의 값을 필수적으로 요구하는 필드이기 때문에 데이터를 저장하는데 있어서 문제가 발생하였다.

(name의 경우 "" 빈 String 형태의 값이 전달되어 별다른 문제를 발생시키지 않지만, age 필드의 경우 0과 같은 default값마저 전달되지 않았기 때문에 문제가 발생한다.)

 

 

Spring Framework 내부적으로는 validation.BindException 이 발생했음을 확인할 수 있다.

 

[nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'bookRecomForm' on field 'age': rejected value []; codes [typeMismatch.bookRecomForm.age,typeMismatch.age,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [bookRecomForm.age,age]; arguments []; default message [age]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'age'; For input string: ""]]

 

작성한 코드들을 자세히 확인해보자.

 

 

Controller

컨트롤러는  form 의 input, select 로부터 값들을 받아 데이터를 저장한 후에 저장한 데이터의 결과들을 보여주는 GET 요청을 받게 된다.

 

 

@RequestMapping(value = "/book/search", method = RequestMethod.GET)
public String createMemberInfo(Model model, BookRecomForm form) {
    MemberInfo memberInfo = new MemberInfo();
    memberInfo.setName(form.getName());
    memberInfo.setAge(form.getAge());
    memberInfo.setGender(form.getGender());
    memberInfo.setInterest(form.getInterest());
    memberInfo.setFeeling(form.getFeeling());

    memberInfoService.join(memberInfo);

    model.addAttribute("memberInfo", memberInfo);
    return "book/result";
}

 

MemberInfo Entity

MemberInfo 엔티티는 다음과 같다.

age 칼럼 필드의 타입이 int형으로 선언되어 있기 때문에 위에서 문제가 발생한 것임을 재차 확인할 수 있다.

 

@Getter
@Setter
@Entity
public class MemberInfo{

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username")
    private String name;

    @Column(name = "age")
    private int age;

    @Column(name = "gender")
    private String gender;

    @Column(name = "interest")
    private String interest;

    @Column(name = "feeling")
    private String feeling;

    @CreatedDate
    private LocalDateTime createdDate;

    public MemberInfo(){
        this.createdDate = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

}
@Getter
@Setter
public class BookRecomForm {
    private String name;
    private int age;
    private String gender;
    private String interest;
    private String feeling;
}

 

 

문제 해결: <form> 태그의 onsubmit 값을 false로 리턴하는 방법

문제는 아래와 같이 해결할 수 있다.

서버에 데이터가 전송되기 이전, front 단에서 javascript 코드를 추가하여 <form> 태그의 submit 값을 false로 바꾸어  submit 자체가 실행되지 않게 해결하는 방법이다.

 

 

<form> 태그 내에 onsubmit="return beforeSubmit()" 속성 값을 추가해주었다.

이름과 나이를 입력하는 <input> 태그 속성에 id 값을 각각 name, age로 설정해준 상태이다.

 

<form id="action_form" action="/book/search" onsubmit="return beforeSubmit()" method="GET">
    <div class="form-group">
        <div id="name-form">
            <label for="name">이름</label>
            <input type="text" id="name" name="name" placeholder="이름을 입력하세요">
        </div>

        <div id="age-form">
            <label for="age">나이</label>
            <input type="text" id="age" name="age" placeholder="나이를 입력하세요">
        </div>


        <!-- -->



    </div>
    <button id="submit" type="submit">완료</button>
</form>

 

같은 html 내에 작성한 beforeSubmit() 메서드는 다음과 같다.

html document 내에서 id 값으로 'name' , 'value' 가 해당되는 태그 element를 찾아 값을 읽는다.

둘 중 하나라도 존재하지 않는 경우, alaert 창이 뜨고 false 값을 전달한다.

 

<script>
    function beforeSubmit(){
        var name = document.getElementById('name').value;
        var age = document.getElementById('age').value;
        if(!name || !age){
            alert("정보를 정확히 입력해주세요");
            return false;
        }
        else{
            return true;
        }
    }
</script>

 

결국 false 값이 전달되면, <form> 태그의 submit 이 전송되지 않기 때문에 action 또한 실행되지 않는다.

따라서 입력되지 않은 값이 서버에 전달되어 발생하는 내부적인 에러를 프론트 단에서 해결할 수 있다.

 

 

 

해결 후 결과 

 

아래와 같이 입력을 하지 않은 경우  alaert창이 뜬다.

 

 

 

아래와 같이 정상적으로 모든 값을 입력한 후에야, action 이 실행되며 GET 요청이 정상적으로 수행된다.

 

728x90
반응형
Comments