체크 박스를 다루는 방법을 알아보겠습니다. 이번 챕터에서는 체크박스 1개와 체크박스 여러개를 처리하는 방법을 둘 다 확인합니다. 또한 입력한 값을 보존하는 방법도 보겠습니다.
우리가 만드는 화면은 아래와 같습니다.
이번 챕터의 소스코드는 https://github.com/koeunyeon/ci4/tree/view-checkbox 에서 확인하실 수 있습니다.
View
컨트롤러에 아래의 메소드를 추가합니다.
app/Controllers/View.php
public function checkbox()
{
$sports_data = [ // (1)
"baseball" => "야구",
"soccer" => "축구",
"basketball" => "농구",
];
$sports_like = $this->request->getPost("sports_like") != null; // (2)
$sports_check = $this->request->getPost("sports_name"); // (3)
if ($sports_check == null || is_array($sports_check) === false){ // (4)
$sports_check = [];
}
return View("/view/checkbox", // (5)
[
"sports_like" => $sports_like,
"sports_data" => $sports_data,
"sports_check" => $sports_check
]
);
}
코드를 확인해 보겠습니다.
(1) 스포츠 데이터를 연관배열로 정의합니다. 키는 HTML에서 사용할 name
이고, 값은 HTML에 표시할 "이름"입니다.
(2) 만들려는 화면의 "스포츠를 좋아하나요?" 항목이 체크된 상태로 보여질 것인지 여부를 결정합니다. HTTP POST 요청에 sports_like
라는 요청이 있으면 체크된 상태라고 판단합니다.
코드이그나이터4에서 HTTP POST 요청을 하나씩 읽으려면 $this->request->getPost(키이름)
메소드를 사용합니다. getPost()
처럼 파라미터 없이 메소드가 호출되면 전체 입력값이 연관배열 형태로 리턴되고, getPost(키이름)
형태로 호출되면 해당 키에 해당하는 값을 리턴합니다. 후자의 경우 해당 키가 없다면 null
을 리턴합니다.
참고로 getPost
메소드는 HTTP 메소드와 무관하게 동작합니다. 다시 말하면 만약 HTTP 메소드가 GET으로 서버에 요청이 왔더라도, $this->request->getPost()
는 빈 배열 []
을 반환할 뿐 오류가 나거나 null
을 리턴하거나 하지 않습니다.
(3) 화면의 "여러개 체크박스" 항목 중 체크된 항목을 나타냅니다. "여러개 체크박스"에는 야구, 축구, 농구 등 여러 개의 스포츠가 보여집니다. 각각의 체크박스를 구분하기 위해 체크박스 하나마다 이름을 주는 것도 방법이지만, 키=[순차배열]
형태로 한번에 체크박스 그룹의 값을 읽어올 수도 있습니다. 잠시 후 뷰 코드를 볼 때 다시 보게 될 텐데, 배열 형태로 값을 넘기려면 HTML에서 아래와 같이 합니다.
name="키이름[]"
예를 들어 HTML에 name=sports_name[]
로 설정된 값이 서버로 전달될 경우 코드이그나이터4에서는 $this->request->getPost("sports_name")
으로 읽을 수 있습니다.
(4) $this->request->getPost(키이름)
형태로 POST 데이터를 읽을 때 만약 키가 없다면 null
을 반환합니다. 우리는 $sports_check
라는 변수를 뷰에서 사용하기 위해 선언했으므로 키가 없어서 null
이라면 빈 배열로 초기화시켜 둡니다.
(5) 뷰에 데이터를 전달합니다. sports_like
는 스포츠를 좋아하는지 여부를 나타내는 boolean
타입의 값입니다. sports_data
는 스포츠의 종류를 나타내는 정의 데이터입니다. sports_check
는 사용자가 선택한 값을 가지고 있는 배열입니다.
뷰를 추가하겠습니다.
app/Views/view/checkbox.php
<form method="POST">
<h3>1개짜리 체크박스</h3> <!-- (1) -->
<p>
스포츠를 좋아하나요?
<!-- (2) -->
<input type="checkbox" name="sports_like" value="Y" <?= $sports_like ? "checked='checked'" : '' ?> />
</p>
<hr />
<h3>여러개 체크박스</h3>
<p>
<ul>
<!-- (3) -->
<?php foreach ($sports_data as $sports_key => $sports_name) : ?>
<li>
<?= $sports_name ?>
<input type="checkbox" name="sports_name[]" value="<?= $sports_key ?>" <?= in_array($sports_key, $sports_check) ? "checked='checked'" : '' ?> /><!-- (4) --><!-- (5) -->
</li>
<?php endforeach; ?>
</ul>
</p>
<p><input type="submit" value="확인"/></p> <!-- (6) -->
</form>
(1) <h3>
태그는 3번째 제목을 나타냅니다. HTML에는 목차를 나타내는 태그가 총 6개가 있는데, 가장 큰 목차가 <h1>
이고, 가장 작은 목차가 <h6>
입니다. 간단한 항목 구분을 위해 <h3>
태그를 사용했습니다.
(2) 스포츠를 좋아하는지 여부를 나타내는 체크박스입니다. HTML FORM의 규칙에 따라 name
항목을 키로 value
항목을 값으로 서버에 전달합니다.
체크박스가 체크된 채로 보여지려면 checked="checked"
속성을 추가하면 됩니다. 참고로 checked
속성의 값은 checked
가 유일하므로, 대부분의 웹 브라우저는 checked
속성만 있다면 값의 유무나 실제 값이 checked
가 아니더라도 그냥 체크되어 있는 상태라고 판단하고 체크박스를 선택한 채 렌더링합니다.
우리는 컨트롤러에서 $sports_like
라는 데이터를 뷰로 전달했습니다. $sports_like
변수는 사용자가 "스포츠를 좋아하나요?" 항목에 체크를 했는지 여부였지요. 따라서 $sports_like
변수가 있다면 체크된 상태로 렌더링하도록 처리합니다.
<?= $sports_like ? "checked='checked'" : '' ?>
(3) $sports_data
는 스포츠를 정의하는 데이터였습니다. 스포츠 데이터를 반복함으로써 여러 개의 스포츠 정보를 그립니다.
(4) 컨트롤러의 (3) 에서 이야기했듯이 name="sports_name[]"
형식으로 이름 뒤에 []
기호가 있다면 HTTP 메세지 페이로드는 아래와 같이 전달됩니다.
sports_name%5B%5D=baseball&sports_name%5B%5D=soccer
%5B%5D
는 URL 인코딩된 []
기호입니다. 따라서 위 페이로드는 아래와 같은 뜻입니다. 동일한 키 sports_name[]
이 두 번 전달되는 것을 볼 수 있습니다.
sports_name[]=baseball&sports_name[]=soccer
PHP는 "순차 배열 형식"으로 sports_name
데이터를 읽습니다.
[
"sports_name" => ["baseball", "soccer"]
]
(5) 체크박스 목록에서 사용자가 체크한 데이터를 체크한 상태로 유지하고 싶다면 "기존의 사용자가 입력한 데이터"를 가지고 있으면 됩니다. 기존의 사용자가 입력한 데이터가 있다면 체크했다고 표기하는 겁니다.
우리는 컨트롤러에서 $sports_check
변수에 사용자가 체크했는지 여부를 뷰로 전달했습니다. 이 변수는 스포츠키 => 스포츠이름
형태로 구성되어 있었죠. 따라서 $sports_check
변수에 스포츠키를 나타내는 $sports_key
가 있다면 이전 화면에서 사용자가 체크한 화면이라는 의미가 됩니다.
(6) 주의해야 할 점은 <input type="checkbox"
일 경우 체크박스가 선택되지 않으면 서버로 값이 전달되지 않습니다. 바꿔 말하면 반드시 체크되어 있는 값만 서버로 전달된다는 의미입니다.
브라우저에서 http://localhost:8080/view/checkbox에 접속해 결과를 확인합니다.
체크박스를 선택해 보고 확인버튼을 클릭했을 때, 선택한 값이 그대로 남아있는지도 확인해 봅시다.