티스토리 뷰
폼 유효성 검사에 실패했을 때 어느 항목이 잘못됐는지 시각적으로 알려주는 방법이다. 부트스트랩 느낌의 경고 스타일을 직접 만들어 쓴다.
1. Laravel Custom Helper 만들기
if (!function_exists('hasError')) {
function hasError($errName, $isMsg = false)
{
if ($errors = session('errors', new \Illuminate\Support\MessageBag())) {
if ($isError = $errors->has($errName)) {
return $isMsg
? $errors->first($errName, ':message')
: 'has-error';
}
}
}
}
두 번째 인자로 동작이 갈린다. false면 CSS 클래스명을, true면 에러 메시지를 반환한다. 하나의 헬퍼로 클래스와 메시지를 모두 처리하려는 의도다.
헬퍼 파일 등록
헬퍼 함수를 만들었으면 오토로드에 등록해야 한다.
// composer.json
"autoload": {
"files": [
"app/Helpers/functions.php"
]
}
composer dump-autoload
2. CSS 처리
input.has-error {
box-shadow: 0 0 5px rgba(255, 90, 90, 1);
padding: 3px 0px 3px 3px;
margin: 5px 1px 3px 0px;
border: 1px solid rgba(255, 90, 90, 1);
}
textarea와 select에도 적용하려면 선택자를 확장한다.
input.has-error,
textarea.has-error,
select.has-error {
box-shadow: 0 0 5px rgba(255, 90, 90, 1);
border: 1px solid rgba(255, 90, 90, 1);
}
3. 폼 HTML
<input class="{{ hasError('phone') }}"
type="text"
name="phone"
id="phone" value="{{ old('phone') }}">
old('phone')가 중요하다. 이게 없으면 검증 실패로 되돌아왔을 때 사용자가 입력했던 값이 전부 날아간다. 항목이 많은 폼에서는 치명적이다.
에러 메시지도 같이 표시
<input class="{{ hasError('phone') }}" type="text" name="phone" value="{{ old('phone') }}">
@if(hasError('phone'))
<span class="error-text">{{ hasError('phone', true) }}</span>
@endif
Laravel 기본 기능으로도 된다
사실 헬퍼를 직접 만들지 않아도 Laravel이 제공하는 디렉티브가 있다.
<input class="@error('phone') has-error @enderror"
type="text" name="phone" value="{{ old('phone') }}">
@error('phone')
<span class="error-text">{{ $message }}</span>
@enderror
@error 디렉티브는 Laravel 5.8.13부터 들어왔다. 별도 헬퍼 없이 쓸 수 있고, 안에서 $message 변수를 바로 쓸 수 있다.
그래도 헬퍼를 만드는 게 나은 경우가 있다. 여러 프로젝트에서 동일한 클래스 규칙을 쓰거나, 반환할 클래스명이 프레임워크마다 다를 때(is-invalid vs has-error) 한 곳에서 관리할 수 있다.
접근성도 같이 챙기면 좋다
색상만으로 오류를 알리면 색각 이상이 있는 사용자는 인지하지 못한다. 텍스트 메시지를 반드시 함께 표시하고, 스크린 리더용 속성도 붙이는 게 좋다.
<input type="text" name="phone"
class="@error('phone') has-error @enderror"
aria-invalid="@error('phone')true@else false@enderror"
aria-describedby="phone-error">
@error('phone')
<span id="phone-error" role="alert">{{ $message }}</span>
@enderror
role="alert"가 있으면 스크린 리더가 에러 발생 시 즉시 읽어준다.
컴포넌트로 묶기
폼 항목이 많으면 매번 같은 코드를 반복하게 된다. 블레이드 컴포넌트로 만들면 훨씬 깔끔하다.
<!-- resources/views/components/input.blade.php -->
@props(['name', 'label', 'type' => 'text'])
<div class="form-group">
<label for="{{ $name }}">{{ $label }}</label>
<input type="{{ $type }}" name="{{ $name }}" id="{{ $name }}"
value="{{ old($name) }}"
class="@error($name) has-error @enderror">
@error($name)
<span class="error-text" role="alert">{{ $message }}</span>
@enderror
</div>
<!-- 사용 -->
<x-input name="phone" label="휴대폰 번호" />
<x-input name="email" label="이메일" type="email" />
정리
- 헬퍼로
has-error클래스와 메시지를 함께 처리할 수 있다 old()를 빠뜨리면 사용자 입력이 전부 날아간다- Laravel 5.8.13+ 는
@error디렉티브로 헬퍼 없이 가능 - 색상만으로 알리지 말고 텍스트 메시지와
role="alert"함께 - 항목이 많으면 블레이드 컴포넌트로 묶는다
'개발 > Laravel' 카테고리의 다른 글
| Laravel paginate에서 값이 매번 달라진 이유, ORDER BY가 없었다 (0) | 2024.05.13 |
|---|---|
| 프로젝트별로 php version 자동 관리하기 (feat: php monitor) (0) | 2023.03.24 |
| Laravel Socialite로 소셜 로그인 붙이기, 카카오·네이버는 어떻게 하나 (0) | 2022.02.24 |
| Laravel로 블로그 직접 만들기 (2018년 기록) (0) | 2018.08.27 |
| Laravel 한글 언어팩 적용하기, 유효성 검사 메시지 한글화 (2) | 2018.08.27 |
댓글
