코드이그나이터4 뷰 다루기 - 3 - 체크박스

고은연·2021년 3월 15일
0

체크 박스를 다루는 방법을 알아보겠습니다. 이번 챕터에서는 체크박스 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에 접속해 결과를 확인합니다.
체크박스를 선택해 보고 확인버튼을 클릭했을 때, 선택한 값이 그대로 남아있는지도 확인해 봅시다.

profile
중년 아저씨. 10 + n년차 백엔드 개발자. 스타트업과 창업, 솔로프리너와 1인 기업에 관심 많아요.

0개의 댓글